cputlb.c (fc1bc777910dc14a3db4e2ad66f3e536effc297d) cputlb.c (2dd926067867c2dd19e66d31a7990e8eea7258f6)
1/*
2 * Common CPU TLB handling
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 1143 unchanged lines hidden (view full) ---

1152 * Load Helpers
1153 *
1154 * We support two different access types. SOFTMMU_CODE_ACCESS is
1155 * specifically for reading instructions from system memory. It is
1156 * called by the translation loop and in some helpers where the code
1157 * is disassembled. It shouldn't be called directly by guest code.
1158 */
1159
1/*
2 * Common CPU TLB handling
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 1143 unchanged lines hidden (view full) ---

1152 * Load Helpers
1153 *
1154 * We support two different access types. SOFTMMU_CODE_ACCESS is
1155 * specifically for reading instructions from system memory. It is
1156 * called by the translation loop and in some helpers where the code
1157 * is disassembled. It shouldn't be called directly by guest code.
1158 */
1159
1160static uint64_t load_helper(CPUArchState *env, target_ulong addr,
1161 TCGMemOpIdx oi, uintptr_t retaddr,
1162 size_t size, bool big_endian,
1163 bool code_read)
1160typedef uint64_t FullLoadHelper(CPUArchState *env, target_ulong addr,
1161 TCGMemOpIdx oi, uintptr_t retaddr);
1162
1163static inline uint64_t __attribute__((always_inline))
1164load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
1165 uintptr_t retaddr, size_t size, bool big_endian, bool code_read,
1166 FullLoadHelper *full_load)
1164{
1165 uintptr_t mmu_idx = get_mmuidx(oi);
1166 uintptr_t index = tlb_index(env, mmu_idx, addr);
1167 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
1168 target_ulong tlb_addr = code_read ? entry->addr_code : entry->addr_read;
1169 const size_t tlb_off = code_read ?
1170 offsetof(CPUTLBEntry, addr_code) : offsetof(CPUTLBEntry, addr_read);
1171 const MMUAccessType access_type =

--- 56 unchanged lines hidden (view full) ---

1228 && unlikely((addr & ~TARGET_PAGE_MASK) + size - 1
1229 >= TARGET_PAGE_SIZE)) {
1230 target_ulong addr1, addr2;
1231 tcg_target_ulong r1, r2;
1232 unsigned shift;
1233 do_unaligned_access:
1234 addr1 = addr & ~(size - 1);
1235 addr2 = addr1 + size;
1167{
1168 uintptr_t mmu_idx = get_mmuidx(oi);
1169 uintptr_t index = tlb_index(env, mmu_idx, addr);
1170 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
1171 target_ulong tlb_addr = code_read ? entry->addr_code : entry->addr_read;
1172 const size_t tlb_off = code_read ?
1173 offsetof(CPUTLBEntry, addr_code) : offsetof(CPUTLBEntry, addr_read);
1174 const MMUAccessType access_type =

--- 56 unchanged lines hidden (view full) ---

1231 && unlikely((addr & ~TARGET_PAGE_MASK) + size - 1
1232 >= TARGET_PAGE_SIZE)) {
1233 target_ulong addr1, addr2;
1234 tcg_target_ulong r1, r2;
1235 unsigned shift;
1236 do_unaligned_access:
1237 addr1 = addr & ~(size - 1);
1238 addr2 = addr1 + size;
1236 r1 = load_helper(env, addr1, oi, retaddr, size, big_endian, code_read);
1237 r2 = load_helper(env, addr2, oi, retaddr, size, big_endian, code_read);
1239 r1 = full_load(env, addr1, oi, retaddr);
1240 r2 = full_load(env, addr2, oi, retaddr);
1238 shift = (addr & (size - 1)) * 8;
1239
1240 if (big_endian) {
1241 /* Big-endian combine. */
1242 res = (r1 << shift) | (r2 >> ((size * 8) - shift));
1243 } else {
1244 /* Little-endian combine. */
1245 res = (r1 >> shift) | (r2 << ((size * 8) - shift));

--- 40 unchanged lines hidden (view full) ---

1286 * complication of ABI-specific return type promotion and always
1287 * return a value extended to the register size of the host. This is
1288 * tcg_target_long, except in the case of a 32-bit host and 64-bit
1289 * data, and for that we always have uint64_t.
1290 *
1291 * We don't bother with this widened value for SOFTMMU_CODE_ACCESS.
1292 */
1293
1241 shift = (addr & (size - 1)) * 8;
1242
1243 if (big_endian) {
1244 /* Big-endian combine. */
1245 res = (r1 << shift) | (r2 >> ((size * 8) - shift));
1246 } else {
1247 /* Little-endian combine. */
1248 res = (r1 >> shift) | (r2 << ((size * 8) - shift));

--- 40 unchanged lines hidden (view full) ---

1289 * complication of ABI-specific return type promotion and always
1290 * return a value extended to the register size of the host. This is
1291 * tcg_target_long, except in the case of a 32-bit host and 64-bit
1292 * data, and for that we always have uint64_t.
1293 *
1294 * We don't bother with this widened value for SOFTMMU_CODE_ACCESS.
1295 */
1296
1297static uint64_t full_ldub_mmu(CPUArchState *env, target_ulong addr,
1298 TCGMemOpIdx oi, uintptr_t retaddr)
1299{
1300 return load_helper(env, addr, oi, retaddr, 1, false, false,
1301 full_ldub_mmu);
1302}
1303
1294tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
1295 TCGMemOpIdx oi, uintptr_t retaddr)
1296{
1304tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
1305 TCGMemOpIdx oi, uintptr_t retaddr)
1306{
1297 return load_helper(env, addr, oi, retaddr, 1, false, false);
1307 return full_ldub_mmu(env, addr, oi, retaddr);
1298}
1299
1308}
1309
1310static uint64_t full_le_lduw_mmu(CPUArchState *env, target_ulong addr,
1311 TCGMemOpIdx oi, uintptr_t retaddr)
1312{
1313 return load_helper(env, addr, oi, retaddr, 2, false, false,
1314 full_le_lduw_mmu);
1315}
1316
1300tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
1301 TCGMemOpIdx oi, uintptr_t retaddr)
1302{
1317tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
1318 TCGMemOpIdx oi, uintptr_t retaddr)
1319{
1303 return load_helper(env, addr, oi, retaddr, 2, false, false);
1320 return full_le_lduw_mmu(env, addr, oi, retaddr);
1304}
1305
1321}
1322
1323static uint64_t full_be_lduw_mmu(CPUArchState *env, target_ulong addr,
1324 TCGMemOpIdx oi, uintptr_t retaddr)
1325{
1326 return load_helper(env, addr, oi, retaddr, 2, true, false,
1327 full_be_lduw_mmu);
1328}
1329
1306tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
1307 TCGMemOpIdx oi, uintptr_t retaddr)
1308{
1330tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
1331 TCGMemOpIdx oi, uintptr_t retaddr)
1332{
1309 return load_helper(env, addr, oi, retaddr, 2, true, false);
1333 return full_be_lduw_mmu(env, addr, oi, retaddr);
1310}
1311
1334}
1335
1336static uint64_t full_le_ldul_mmu(CPUArchState *env, target_ulong addr,
1337 TCGMemOpIdx oi, uintptr_t retaddr)
1338{
1339 return load_helper(env, addr, oi, retaddr, 4, false, false,
1340 full_le_ldul_mmu);
1341}
1342
1312tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
1313 TCGMemOpIdx oi, uintptr_t retaddr)
1314{
1343tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
1344 TCGMemOpIdx oi, uintptr_t retaddr)
1345{
1315 return load_helper(env, addr, oi, retaddr, 4, false, false);
1346 return full_le_ldul_mmu(env, addr, oi, retaddr);
1316}
1317
1347}
1348
1349static uint64_t full_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1350 TCGMemOpIdx oi, uintptr_t retaddr)
1351{
1352 return load_helper(env, addr, oi, retaddr, 4, true, false,
1353 full_be_ldul_mmu);
1354}
1355
1318tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1319 TCGMemOpIdx oi, uintptr_t retaddr)
1320{
1356tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1357 TCGMemOpIdx oi, uintptr_t retaddr)
1358{
1321 return load_helper(env, addr, oi, retaddr, 4, true, false);
1359 return full_be_ldul_mmu(env, addr, oi, retaddr);
1322}
1323
1324uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
1325 TCGMemOpIdx oi, uintptr_t retaddr)
1326{
1360}
1361
1362uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
1363 TCGMemOpIdx oi, uintptr_t retaddr)
1364{
1327 return load_helper(env, addr, oi, retaddr, 8, false, false);
1365 return load_helper(env, addr, oi, retaddr, 8, false, false,
1366 helper_le_ldq_mmu);
1328}
1329
1330uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
1331 TCGMemOpIdx oi, uintptr_t retaddr)
1332{
1367}
1368
1369uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
1370 TCGMemOpIdx oi, uintptr_t retaddr)
1371{
1333 return load_helper(env, addr, oi, retaddr, 8, true, false);
1372 return load_helper(env, addr, oi, retaddr, 8, true, false,
1373 helper_be_ldq_mmu);
1334}
1335
1336/*
1337 * Provide signed versions of the load routines as well. We can of course
1338 * avoid this for 64-bit data, or for 32-bit data on 32-bit host.
1339 */
1340
1341

--- 266 unchanged lines hidden (view full) ---

1608
1609#ifdef CONFIG_ATOMIC64
1610#define DATA_SIZE 8
1611#include "atomic_template.h"
1612#endif
1613
1614/* Code access functions. */
1615
1374}
1375
1376/*
1377 * Provide signed versions of the load routines as well. We can of course
1378 * avoid this for 64-bit data, or for 32-bit data on 32-bit host.
1379 */
1380
1381

--- 266 unchanged lines hidden (view full) ---

1648
1649#ifdef CONFIG_ATOMIC64
1650#define DATA_SIZE 8
1651#include "atomic_template.h"
1652#endif
1653
1654/* Code access functions. */
1655
1656static uint64_t full_ldub_cmmu(CPUArchState *env, target_ulong addr,
1657 TCGMemOpIdx oi, uintptr_t retaddr)
1658{
1659 return load_helper(env, addr, oi, retaddr, 1, false, true,
1660 full_ldub_cmmu);
1661}
1662
1616uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1617 TCGMemOpIdx oi, uintptr_t retaddr)
1618{
1663uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1664 TCGMemOpIdx oi, uintptr_t retaddr)
1665{
1619 return load_helper(env, addr, oi, retaddr, 1, false, true);
1666 return full_ldub_cmmu(env, addr, oi, retaddr);
1620}
1621
1667}
1668
1669static uint64_t full_le_lduw_cmmu(CPUArchState *env, target_ulong addr,
1670 TCGMemOpIdx oi, uintptr_t retaddr)
1671{
1672 return load_helper(env, addr, oi, retaddr, 2, false, true,
1673 full_le_lduw_cmmu);
1674}
1675
1622uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1623 TCGMemOpIdx oi, uintptr_t retaddr)
1624{
1676uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1677 TCGMemOpIdx oi, uintptr_t retaddr)
1678{
1625 return load_helper(env, addr, oi, retaddr, 2, false, true);
1679 return full_le_lduw_cmmu(env, addr, oi, retaddr);
1626}
1627
1680}
1681
1682static uint64_t full_be_lduw_cmmu(CPUArchState *env, target_ulong addr,
1683 TCGMemOpIdx oi, uintptr_t retaddr)
1684{
1685 return load_helper(env, addr, oi, retaddr, 2, true, true,
1686 full_be_lduw_cmmu);
1687}
1688
1628uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1629 TCGMemOpIdx oi, uintptr_t retaddr)
1630{
1689uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1690 TCGMemOpIdx oi, uintptr_t retaddr)
1691{
1631 return load_helper(env, addr, oi, retaddr, 2, true, true);
1692 return full_be_lduw_cmmu(env, addr, oi, retaddr);
1632}
1633
1693}
1694
1695static uint64_t full_le_ldul_cmmu(CPUArchState *env, target_ulong addr,
1696 TCGMemOpIdx oi, uintptr_t retaddr)
1697{
1698 return load_helper(env, addr, oi, retaddr, 4, false, true,
1699 full_le_ldul_cmmu);
1700}
1701
1634uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1635 TCGMemOpIdx oi, uintptr_t retaddr)
1636{
1702uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1703 TCGMemOpIdx oi, uintptr_t retaddr)
1704{
1637 return load_helper(env, addr, oi, retaddr, 4, false, true);
1705 return full_le_ldul_cmmu(env, addr, oi, retaddr);
1638}
1639
1706}
1707
1708static uint64_t full_be_ldul_cmmu(CPUArchState *env, target_ulong addr,
1709 TCGMemOpIdx oi, uintptr_t retaddr)
1710{
1711 return load_helper(env, addr, oi, retaddr, 4, true, true,
1712 full_be_ldul_cmmu);
1713}
1714
1640uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1641 TCGMemOpIdx oi, uintptr_t retaddr)
1642{
1715uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1716 TCGMemOpIdx oi, uintptr_t retaddr)
1717{
1643 return load_helper(env, addr, oi, retaddr, 4, true, true);
1718 return full_be_ldul_cmmu(env, addr, oi, retaddr);
1644}
1645
1646uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1647 TCGMemOpIdx oi, uintptr_t retaddr)
1648{
1719}
1720
1721uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1722 TCGMemOpIdx oi, uintptr_t retaddr)
1723{
1649 return load_helper(env, addr, oi, retaddr, 8, false, true);
1724 return load_helper(env, addr, oi, retaddr, 8, false, true,
1725 helper_le_ldq_cmmu);
1650}
1651
1652uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1653 TCGMemOpIdx oi, uintptr_t retaddr)
1654{
1726}
1727
1728uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1729 TCGMemOpIdx oi, uintptr_t retaddr)
1730{
1655 return load_helper(env, addr, oi, retaddr, 8, true, true);
1731 return load_helper(env, addr, oi, retaddr, 8, true, true,
1732 helper_be_ldq_cmmu);
1656}
1733}