diff options
author | Saleem Abdulrasool <abdulras@google.com> | 2021-05-07 16:11:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-07 16:11:18 -0700 |
commit | e8d15a489fa76612707ff9e99feb0fb36acc9f14 (patch) | |
tree | b7dbe713c8a6595785a58c4102494a9abdee18a8 | |
parent | 5450c2f731f16abe3a4f244c383c55f559c97359 (diff) | |
download | riscv-pk-e8d15a489fa76612707ff9e99feb0fb36acc9f14.zip riscv-pk-e8d15a489fa76612707ff9e99feb0fb36acc9f14.tar.gz riscv-pk-e8d15a489fa76612707ff9e99feb0fb36acc9f14.tar.bz2 |
machine: correct some additional cases of UB (#246)
Use of asm aliased register variables in local scope can only be used
for extended assembly parameters. This changes the few instances of
this in the floating point emulation to use the GNU extended assembly
syntax to access the `tp` register. This ensures that we do not rely on
undefined behaviour. This was uncovered when building the Proxy kernel
with clang and LLVM.
-rw-r--r-- | machine/fp_emulation.h | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/machine/fp_emulation.h b/machine/fp_emulation.h index 1352ca3..eeafafb 100644 --- a/machine/fp_emulation.h +++ b/machine/fp_emulation.h @@ -47,14 +47,22 @@ else tp = GET_RM(insn); \ asm volatile ("":"+r"(tp)); }) # define softfloat_raiseFlags(which) set_csr(fflags, which) -# define softfloat_roundingMode ({ register int tp asm("tp"); tp; }) +# define softfloat_roundingMode ({ \ + uintptr_t __tp; \ + __asm__("mv %0, tp" : "=r"(__tp)); \ + __tp; \ +}) # define SET_FS_DIRTY() ((void) 0) #else # define GET_F64_REG(insn, pos, regs) (*(int64_t*)((void*)((regs) + 32) + (SHIFT_RIGHT(insn, (pos)-3) & 0xf8))) # define SET_F64_REG(insn, pos, regs, val) (GET_F64_REG(insn, pos, regs) = (val)) # define GET_F32_REG(insn, pos, regs) (*(int32_t*)&GET_F64_REG(insn, pos, regs)) # define SET_F32_REG(insn, pos, regs, val) (GET_F32_REG(insn, pos, regs) = (val)) -# define GET_FCSR() ({ register int tp asm("tp"); tp & 0xFF; }) +# define GET_FCSR() ({ \ + uintptr_t __tp; \ + __asm__("mv %0, tp" : "=r"(__tp)); \ + __tp & 0xff; \ +}) # define SET_FCSR(value) ({ asm volatile("add tp, x0, %0" :: "rI"((value) & 0xFF)); SET_FS_DIRTY(); }) # define GET_FRM() (GET_FCSR() >> 5) # define SET_FRM(value) SET_FCSR(GET_FFLAGS() | ((value) << 5)) @@ -62,13 +70,19 @@ # define SET_FFLAGS(value) SET_FCSR((GET_FRM() << 5) | ((value) & 0x1F)) # define SETUP_STATIC_ROUNDING(insn) ({ \ - register int tp asm("tp"); tp &= 0xFF; \ + register uintptr_t tp asm("tp"); \ + __asm__("mv %0, tp" : "=r"(tp)); \ + tp &= 0xff; \ if (likely(((insn) & MASK_FUNCT3) == MASK_FUNCT3)) tp |= tp << 8; \ else if (GET_RM(insn) > 4) return truly_illegal_insn(regs, mcause, mepc, mstatus, insn); \ else tp |= GET_RM(insn) << 13; \ asm volatile ("":"+r"(tp)); }) # define softfloat_raiseFlags(which) ({ asm volatile ("or tp, tp, %0" :: "rI"(which)); }) -# define softfloat_roundingMode ({ register int tp asm("tp"); tp >> 13; }) +# define softfloat_roundingMode ({ \ + uintptr_t __tp; \ + __asm__("mv %0, tp" : "=r"(__tp)); \ + __tp >> 13; \ +}) # define SET_FS_DIRTY() set_csr(mstatus, MSTATUS_FS) #endif |