aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-10-19 17:03:16 -0700
committerAndrew Waterman <andrew@sifive.com>2022-10-19 21:12:25 -0700
commit5746722334321b14c1937224f822cf47b1135b4e (patch)
treeaee970b87efb0503484923774ab651d6a9bb6221
parent15bad75ecc88a6db5889410cb5f4d4073f237631 (diff)
downloadriscv-isa-sim-5746722334321b14c1937224f822cf47b1135b4e.zip
riscv-isa-sim-5746722334321b14c1937224f822cf47b1135b4e.tar.gz
riscv-isa-sim-5746722334321b14c1937224f822cf47b1135b4e.tar.bz2
Template-ize load_func macro
For now, preserve the macro for compatibility with existing uses.
-rw-r--r--riscv/mmu.h35
1 files changed, 20 insertions, 15 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 4b44fef..70a644d 100644
--- a/riscv/mmu.h
+++ b/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)