Browse Source

Template-ize load_func macro

For now, preserve the macro for compatibility with existing uses.
pull/1122/head
Andrew Waterman 4 years ago
parent
commit
5746722334
  1. 35
      riscv/mmu.h

35
riscv/mmu.h

@ -59,23 +59,28 @@ public:
proc->state.log_mem_read.push_back(std::make_tuple(addr, 0, size));
#endif
template<typename T>
T ALWAYS_INLINE load(reg_t addr, bool require_alignment = false, uint32_t xlate_flags = 0) {
target_endian<T> res;
reg_t vpn = addr >> PGSHIFT;
bool aligned = (addr & (sizeof(T) - 1)) == 0;
bool tlb_hit = tlb_load_tag[vpn % TLB_ENTRIES] == vpn;
if (likely(xlate_flags == 0 && aligned && tlb_hit)) {
res = *(target_endian<T>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr);
} else {
load_slow_path(addr, sizeof(T), (uint8_t*)&res, xlate_flags, require_alignment);
}
if (proc)
READ_MEM(addr, sizeof(T));
return from_target(res);
}
// template for functions that load an aligned value from memory
#define load_func(type, prefix, xlate_flags) \
type##_t ALWAYS_INLINE prefix##_##type(reg_t addr, bool require_alignment = false) { \
reg_t vpn = addr >> PGSHIFT; \
size_t size = sizeof(type##_t); \
bool aligned = (addr & (size - 1)) == 0; \
bool tlb_hit = tlb_load_tag[vpn % TLB_ENTRIES] == vpn; \
if (likely((xlate_flags) == 0 && aligned && tlb_hit)) { \
if (proc) READ_MEM(addr, size); \
return from_target(*(target_endian<type##_t>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \
} else { \
target_endian<type##_t> res; \
load_slow_path(addr, sizeof(type##_t), (uint8_t*)&res, (xlate_flags), require_alignment); \
if (proc) READ_MEM(addr, size); \
return from_target(res); \
} \
}
type##_t ALWAYS_INLINE prefix##_##type(reg_t addr, bool require_alignment = false) { return load<type##_t>(addr, require_alignment, xlate_flags); }
// load value from memory at aligned address; zero extend to register width
load_func(uint8, load, 0)

Loading…
Cancel
Save