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} |