From 1132fdf4f07dfbfba237af7b0cfac3cae543a79b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 5 Apr 2017 20:37:01 -0700 Subject: [PATCH] Add --enable-misaligned option for misaligned ld/st support Resolves #93 --- config.h.in | 3 +++ configure | 16 ++++++++++++++++ riscv/mmu.h | 30 ++++++++++++++++++++++++++---- riscv/riscv.ac | 5 +++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/config.h.in b/config.h.in index 15b5850..137f195 100644 --- a/config.h.in +++ b/config.h.in @@ -75,6 +75,9 @@ /* Enable PC histogram generation */ #undef RISCV_ENABLE_HISTOGRAM +/* Enable hardware support for misaligned loads and stores */ +#undef RISCV_ENABLE_MISALIGNED + /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef SOFTFLOAT_ENABLED diff --git a/configure b/configure index eddc147..77bab30 100755 --- a/configure +++ b/configure @@ -706,6 +706,7 @@ with_fesvr enable_commitlog enable_histogram enable_dirty +enable_misaligned ' ac_precious_vars='build_alias host_alias @@ -1352,6 +1353,8 @@ Optional Features: --enable-histogram Enable PC histogram generation --enable-dirty Enable hardware management of PTE accessed and dirty bits + --enable-misaligned Enable hardware support for misaligned loads and + stores Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -4679,6 +4682,19 @@ if test "x$enable_dirty" = "xyes"; then : $as_echo "#define RISCV_ENABLE_DIRTY /**/" >>confdefs.h +fi + +# Check whether --enable-misaligned was given. +if test "${enable_misaligned+set}" = set; then : + enableval=$enable_misaligned; +fi + +if test "x$enable_misaligned" = "xyes"; then : + + +$as_echo "#define RISCV_ENABLE_MISALIGNED /**/" >>confdefs.h + + fi diff --git a/riscv/mmu.h b/riscv/mmu.h index 66454be..a8d9675 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -51,11 +51,33 @@ public: mmu_t(sim_t* sim, processor_t* proc); ~mmu_t(); + inline reg_t misaligned_load(reg_t addr, size_t size) + { +#ifdef RISCV_ENABLE_MISALIGNED + reg_t res = 0; + for (size_t i = 0; i < size; i++) + res += (reg_t)load_uint8(addr + i) << (i * 8); + return res; +#else + throw trap_load_address_misaligned(addr); +#endif + } + + inline void misaligned_store(reg_t addr, reg_t data, size_t size) + { +#ifdef RISCV_ENABLE_MISALIGNED + for (size_t i = 0; i < size; i++) + store_uint8(addr + i, data >> (i * 8)); +#else + throw trap_store_address_misaligned(addr); +#endif + } + // template for functions that load an aligned value from memory #define load_func(type) \ inline type##_t load_##type(reg_t addr) { \ - if (addr & (sizeof(type##_t)-1)) \ - throw trap_load_address_misaligned(addr); \ + if (unlikely(addr & (sizeof(type##_t)-1))) \ + return misaligned_load(addr, sizeof(type##_t)); \ reg_t vpn = addr >> PGSHIFT; \ if (likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) \ return *(type##_t*)(tlb_data[vpn % TLB_ENTRIES] + addr); \ @@ -88,8 +110,8 @@ public: // template for functions that store an aligned value to memory #define store_func(type) \ void store_##type(reg_t addr, type##_t val) { \ - if (addr & (sizeof(type##_t)-1)) \ - throw trap_store_address_misaligned(addr); \ + if (unlikely(addr & (sizeof(type##_t)-1))) \ + return misaligned_store(addr, val, sizeof(type##_t)); \ reg_t vpn = addr >> PGSHIFT; \ if (likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) \ *(type##_t*)(tlb_data[vpn % TLB_ENTRIES] + addr) = val; \ diff --git a/riscv/riscv.ac b/riscv/riscv.ac index a099269..68bcdb5 100644 --- a/riscv/riscv.ac +++ b/riscv/riscv.ac @@ -37,3 +37,8 @@ AC_ARG_ENABLE([dirty], AS_HELP_STRING([--enable-dirty], [Enable hardware managem AS_IF([test "x$enable_dirty" = "xyes"], [ AC_DEFINE([RISCV_ENABLE_DIRTY],,[Enable hardware management of PTE accessed and dirty bits]) ]) + +AC_ARG_ENABLE([misaligned], AS_HELP_STRING([--enable-misaligned], [Enable hardware support for misaligned loads and stores])) +AS_IF([test "x$enable_misaligned" = "xyes"], [ + AC_DEFINE([RISCV_ENABLE_MISALIGNED],,[Enable hardware support for misaligned loads and stores]) +]) -- 2.30.2