aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaleem Abdulrasool <abdulras@google.com>2021-05-07 16:11:18 -0700
committerGitHub <noreply@github.com>2021-05-07 16:11:18 -0700
commite8d15a489fa76612707ff9e99feb0fb36acc9f14 (patch)
treeb7dbe713c8a6595785a58c4102494a9abdee18a8
parent5450c2f731f16abe3a4f244c383c55f559c97359 (diff)
downloadpk-e8d15a489fa76612707ff9e99feb0fb36acc9f14.zip
pk-e8d15a489fa76612707ff9e99feb0fb36acc9f14.tar.gz
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.h22
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