From: zhaomingxin Date: Thu, 13 Apr 2023 07:11:46 +0000 (+0800) Subject: riscv64: Add missing floating-point ITE/CSEL support in VEX backend X-Git-Tag: VALGRIND_3_25_0~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=18c771ada2d21ec256bcece29ed5442ec20b4ced;p=thirdparty%2Fvalgrind.git riscv64: Add missing floating-point ITE/CSEL support in VEX backend --- diff --git a/VEX/priv/host_riscv64_defs.c b/VEX/priv/host_riscv64_defs.c index 7e6b95380..12c6cb9bd 100644 --- a/VEX/priv/host_riscv64_defs.c +++ b/VEX/priv/host_riscv64_defs.c @@ -563,6 +563,19 @@ RISCV64Instr_FpLdSt(RISCV64FpLdStOp op, HReg reg, HReg base, Int soff12) return i; } +RISCV64Instr* +RISCV64Instr_FpCSEL(IRType ty, HReg dst, HReg iftrue, HReg iffalse, HReg cond) +{ + RISCV64Instr* i = LibVEX_Alloc_inline(sizeof(RISCV64Instr)); + i->tag = RISCV64in_FpCSEL; + i->RISCV64in.FpCSEL.ty = ty; + i->RISCV64in.FpCSEL.dst = dst; + i->RISCV64in.FpCSEL.iftrue = iftrue; + i->RISCV64in.FpCSEL.iffalse = iffalse; + i->RISCV64in.FpCSEL.cond = cond; + return i; +} + RISCV64Instr* RISCV64Instr_CAS(RISCV64CASOp op, HReg old, HReg addr, HReg expd, HReg data) { @@ -783,6 +796,21 @@ void ppRISCV64Instr(const RISCV64Instr* i, Bool mode64) ppHRegRISCV64(i->RISCV64in.FpLdSt.base); vex_printf(")"); return; + case RISCV64in_FpCSEL: { + UChar suffix = i->RISCV64in.FpCSEL.ty == Ity_F32 ? 's' : 'd'; + vex_printf("(FpCSEL) beq "); + ppHRegRISCV64(i->RISCV64in.FpCSEL.cond); + vex_printf(", zero, 1f; fmv.%c ", suffix); + ppHRegRISCV64(i->RISCV64in.FpCSEL.dst); + vex_printf(", "); + ppHRegRISCV64(i->RISCV64in.FpCSEL.iftrue); + vex_printf("; c.j 2f; 1: fmv.%c ", suffix); + ppHRegRISCV64(i->RISCV64in.FpCSEL.dst); + vex_printf(", "); + ppHRegRISCV64(i->RISCV64in.FpCSEL.iffalse); + vex_printf("; 2:"); + return; + } case RISCV64in_CAS: { vassert(i->RISCV64in.CAS.op == RISCV64op_CAS_D || i->RISCV64in.CAS.op == RISCV64op_CAS_W); @@ -1055,6 +1083,12 @@ void getRegUsage_RISCV64Instr(HRegUsage* u, const RISCV64Instr* i, Bool mode64) } addHRegUse(u, HRmRead, i->RISCV64in.FpLdSt.base); return; + case RISCV64in_FpCSEL: + addHRegUse(u, HRmWrite, i->RISCV64in.FpCSEL.dst); + addHRegUse(u, HRmRead, i->RISCV64in.FpCSEL.iftrue); + addHRegUse(u, HRmRead, i->RISCV64in.FpCSEL.iffalse); + addHRegUse(u, HRmRead, i->RISCV64in.FpCSEL.cond); + return; case RISCV64in_CAS: addHRegUse(u, HRmWrite, i->RISCV64in.CAS.old); addHRegUse(u, HRmRead, i->RISCV64in.CAS.addr); @@ -1267,6 +1301,12 @@ void mapRegs_RISCV64Instr(HRegRemap* m, RISCV64Instr* i, Bool mode64) mapReg(m, &i->RISCV64in.FpLdSt.reg); mapReg(m, &i->RISCV64in.FpLdSt.base); return; + case RISCV64in_FpCSEL: + mapReg(m, &i->RISCV64in.FpCSEL.dst); + mapReg(m, &i->RISCV64in.FpCSEL.iftrue); + mapReg(m, &i->RISCV64in.FpCSEL.iffalse); + mapReg(m, &i->RISCV64in.FpCSEL.cond); + return; case RISCV64in_CAS: mapReg(m, &i->RISCV64in.CAS.old); mapReg(m, &i->RISCV64in.CAS.addr); @@ -2227,6 +2267,26 @@ Int emit_RISCV64Instr(/*MB_MOD*/ Bool* is_profInc, } break; } + case RISCV64in_FpCSEL: { + /* ty = RISCV64in.FpCSEL.ty == Ity_F32 ? s : d + + beq cond, zero, 1f + fmv.{ty} dst, iftrue + c.j 2f + 1: fmv.{ty} dst, iffalse + 2: + */ + UInt dst = fregEnc(i->RISCV64in.FpCSEL.dst); + UInt iftrue = fregEnc(i->RISCV64in.FpCSEL.iftrue); + UInt iffalse = fregEnc(i->RISCV64in.FpCSEL.iffalse); + UInt cond = iregEnc(i->RISCV64in.FpCSEL.cond); + UInt fmt = i->RISCV64in.FpCSEL.ty == Ity_F32 ? 0b0010000 : 0b0010001; + p = emit_B(p, 0b1100011, (10 >> 1) & 0xfff, 0b000, cond, 0 /*x0/zero*/); + p = emit_R(p, 0b1010011, dst, 0b000, iftrue, iftrue, fmt); + p = emit_CJ(p, 0b01, (6 >> 1) & 0x7ff, 0b101); + p = emit_R(p, 0b1010011, dst, 0b000, iffalse, iffalse, fmt); + goto done; + } case RISCV64in_CAS: { /* 1: lr. old, (addr) bne old, expd, 2f diff --git a/VEX/priv/host_riscv64_defs.h b/VEX/priv/host_riscv64_defs.h index 1990fe3f5..59e556ca3 100644 --- a/VEX/priv/host_riscv64_defs.h +++ b/VEX/priv/host_riscv64_defs.h @@ -336,6 +336,7 @@ typedef enum { RISCV64in_FpConvert, /* Floating-point convert instruction. */ RISCV64in_FpCompare, /* Floating-point compare instruction. */ RISCV64in_FpLdSt, /* Floating-point load/store instruction. */ + RISCV64in_FpCSEL, /* Floating-point conditional-select pseudoinstruction.*/ RISCV64in_CAS, /* Compare-and-swap pseudoinstruction. */ RISCV64in_FENCE, /* Device I/O and memory fence. */ RISCV64in_CSEL, /* Conditional-select pseudoinstruction. */ @@ -455,6 +456,14 @@ typedef struct { HReg base; Int soff12; /* -2048 .. +2047 */ } FpLdSt; + /* Floating-point conditional-select pseudoinstruction. */ + struct { + IRType ty; + HReg dst; + HReg iftrue; + HReg iffalse; + HReg cond; + } FpCSEL; /* Compare-and-swap pseudoinstruction. */ struct { RISCV64CASOp op; @@ -553,6 +562,8 @@ RISCV64Instr_FpCompare(RISCV64FpCompareOp op, HReg dst, HReg src1, HReg src2); RISCV64Instr* RISCV64Instr_FpLdSt(RISCV64FpLdStOp op, HReg reg, HReg base, Int soff12); RISCV64Instr* +RISCV64Instr_FpCSEL(IRType ty, HReg dst, HReg iftrue, HReg iffalse, HReg cond); +RISCV64Instr* RISCV64Instr_CAS(RISCV64CASOp op, HReg old, HReg addr, HReg expd, HReg data); RISCV64Instr* RISCV64Instr_FENCE(void); RISCV64Instr* RISCV64Instr_CSEL(HReg dst, HReg iftrue, HReg iffalse, HReg cond); diff --git a/VEX/priv/host_riscv64_isel.c b/VEX/priv/host_riscv64_isel.c index c476d133c..747d41554 100644 --- a/VEX/priv/host_riscv64_isel.c +++ b/VEX/priv/host_riscv64_isel.c @@ -1555,6 +1555,19 @@ static HReg iselFltExpr_wrk(ISelEnv* env, IRExpr* e) return dst; } + /* ---------------------- MULTIPLEX ---------------------- */ + case Iex_ITE: { + /* ITE(ccexpr, iftrue, iffalse) */ + HReg cond = iselIntExpr_R(env, e->Iex.ITE.cond); + HReg iftrue = iselFltExpr(env, e->Iex.ITE.iftrue); + HReg iffalse = iselFltExpr(env, e->Iex.ITE.iffalse); + HReg dst = newVRegF(env); + IRType csel_ty = typeOfIRExpr(env->type_env, e->Iex.ITE.iftrue); + vassert(csel_ty == Ity_F64 || csel_ty == Ity_F32); + addInstr(env, RISCV64Instr_FpCSEL(csel_ty, dst, iftrue, iffalse, cond)); + return dst; + } + default: break; }