From 57fb2facf39a640a264a7c0229251dd616946836 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 5 Dec 2025 16:59:26 -0800 Subject: [PATCH] Fix Q extension on big-endian targets The previous routines always stored the low-order bits into the low-order doubleword, which is only correct on little-endian targets. --- riscv/insns/flq.h | 4 +++- riscv/insns/fsq.h | 3 ++- riscv/mmu.h | 22 ---------------------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/riscv/insns/flq.h b/riscv/insns/flq.h index 81d225cd..6a60c0ca 100644 --- a/riscv/insns/flq.h +++ b/riscv/insns/flq.h @@ -1,3 +1,5 @@ require_extension('Q'); require_fp; -WRITE_FRD(MMU.load_float128(RS1 + insn.i_imm())); +uint128_t v = MMU.load(RS1 + insn.i_imm()); +float128_t f = { uint64_t(v), uint64_t(v >> 64) }; +WRITE_FRD(f); diff --git a/riscv/insns/fsq.h b/riscv/insns/fsq.h index 610960e5..7a4bdd8f 100644 --- a/riscv/insns/fsq.h +++ b/riscv/insns/fsq.h @@ -1,3 +1,4 @@ require_extension('Q'); require_fp; -MMU.store_float128(RS1 + insn.s_imm(), FRS2); +uint128_t v = FRS2.v[0] | (uint128_t(FRS2.v[1]) << 64); +MMU.store(RS1 + insn.s_imm(), v); diff --git a/riscv/mmu.h b/riscv/mmu.h index 9112eed6..bd8bfd31 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -211,28 +211,6 @@ public: }) } - void store_float128(reg_t addr, float128_t val) - { - if (unlikely(addr & (sizeof(float128_t)-1)) && !is_misaligned_enabled()) { - throw trap_store_address_misaligned((proc) ? proc->state.v : false, addr, 0, 0); - } - - store(addr, val.v[0]); - store(addr + 8, val.v[1]); - } - - float128_t load_float128(reg_t addr) - { - if (unlikely(addr & (sizeof(float128_t)-1)) && !is_misaligned_enabled()) { - throw trap_load_address_misaligned((proc) ? proc->state.v : false, addr, 0, 0); - } - - float128_t res; - res.v[0] = load(addr); - res.v[1] = load(addr + 8); - return res; - } - void cbo_zero(reg_t addr) { auto access_info = generate_access_info(addr, STORE, {}); reg_t transformed_addr = access_info.transformed_vaddr;