From 007dc701b5d054788ccfb06dc067573b7a3f3741 Mon Sep 17 00:00:00 2001 From: Dejan Jevtic Date: Wed, 19 Feb 2014 11:56:29 +0000 Subject: [PATCH] mips32: VEX Support for 64bit FPU on MIPS32 platforms. This patch is adding support for mips32 with 64bit FPU. Assume that floating-point registers are 64 bits wide. git-svn-id: svn://svn.valgrind.org/vex/trunk@2821 --- VEX/priv/guest_mips_defs.h | 8 +- VEX/priv/guest_mips_helpers.c | 251 ++++++++++---- VEX/priv/guest_mips_toIR.c | 629 +++++++++++++++++++--------------- VEX/priv/host_mips_defs.c | 26 +- VEX/priv/host_mips_isel.c | 207 +++++++---- VEX/priv/ir_defs.c | 1 + VEX/pub/libvex.h | 7 +- VEX/pub/libvex_guest_mips32.h | 177 +++++----- VEX/pub/libvex_ir.h | 1 + VEX/pub/libvex_trc_values.h | 3 + 10 files changed, 785 insertions(+), 525 deletions(-) diff --git a/VEX/priv/guest_mips_defs.h b/VEX/priv/guest_mips_defs.h index dc7163c3af..da112c5b1b 100644 --- a/VEX/priv/guest_mips_defs.h +++ b/VEX/priv/guest_mips_defs.h @@ -99,8 +99,12 @@ extern UInt mips32_dirtyhelper_rdhwr ( UInt rt, UInt rd ); extern ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd ); #endif -extern UInt mips_dirtyhelper_calculate_FCSR ( void* guest_state, UInt fs, - UInt ft, flt_op op ); +/* Calculate FCSR in fp32 mode. */ +extern UInt mips_dirtyhelper_calculate_FCSR_fp32 ( void* guest_state, UInt fs, + UInt ft, flt_op op ); +/* Calculate FCSR in fp64 mode. */ +extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* guest_state, UInt fs, + UInt ft, flt_op op ); /*---------------------------------------------------------*/ /*--- Condition code stuff ---*/ diff --git a/VEX/priv/guest_mips_helpers.c b/VEX/priv/guest_mips_helpers.c index 9e47bc7f22..92580165d3 100644 --- a/VEX/priv/guest_mips_helpers.c +++ b/VEX/priv/guest_mips_helpers.c @@ -44,7 +44,7 @@ these functions are generated by the back end. */ -#define ALWAYSDEFD32(field) \ +#define ALWAYSDEFD32(field) \ { offsetof(VexGuestMIPS32State, field), \ (sizeof ((VexGuestMIPS32State*)0)->field) } @@ -1133,14 +1133,14 @@ ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd ) ); #define ASM_VOLATILE_UNARY64(inst) \ - __asm__ volatile("cfc1 $t0, $31" "\n\t" \ - "ctc1 %2, $31" "\n\t" \ - "dmtc1 %1, $f24" "\n\t" \ - #inst" $f24, $f24" "\n\t" \ - "cfc1 %0, $31" "\n\t" \ - "ctc1 $t0, $31" "\n\t" \ + __asm__ volatile("cfc1 $t0, $31" "\n\t" \ + "ctc1 %2, $31" "\n\t" \ + "ldc1 $f24, 0(%1)" "\n\t" \ + #inst" $f24, $f24" "\n\t" \ + "cfc1 %0, $31" "\n\t" \ + "ctc1 $t0, $31" "\n\t" \ : "=r" (ret) \ - : "r" (fsVal), "r" (fcsr) \ + : "r" (&(addr[fs])), "r" (fcsr) \ : "t0", "$f24" \ ); @@ -1173,144 +1173,257 @@ ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd ) : "t0", "$f20", "$f21", "$f22", "$f23" \ ); -#define ASM_VOLATILE_BINARY64(inst) \ - __asm__ volatile("cfc1 $t0, $31" "\n\t" \ - "ctc1 %3, $31" "\n\t" \ - "dmtc1 %1, $f24" "\n\t" \ - "dmtc1 %2, $f25" "\n\t" \ - #inst" $f24, $f24, $f25" "\n\t" \ - "cfc1 %0, $31" "\n\t" \ - "ctc1 $t0, $31" "\n\t" \ - : "=r" (ret) \ - : "r" (fsVal), "r" (ftVal), "r" (fcsr) \ - : "t0", "$f24", "$f25" \ +#define ASM_VOLATILE_BINARY64(inst) \ + __asm__ volatile("cfc1 $t0, $31" "\n\t" \ + "ctc1 %3, $31" "\n\t" \ + "ldc1 $f24, 0(%1)" "\n\t" \ + "ldc1 $f26, 0(%2)" "\n\t" \ + #inst" $f24, $f24, $f26" "\n\t" \ + "cfc1 %0, $31" "\n\t" \ + "ctc1 $t0, $31" "\n\t" \ + : "=r" (ret) \ + : "r" (&(addr[fs])), "r" (&(addr[ft])), "r" (fcsr) \ + : "t0", "$f24", "$f26" \ ); /* TODO: Add cases for all fpu instructions because all fpu instructions are change the value of FCSR register. */ -extern UInt mips_dirtyhelper_calculate_FCSR ( void* gs, UInt fs, UInt ft, - flt_op inst ) +extern UInt mips_dirtyhelper_calculate_FCSR_fp32 ( void* gs, UInt fs, UInt ft, + flt_op inst ) +{ + UInt ret = 0; +#if defined(__mips__) + VexGuestMIPS32State* guest_state = (VexGuestMIPS32State*)gs; + UInt loFsVal, hiFsVal, loFtVal, hiFtVal; +#if defined (_MIPSEL) + ULong *addr = (ULong *)&guest_state->guest_f0; + loFsVal = (UInt)addr[fs]; + hiFsVal = (UInt)addr[fs+1]; + loFtVal = (UInt)addr[ft]; + hiFtVal = (UInt)addr[ft+1]; +#elif defined (_MIPSEB) + UInt *addr = (UInt *)&guest_state->guest_f0; + loFsVal = (UInt)addr[fs*2]; + hiFsVal = (UInt)addr[fs*2+2]; + loFtVal = (UInt)addr[ft*2]; + hiFtVal = (UInt)addr[ft*2+2]; +#endif + UInt fcsr = guest_state->guest_FCSR; + switch (inst) { + case ROUNDWD: + ASM_VOLATILE_UNARY32_DOUBLE(round.w.d) + break; + case FLOORWS: + ASM_VOLATILE_UNARY32(floor.w.s) + break; + case FLOORWD: + ASM_VOLATILE_UNARY32_DOUBLE(floor.w.d) + break; + case TRUNCWS: + ASM_VOLATILE_UNARY32(trunc.w.s) + break; + case TRUNCWD: + ASM_VOLATILE_UNARY32_DOUBLE(trunc.w.d) + break; + case CEILWS: + ASM_VOLATILE_UNARY32(ceil.w.s) + break; + case CEILWD: + ASM_VOLATILE_UNARY32_DOUBLE(ceil.w.d) + break; + case CVTDS: + ASM_VOLATILE_UNARY32(cvt.d.s) + break; + case CVTDW: + ASM_VOLATILE_UNARY32(cvt.d.w) + break; + case CVTSW: + ASM_VOLATILE_UNARY32(cvt.s.w) + break; + case CVTSD: + ASM_VOLATILE_UNARY32_DOUBLE(cvt.s.d) + break; + case CVTWS: + ASM_VOLATILE_UNARY32(cvt.w.s) + break; + case CVTWD: + ASM_VOLATILE_UNARY32_DOUBLE(cvt.w.d) + break; + case ROUNDWS: + ASM_VOLATILE_UNARY32(round.w.s) + break; +#if ((__mips == 32) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) \ + || (__mips == 64) + case CEILLS: + ASM_VOLATILE_UNARY32(ceil.l.s) + break; + case CEILLD: + ASM_VOLATILE_UNARY32_DOUBLE(ceil.l.d) + break; + case CVTDL: + ASM_VOLATILE_UNARY32_DOUBLE(cvt.d.l) + break; + case CVTLS: + ASM_VOLATILE_UNARY32(cvt.l.s) + break; + case CVTLD: + ASM_VOLATILE_UNARY32_DOUBLE(cvt.l.d) + break; + case CVTSL: + ASM_VOLATILE_UNARY32_DOUBLE(cvt.s.l) + break; + case FLOORLS: + ASM_VOLATILE_UNARY32(floor.l.s) + break; + case FLOORLD: + ASM_VOLATILE_UNARY32_DOUBLE(floor.l.d) + break; + case ROUNDLS: + ASM_VOLATILE_UNARY32(round.l.s) + break; + case ROUNDLD: + ASM_VOLATILE_UNARY32_DOUBLE(round.l.d) + break; + case TRUNCLS: + ASM_VOLATILE_UNARY32(trunc.l.s) + break; + case TRUNCLD: + ASM_VOLATILE_UNARY32_DOUBLE(trunc.l.d) + break; +#endif + case ADDS: + ASM_VOLATILE_BINARY32(add.s) + break; + case ADDD: + ASM_VOLATILE_BINARY32_DOUBLE(add.d) + break; + case SUBS: + ASM_VOLATILE_BINARY32(sub.s) + break; + case SUBD: + ASM_VOLATILE_BINARY32_DOUBLE(sub.d) + break; + case DIVS: + ASM_VOLATILE_BINARY32(div.s) + break; + default: + vassert(0); + break; + } +#endif + return ret; +} + +/* TODO: Add cases for all fpu instructions because all fpu instructions are + change the value of FCSR register. */ +extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft, + flt_op inst ) { UInt ret = 0; #if defined(__mips__) #if defined(VGA_mips32) VexGuestMIPS32State* guest_state = (VexGuestMIPS32State*)gs; - UInt *addr = (UInt *)&guest_state->guest_f0; - UInt loFsVal = addr[fs]; - UInt hiFsVal = addr[fs+1]; - UInt loFtVal = addr[ft]; - UInt hiFtVal = addr[ft+1]; -#define ASM_VOLATILE_UNARY(inst) ASM_VOLATILE_UNARY32(inst) -#define ASM_VOLATILE_UNARY_DOUBLE(inst) ASM_VOLATILE_UNARY32_DOUBLE(inst) -#define ASM_VOLATILE_BINARY(inst) ASM_VOLATILE_BINARY32(inst) -#define ASM_VOLATILE_BINARY_DOUBLE(inst) ASM_VOLATILE_BINARY32_DOUBLE(inst) #else VexGuestMIPS64State* guest_state = (VexGuestMIPS64State*)gs; - ULong *addr = (ULong *)&guest_state->guest_f0; - ULong fsVal = addr[fs]; - ULong ftVal = addr[ft]; -#define ASM_VOLATILE_UNARY(inst) ASM_VOLATILE_UNARY64(inst) -#define ASM_VOLATILE_UNARY_DOUBLE(inst) ASM_VOLATILE_UNARY64(inst) -#define ASM_VOLATILE_BINARY(inst) ASM_VOLATILE_BINARY64(inst) -#define ASM_VOLATILE_BINARY_DOUBLE(inst) ASM_VOLATILE_BINARY64(inst) #endif - UInt fcsr = guest_state->guest_FCSR; + ULong *addr = (ULong *)&guest_state->guest_f0; + UInt fcsr = guest_state->guest_FCSR; switch (inst) { case ROUNDWD: - ASM_VOLATILE_UNARY_DOUBLE(round.w.d) + ASM_VOLATILE_UNARY64(round.w.d) break; case FLOORWS: - ASM_VOLATILE_UNARY(floor.w.s) + ASM_VOLATILE_UNARY64(floor.w.s) break; case FLOORWD: - ASM_VOLATILE_UNARY_DOUBLE(floor.w.d) + ASM_VOLATILE_UNARY64(floor.w.d) break; case TRUNCWS: - ASM_VOLATILE_UNARY(trunc.w.s) + ASM_VOLATILE_UNARY64(trunc.w.s) break; case TRUNCWD: - ASM_VOLATILE_UNARY_DOUBLE(trunc.w.d) + ASM_VOLATILE_UNARY64(trunc.w.d) break; case CEILWS: - ASM_VOLATILE_UNARY(ceil.w.s) + ASM_VOLATILE_UNARY64(ceil.w.s) break; case CEILWD: - ASM_VOLATILE_UNARY_DOUBLE(ceil.w.d) + ASM_VOLATILE_UNARY64(ceil.w.d) break; case CVTDS: - ASM_VOLATILE_UNARY(cvt.d.s) + ASM_VOLATILE_UNARY64(cvt.d.s) break; case CVTDW: - ASM_VOLATILE_UNARY(cvt.d.w) + ASM_VOLATILE_UNARY64(cvt.d.w) break; case CVTSW: - ASM_VOLATILE_UNARY(cvt.s.w) + ASM_VOLATILE_UNARY64(cvt.s.w) break; case CVTSD: - ASM_VOLATILE_UNARY_DOUBLE(cvt.s.d) + ASM_VOLATILE_UNARY64(cvt.s.d) break; case CVTWS: - ASM_VOLATILE_UNARY(cvt.w.s) + ASM_VOLATILE_UNARY64(cvt.w.s) break; case CVTWD: - ASM_VOLATILE_UNARY_DOUBLE(cvt.w.d) + ASM_VOLATILE_UNARY64(cvt.w.d) break; case ROUNDWS: - ASM_VOLATILE_UNARY(round.w.s) + ASM_VOLATILE_UNARY64(round.w.s) break; #if ((__mips == 32) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) \ || (__mips == 64) case CEILLS: - ASM_VOLATILE_UNARY(ceil.l.s) + ASM_VOLATILE_UNARY64(ceil.l.s) break; case CEILLD: - ASM_VOLATILE_UNARY_DOUBLE(ceil.l.d) + ASM_VOLATILE_UNARY64(ceil.l.d) break; case CVTDL: - ASM_VOLATILE_UNARY_DOUBLE(cvt.d.l) + ASM_VOLATILE_UNARY64(cvt.d.l) break; case CVTLS: - ASM_VOLATILE_UNARY(cvt.l.s) + ASM_VOLATILE_UNARY64(cvt.l.s) break; case CVTLD: - ASM_VOLATILE_UNARY_DOUBLE(cvt.l.d) + ASM_VOLATILE_UNARY64(cvt.l.d) break; case CVTSL: - ASM_VOLATILE_UNARY_DOUBLE(cvt.s.l) + ASM_VOLATILE_UNARY64(cvt.s.l) break; case FLOORLS: - ASM_VOLATILE_UNARY(floor.l.s) + ASM_VOLATILE_UNARY64(floor.l.s) break; case FLOORLD: - ASM_VOLATILE_UNARY_DOUBLE(floor.l.d) + ASM_VOLATILE_UNARY64(floor.l.d) break; case ROUNDLS: - ASM_VOLATILE_UNARY(round.l.s) + ASM_VOLATILE_UNARY64(round.l.s) break; case ROUNDLD: - ASM_VOLATILE_UNARY_DOUBLE(round.l.d) + ASM_VOLATILE_UNARY64(round.l.d) break; case TRUNCLS: - ASM_VOLATILE_UNARY(trunc.l.s) + ASM_VOLATILE_UNARY64(trunc.l.s) break; case TRUNCLD: - ASM_VOLATILE_UNARY_DOUBLE(trunc.l.d) + ASM_VOLATILE_UNARY64(trunc.l.d) break; #endif case ADDS: - ASM_VOLATILE_BINARY(add.s) + ASM_VOLATILE_BINARY64(add.s) break; case ADDD: - ASM_VOLATILE_BINARY_DOUBLE(add.d) + ASM_VOLATILE_BINARY64(add.d) break; case SUBS: - ASM_VOLATILE_BINARY(sub.s) + ASM_VOLATILE_BINARY64(sub.s) break; case SUBD: - ASM_VOLATILE_BINARY_DOUBLE(sub.d) + ASM_VOLATILE_BINARY64(sub.d) break; case DIVS: - ASM_VOLATILE_BINARY(div.s) + ASM_VOLATILE_BINARY64(div.s) break; default: vassert(0); diff --git a/VEX/priv/guest_mips_toIR.c b/VEX/priv/guest_mips_toIR.c index 9ee65bf434..94ec293318 100644 --- a/VEX/priv/guest_mips_toIR.c +++ b/VEX/priv/guest_mips_toIR.c @@ -72,6 +72,9 @@ static IRSB *irsb; disInstr_MIPS below. */ static Bool mode64 = False; +/* CPU has FPU and 32 dbl. prec. FP registers. */ +static Bool fp_mode64 = False; + /* Define 1.0 in single and double precision. */ #define ONE_SINGLE 0x3F800000 #define ONE_DOUBLE 0x3FF0000000000000ULL @@ -541,6 +544,11 @@ static inline UInt getUInt(UChar * p) binop(Iop_Shr32, getFCSR(), mkU8(24+cc))), \ mkU32(0x1))); +#define ILLEGAL_INSTRUCTON \ + putPC(mkU32(guest_PC_curr_instr + 4)); \ + dres.jk_StopHere = Ijk_SigILL; \ + dres.whatNext = Dis_StopHere; + /*------------------------------------------------------------*/ /*--- Field helpers ---*/ /*------------------------------------------------------------*/ @@ -1105,22 +1113,30 @@ static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN) { IRDirty *d; IRTemp fcsr = newTemp(Ity_I32); - /* IRExpr_BBPTR() => Need to pass pointer to guest - state to helper. */ - d = unsafeIRDirty_1_N(fcsr, 0, - "mips_dirtyhelper_calculate_FCSR", - &mips_dirtyhelper_calculate_FCSR, - mkIRExprVec_4(IRExpr_BBPTR(), - mkU32(fs), - mkU32(ft), - mkU32(inst))); + /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper. */ + if (fp_mode64) + d = unsafeIRDirty_1_N(fcsr, 0, + "mips_dirtyhelper_calculate_FCSR_fp64", + &mips_dirtyhelper_calculate_FCSR_fp64, + mkIRExprVec_4(IRExpr_BBPTR(), + mkU32(fs), + mkU32(ft), + mkU32(inst))); + else + d = unsafeIRDirty_1_N(fcsr, 0, + "mips_dirtyhelper_calculate_FCSR_fp32", + &mips_dirtyhelper_calculate_FCSR_fp32, + mkIRExprVec_4(IRExpr_BBPTR(), + mkU32(fs), + mkU32(ft), + mkU32(inst))); if (opN == 1) { /* Unary operation. */ /* Declare we're reading guest state. */ - if (!mode64 && !sz32) - d->nFxState = 3; - else + if (sz32 || fp_mode64) d->nFxState = 2; + else + d->nFxState = 3; vex_bzero(&d->fxState, sizeof(d->fxState)); d->fxState[0].fx = Ifx_Read; /* read */ @@ -1128,22 +1144,19 @@ static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN) d->fxState[0].size = sizeof(UInt); d->fxState[1].fx = Ifx_Read; /* read */ d->fxState[1].offset = floatGuestRegOffset(fs); - if (mode64) - d->fxState[1].size = sizeof(ULong); - else - d->fxState[1].size = sizeof(UInt); + d->fxState[1].size = sizeof(ULong); - if (!mode64 && !sz32) { + if (!(sz32 || fp_mode64)) { d->fxState[2].fx = Ifx_Read; /* read */ d->fxState[2].offset = floatGuestRegOffset(fs+1); - d->fxState[2].size = sizeof(UInt); + d->fxState[2].size = sizeof(ULong); } } else if (opN == 2) { /* Binary operation. */ /* Declare we're reading guest state. */ - if (!mode64 && !sz32) - d->nFxState = 5; - else + if (sz32 || fp_mode64) d->nFxState = 3; + else + d->nFxState = 5; vex_bzero(&d->fxState, sizeof(d->fxState)); d->fxState[0].fx = Ifx_Read; /* read */ @@ -1151,22 +1164,18 @@ static void calculateFCSR(UInt fs, UInt ft, UInt inst, Bool sz32, UInt opN) d->fxState[0].size = sizeof(UInt); d->fxState[1].fx = Ifx_Read; /* read */ d->fxState[1].offset = floatGuestRegOffset(fs); + d->fxState[1].size = sizeof(ULong); d->fxState[2].fx = Ifx_Read; /* read */ d->fxState[2].offset = floatGuestRegOffset(ft); - if (mode64) { - d->fxState[1].size = sizeof(ULong); - d->fxState[2].size = sizeof(ULong); - } else { - d->fxState[1].size = sizeof(UInt); - d->fxState[2].size = sizeof(UInt); - } - if (!mode64 && !sz32) { + d->fxState[2].size = sizeof(ULong); + + if (!(sz32 || fp_mode64)) { d->fxState[3].fx = Ifx_Read; /* read */ d->fxState[3].offset = floatGuestRegOffset(fs+1); - d->fxState[3].size = sizeof(UInt); + d->fxState[3].size = sizeof(ULong); d->fxState[4].fx = Ifx_Read; /* read */ d->fxState[4].offset = floatGuestRegOffset(ft+1); - d->fxState[4].size = sizeof(UInt); + d->fxState[4].size = sizeof(ULong); } } @@ -1192,6 +1201,12 @@ static void putIReg(UInt archreg, IRExpr * e) stmt(IRStmt_Put(integerGuestRegOffset(archreg), e)); } +static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src) +{ + vassert(ty == Ity_I32 || ty == Ity_I64); + return ty == Ity_I64 ? unop(Iop_64to32, src) : src; +} + static void putLO(IRExpr * e) { if (mode64) { @@ -1285,12 +1300,6 @@ static IRExpr *narrowTo(IRType dst_ty, IRExpr * e) return 0; } -static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src) -{ - vassert(ty == Ity_I32 || ty == Ity_I64); - return ty == Ity_I64 ? unop(Iop_64to32, src) : src; -} - static IRExpr *getLoFromF64(IRType ty, IRExpr * src) { vassert(ty == Ity_F32 || ty == Ity_F64); @@ -1386,21 +1395,21 @@ static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set) (UInt) branch_offset), OFFB_PC); } -static IRExpr *getFReg(UInt dregNo) +static IRExpr *getFReg(UInt fregNo) { - vassert(dregNo < 32); - IRType ty = mode64 ? Ity_F64 : Ity_F32; - return IRExpr_Get(floatGuestRegOffset(dregNo), ty); + vassert(fregNo < 32); + IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; + return IRExpr_Get(floatGuestRegOffset(fregNo), ty); } static IRExpr *getDReg(UInt dregNo) { - if (mode64) { - vassert(dregNo < 32); - IRType ty = Ity_F64; - return IRExpr_Get(floatGuestRegOffset(dregNo), ty); + vassert(dregNo < 32); + if (fp_mode64) { + return IRExpr_Get(floatGuestRegOffset(dregNo), Ity_F64); } else { - vassert(dregNo < 32); + /* Read a floating point register pair and combine their contents into a + 64-bit value */ IRTemp t0 = newTemp(Ity_F32); IRTemp t1 = newTemp(Ity_F32); IRTemp t2 = newTemp(Ity_F64); @@ -1423,14 +1432,14 @@ static IRExpr *getDReg(UInt dregNo) static void putFReg(UInt dregNo, IRExpr * e) { vassert(dregNo < 32); - IRType ty = mode64 ? Ity_F64 : Ity_F32; + IRType ty = fp_mode64 ? Ity_F64 : Ity_F32; vassert(typeOfIRExpr(irsb->tyenv, e) == ty); stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e)); } static void putDReg(UInt dregNo, IRExpr * e) { - if (mode64) { + if (fp_mode64) { vassert(dregNo < 32); IRType ty = Ity_F64; vassert(typeOfIRExpr(irsb->tyenv, e) == ty); @@ -1725,7 +1734,7 @@ static Bool dis_instr_CCondFmt ( UInt cins ) switch (fmt) { case 0x10: { /* C.cond.S */ DIP("C.%s.S %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I32); t1 = newTemp(Ity_I32); t2 = newTemp(Ity_I32); @@ -1740,7 +1749,8 @@ static Bool dis_instr_CCondFmt ( UInt cins ) getFReg(ft)))); assign(ccIR, binop(Iop_CmpF64, mkexpr(tmp5), mkexpr(tmp6))); - putHI(mkWidenFrom32(Ity_I64, mkexpr(ccIR), True)); + putHI(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, + mkexpr(ccIR), True)); /* Map compare result from IR to MIPS FP cmp result | MIPS | IR -------------------------- @@ -1757,7 +1767,8 @@ static Bool dis_instr_CCondFmt ( UInt cins ) binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR), binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))), mkU32(1)))))); - putLO(mkWidenFrom32(Ity_I64, mkexpr(ccMIPS), True)); + putLO(mkWidenFrom32(mode64 ? Ity_I64: Ity_I32, + mkexpr(ccMIPS), True)); /* UN */ assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1))); @@ -11829,7 +11840,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, trap_code = get_code(cins); function = get_function(cins); IRType ty = mode64 ? Ity_I64 : Ity_I32; - IRType tyF = mode64 ? Ity_F64 : Ity_F32; + IRType tyF = fp_mode64 ? Ity_F64 : Ity_F32; ac = get_acNo(cins); @@ -11862,110 +11873,119 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, lastn = mkexpr(t0); break; - case 0x11: /* COP1 */ - { + case 0x11: { /* COP1 */ + if (fmt == 0x3 && fd == 0 && function == 0) { /* MFHC1 */ + DIP("mfhc1 r%d, f%d", rt, fs); + if (fp_mode64) { + t0 = newTemp(Ity_I64); + t1 = newTemp(Ity_I32); + assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs))); + assign(t1, unop(Iop_64HIto32, mkexpr(t0))); + putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True)); + } else { + ILLEGAL_INSTRUCTON; + } + break; + } else if (fmt == 0x7 && fd == 0 && function == 0) { /* MTHC1 */ + DIP("mthc1 r%d, f%d", rt, fs); + if (fp_mode64) { + t0 = newTemp(Ity_I64); + assign(t0, binop(Iop_32HLto64, getIReg(rt), + unop(Iop_ReinterpF32asI32, + getLoFromF64(Ity_F64 /* 32FPR mode. */, + getDReg(fs))))); + putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } + break; + } else if (fmt == 0x8) { /* BC */ + /* FcConditionalCode(bc1_cc) */ UInt bc1_cc = get_bc1_cc(cins); - if (0x08 == fmt) { - switch (fmt) { - case 0x08: /* BC */ - { - DIP("tf: %d, nd: %d", tf, nd); - /* FcConditionalCode(bc1_cc) */ - t1 = newTemp(Ity_I1); - t2 = newTemp(Ity_I32); - t3 = newTemp(Ity_I1); - - assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc))); - assign(t2, IRExpr_ITE(mkexpr(t1), - binop(Iop_And32, - binop(Iop_Shr32, getFCSR(), - mkU8(23)), - mkU32(0x1)), - binop(Iop_And32, - binop(Iop_Shr32, getFCSR(), - mkU8(24 + bc1_cc)), - mkU32(0x1)) - )); - - if (tf == 1 && nd == 0) { - /* branch on true */ - DIP("bc1t %d, %d", bc1_cc, imm); - assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); - dis_branch(False, mkexpr(t3), imm, &bstmt); - break; - } else if (tf == 0 && nd == 0) { - /* branch on false */ - DIP("bc1f %d, %d", bc1_cc, imm); - assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); - dis_branch(False, mkexpr(t3), imm, &bstmt); - break; - } else if (nd == 1 && tf == 0) { - DIP("bc1fl %d, %d", bc1_cc, imm); - lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2), - mkU32(0x0)), imm); + t1 = newTemp(Ity_I1); + t2 = newTemp(Ity_I32); + t3 = newTemp(Ity_I1); + + assign(t1, binop(Iop_CmpEQ32, mkU32(0), mkU32(bc1_cc))); + assign(t2, IRExpr_ITE(mkexpr(t1), + binop(Iop_And32, + binop(Iop_Shr32, getFCSR(), mkU8(23)), + mkU32(0x1)), + binop(Iop_And32, + binop(Iop_Shr32, getFCSR(), + mkU8(24 + bc1_cc)), + mkU32(0x1)))); + + if (tf == 1 && nd == 0) { + /* branch on true */ + DIP("bc1t %d, %d", bc1_cc, imm); + assign(t3, binop(Iop_CmpEQ32, mkU32(1), mkexpr(t2))); + dis_branch(False, mkexpr(t3), imm, &bstmt); + break; + } else if (tf == 0 && nd == 0) { + /* branch on false */ + DIP("bc1f %d, %d", bc1_cc, imm); + assign(t3, binop(Iop_CmpEQ32, mkU32(0), mkexpr(t2))); + dis_branch(False, mkexpr(t3), imm, &bstmt); + break; + } else if (nd == 1 && tf == 0) { + DIP("bc1fl %d, %d", bc1_cc, imm); + lastn = dis_branch_likely(binop(Iop_CmpNE32, mkexpr(t2), + mkU32(0x0)), imm); + break; + } else if (nd == 1 && tf == 1) { + DIP("bc1tl %d, %d", bc1_cc, imm); + lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2), + mkU32(0x0)), imm); + break; + } else + goto decode_failure; + } else { + switch (function) { + case 0x4: { /* SQRT.fmt */ + switch (fmt) { + case 0x10: { /* S */ + IRExpr *rm = get_IR_roundingmode(); + putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm, + getLoFromF64(tyF, getFReg(fs))))); break; - } else if (nd == 1 && tf == 1) { - DIP("bc1tl %d, %d", bc1_cc, imm); - lastn = dis_branch_likely(binop(Iop_CmpEQ32, mkexpr(t2), - mkU32(0x0)), imm); + } + case 0x11: { /* D */ + IRExpr *rm = get_IR_roundingmode(); + putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs))); break; - } else + } + default: goto decode_failure; - } - - default: - goto decode_failure; - } - } else { - switch (function) { - - case 0x4: /* SQRT.fmt */ - { - switch (fmt) { - case 0x10: /* S */ - { - IRExpr *rm = get_IR_roundingmode(); - putFReg(fd, mkWidenFromF32(tyF, binop(Iop_SqrtF32, rm, - getLoFromF64(tyF, getFReg(fs))))); - } - break; - case 0x11: /* D */ - { - IRExpr *rm = get_IR_roundingmode(); - putDReg(fd, binop(Iop_SqrtF64, rm, getDReg(fs))); - } - break; } } break; case 0x5: /* abs.fmt */ switch (fmt) { - case 0x10: /* S */ - DIP("abs.s f%d, f%d", fd, fs); - putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32, - getLoFromF64(tyF, getFReg(fs))))); - break; - case 0x11: /* D */ - DIP("abs.d f%d, f%d", fd, fs); - putDReg(fd, unop(Iop_AbsF64, getDReg(fs))); - break; - default: - goto decode_failure; + case 0x10: /* S */ + DIP("abs.s f%d, f%d", fd, fs); + putFReg(fd, mkWidenFromF32(tyF, unop(Iop_AbsF32, + getLoFromF64(tyF, getFReg(fs))))); + break; + case 0x11: /* D */ + DIP("abs.d f%d, f%d", fd, fs); + putDReg(fd, unop(Iop_AbsF64, getDReg(fs))); + break; + default: + goto decode_failure; } break; /* case 0x5 */ case 0x02: /* MUL.fmt */ switch (fmt) { - case 0x11: /* D */ - { + case 0x11: { /* D */ DIP("mul.d f%d, f%d, f%d", fd, fs, ft); IRExpr *rm = get_IR_roundingmode(); putDReg(fd, triop(Iop_MulF64, rm, getDReg(fs), getDReg(ft))); break; } - case 0x10: /* S */ - { + case 0x10: { /* S */ DIP("mul.s f%d, f%d, f%d", fd, fs, ft); IRExpr *rm = get_IR_roundingmode(); putFReg(fd, mkWidenFromF32(tyF, triop(Iop_MulF32, rm, @@ -11973,23 +11993,21 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, getLoFromF64(tyF, getFReg(ft))))); break; } - default: - goto decode_failure; + default: + goto decode_failure; } break; /* MUL.fmt */ case 0x03: /* DIV.fmt */ switch (fmt) { - case 0x11: /* D */ - { + case 0x11: { /* D */ DIP("div.d f%d, f%d, f%d", fd, fs, ft); IRExpr *rm = get_IR_roundingmode(); putDReg(fd, triop(Iop_DivF64, rm, getDReg(fs), getDReg(ft))); break; } - case 0x10: /* S */ - { + case 0x10: { /* S */ DIP("div.s f%d, f%d, f%d", fd, fs, ft); calculateFCSR(fs, ft, DIVS, False, 2); IRExpr *rm = get_IR_roundingmode(); @@ -11998,8 +12016,8 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, getLoFromF64(tyF, getFReg(ft))))); break; } - default: - goto decode_failure; + default: + goto decode_failure; } break; /* DIV.fmt */ @@ -12031,8 +12049,8 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x11: /* D */ DIP("mov.d f%d, f%d", fd, fs); - if (mode64) { - putFReg(fd, getFReg(fs)); + if (fp_mode64) { + putDReg(fd, getDReg(fs)); } else { putFReg(fd, getFReg(fs)); putFReg(fd + 1, getFReg(fs + 1)); @@ -12067,19 +12085,27 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("round.l.s f%d, f%d", fd, fs); - calculateFCSR(fs, 0, ROUNDLS, True, 1); - t0 = newTemp(Ity_I64); + if (fp_mode64) { + calculateFCSR(fs, 0, ROUNDLS, True, 1); + t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_F32toI64S, mkU32(0x0), - getLoFromF64(Ity_F64, getFReg(fs)))); + assign(t0, binop(Iop_F32toI64S, mkU32(0x0), + getLoFromF64(Ity_F64, getFReg(fs)))); - putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); - break; + putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } + break; case 0x11: /* D */ DIP("round.l.d f%d, f%d", fd, fs); - calculateFCSR(fs, 0, ROUNDLD, False, 1); - putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0), - getFReg(fs))); + if (fp_mode64) { + calculateFCSR(fs, 0, ROUNDLD, False, 1); + putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x0), + getDReg(fs))); + } else { + ILLEGAL_INSTRUCTON; + } break; default: goto decode_failure; @@ -12091,18 +12117,26 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("trunc.l.s f%d, f%d", fd, fs); - calculateFCSR(fs, 0, TRUNCLS, True, 1); - t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_F32toI64S, mkU32(0x3), - getLoFromF64(Ity_F64, getFReg(fs)))); + if (fp_mode64) { + calculateFCSR(fs, 0, TRUNCLS, True, 1); + t0 = newTemp(Ity_I64); + assign(t0, binop(Iop_F32toI64S, mkU32(0x3), + getLoFromF64(Ity_F64, getFReg(fs)))); - putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x11: /* D */ DIP("trunc.l.d f%d, f%d", fd, fs); - calculateFCSR(fs, 0, TRUNCLD, False, 1); - putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3), - getFReg(fs))); + if (fp_mode64) { + calculateFCSR(fs, 0, TRUNCLD, False, 1); + putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x3), + getDReg(fs))); + } else { + ILLEGAL_INSTRUCTON; + } break; default: goto decode_failure; @@ -12139,7 +12173,6 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("movn.s f%d, f%d, r%d", fd, fs, rt); - t1 = newTemp(Ity_F64); t2 = newTemp(Ity_F64); t3 = newTemp(Ity_I1); @@ -12149,13 +12182,19 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, assign(t2, getFReg(fd)); assign(t3, binop(Iop_CmpNE64, mkU64(0), getIReg(rt))); } else { - assign(t1, unop(Iop_F32toF64, getFReg(fs))); - assign(t2, unop(Iop_F32toF64, getFReg(fd))); - assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); + if (fp_mode64) { + assign(t1, getFReg(fs)); + assign(t2, getFReg(fd)); + assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); + } else { + assign(t1, unop(Iop_F32toF64, getFReg(fs))); + assign(t2, unop(Iop_F32toF64, getFReg(fd))); + assign(t3, binop(Iop_CmpNE32, mkU32(0), getIReg(rt))); + } } assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); - if (mode64) { + if (fp_mode64) { IRTemp f = newTemp(Ity_F64); IRTemp fd_hi = newTemp(Ity_I32); t5 = newTemp(Ity_I64); @@ -12163,7 +12202,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, mkexpr(f)))); - assign(t5, mkWidenFrom32(ty, unop(Iop_64to32, + assign(t5, mkWidenFrom32(Ity_I64, unop(Iop_64to32, unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); putFReg(fd, unop (Iop_ReinterpI64asF64, mkexpr(t5))); @@ -12198,10 +12237,13 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, t2 = newTemp(Ity_F64); t3 = newTemp(Ity_I1); t4 = newTemp(Ity_F64); - if (mode64) { + if (fp_mode64) { assign(t1, getFReg(fs)); assign(t2, getFReg(fd)); - assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); + if (mode64) + assign(t3, binop(Iop_CmpEQ64, mkU64(0), getIReg(rt))); + else + assign(t3, binop(Iop_CmpEQ32, mkU32(0), getIReg(rt))); } else { assign(t1, unop(Iop_F32toF64, getFReg(fs))); assign(t2, unop(Iop_F32toF64, getFReg(fd))); @@ -12209,14 +12251,14 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, } assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t1), mkexpr(t2))); - if (mode64) { + if (fp_mode64) { IRTemp f = newTemp(Ity_F64); IRTemp fd_hi = newTemp(Ity_I32); t7 = newTemp(Ity_I64); assign(f, getFReg(fd)); assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, mkexpr(f)))); - assign(t7, mkWidenFrom32(ty, unop(Iop_64to32, + assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t7))); @@ -12279,7 +12321,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, t6 = newTemp(Ity_F64); t7 = newTemp(Ity_I64); - if (mode64) { + if (fp_mode64) { assign(t5, getFReg(fs)); assign(t6, getFReg(fd)); } else { @@ -12303,13 +12345,13 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t5), mkexpr(t6))); - if (mode64) { + if (fp_mode64) { IRTemp f = newTemp(Ity_F64); IRTemp fd_hi = newTemp(Ity_I32); assign(f, getFReg(fd)); assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, mkexpr(f)))); - assign(t7, mkWidenFrom32(ty, unop(Iop_64to32, + assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); @@ -12359,7 +12401,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, t5 = newTemp(Ity_F64); t6 = newTemp(Ity_F64); - if (mode64) { + if (fp_mode64) { assign(t5, getFReg(fs)); assign(t6, getFReg(fd)); } else { @@ -12383,14 +12425,14 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, assign(t4, IRExpr_ITE(mkexpr(t3), mkexpr(t5), mkexpr(t6))); - if (mode64) { + if (fp_mode64) { IRTemp f = newTemp(Ity_F64); IRTemp fd_hi = newTemp(Ity_I32); t7 = newTemp(Ity_I64); assign(f, getFReg(fd)); assign(fd_hi, unop(Iop_64HIto32, unop(Iop_ReinterpF64asI64, mkexpr(f)))); - assign(t7, mkWidenFrom32(ty, unop(Iop_64to32, + assign(t7, mkWidenFrom32(Ity_I64, unop(Iop_64to32, unop(Iop_ReinterpF64asI64, mkexpr(t4))), True)); @@ -12427,10 +12469,10 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x4: /* MTC1 (Move Word to Floating Point) */ DIP("mtc1 r%d, f%d", rt, fs); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I32); t1 = newTemp(Ity_F32); - assign(t0, unop(Iop_64to32, getIReg(rt))); + assign(t0, mkNarrowTo32(ty, getIReg(rt))); assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); putFReg(fs, mkWidenFromF32(tyF, mkexpr(t1))); @@ -12446,7 +12488,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x0: /* MFC1 */ DIP("mfc1 r%d, f%d", rt, fs); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); assign(t0, unop(Iop_ReinterpF64asI64, getFReg(fs))); @@ -12570,7 +12612,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("cvt.d.s f%d, f%d", fd, fs); calculateFCSR(fs, 0, CVTDS, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12590,7 +12632,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x14: DIP("cvt.d.w %d, %d", fd, fs); calculateFCSR(fs, 0, CVTDW, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12609,7 +12651,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, } case 0x15: { /* L */ - if (mode64) { + if (fp_mode64) { DIP("cvt.d.l %d, %d", fd, fs); calculateFCSR(fs, 0, CVTDL, False, 1); t0 = newTemp(Ity_I64); @@ -12631,7 +12673,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x14: /* W */ DIP("cvt.s.w %d, %d", fd, fs); calculateFCSR(fs, 0, CVTSW, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12653,14 +12695,10 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x11: /* D */ DIP("cvt.s.d %d, %d", fd, fs); calculateFCSR(fs, 0, CVTSD, False, 1); - if (mode64) { - t0 = newTemp(Ity_F32); - assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(), - getFReg(fs))); - putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0))); - } else - putFReg(fd, binop(Iop_F64toF32, get_IR_roundingmode(), - getDReg(fs))); + t0 = newTemp(Ity_F32); + assign(t0, binop(Iop_F64toF32, get_IR_roundingmode(), + getDReg(fs))); + putFReg(fd, mkWidenFromF32(tyF, mkexpr(t0))); break; case 0x15: /* L */ @@ -12683,33 +12721,23 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("cvt.w.s %d, %d", fd, fs); calculateFCSR(fs, 0, CVTWS, True, 1); - if (mode64) { - putFReg(fd, mkWidenFromF32(tyF, binop(Iop_RoundF32toInt, - get_IR_roundingmode(), getLoFromF64(tyF, - getFReg(fs))))); - } else - putFReg(fd, binop(Iop_RoundF32toInt, get_IR_roundingmode(), - getFReg(fs))); + putFReg(fd, + mkWidenFromF32(tyF, + binop(Iop_RoundF32toInt, + get_IR_roundingmode(), + getLoFromF64(tyF, getFReg(fs)))) + ); break; case 0x11: DIP("cvt.w.d %d, %d", fd, fs); calculateFCSR(fs, 0, CVTWD, False, 1); - if (mode64) { - t0 = newTemp(Ity_I32); - t1 = newTemp(Ity_F32); - assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(), - getFReg(fs))); - assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); - putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); - } else { - t0 = newTemp(Ity_I32); - - assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(), - getDReg(fs))); - - putFReg(fd, unop(Iop_ReinterpI32asF32, mkexpr(t0))); - } + t0 = newTemp(Ity_I32); + t1 = newTemp(Ity_F32); + assign(t0, binop(Iop_F64toI32S, get_IR_roundingmode(), + getDReg(fs))); + assign(t1, unop(Iop_ReinterpI32asF32, mkexpr(t0))); + putFReg(fd, mkWidenFromF32(tyF, mkexpr(t1))); break; default: @@ -12722,20 +12750,28 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("cvt.l.s %d, %d", fd, fs); - calculateFCSR(fs, 0, CVTLS, True, 1); - t0 = newTemp(Ity_I64); + if (fp_mode64) { + calculateFCSR(fs, 0, CVTLS, True, 1); + t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(), - getLoFromF64(Ity_F64, getFReg(fs)))); + assign(t0, binop(Iop_F32toI64S, get_IR_roundingmode(), + getLoFromF64(tyF, getFReg(fs)))); - putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x11: { /* D */ DIP("cvt.l.d %d, %d", fd, fs); - calculateFCSR(fs, 0, CVTLD, False, 1); - putFReg(fd, binop(Iop_RoundF64toInt, - get_IR_roundingmode(), getFReg(fs))); + if (fp_mode64) { + calculateFCSR(fs, 0, CVTLD, False, 1); + putDReg(fd, binop(Iop_RoundF64toInt, + get_IR_roundingmode(), getDReg(fs))); + } else { + ILLEGAL_INSTRUCTON; + } break; } @@ -12748,20 +12784,28 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("floor.l.s %d, %d", fd, fs); - calculateFCSR(fs, 0, FLOORLS, True, 1); - t0 = newTemp(Ity_I64); + if (fp_mode64) { + calculateFCSR(fs, 0, FLOORLS, True, 1); + t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_F32toI64S, mkU32(0x1), - getLoFromF64(Ity_F64, getFReg(fs)))); + assign(t0, binop(Iop_F32toI64S, mkU32(0x1), + getLoFromF64(tyF, getFReg(fs)))); - putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + putDReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x11: /* D */ DIP("floor.l.d %d, %d", fd, fs); - calculateFCSR(fs, 0, FLOORLD, False, 1); - putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1), - getFReg(fs))); + if (fp_mode64) { + calculateFCSR(fs, 0, FLOORLD, False, 1); + putDReg(fd, binop(Iop_RoundF64toInt, mkU32(0x1), + getDReg(fs))); + } else { + ILLEGAL_INSTRUCTON; + } break; default: goto decode_failure; @@ -12773,7 +12817,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("round.w.s f%d, f%d", fd, fs); calculateFCSR(fs, 0, ROUNDWS, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12797,7 +12841,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x11: /* D */ DIP("round.w.d f%d, f%d", fd, fs); calculateFCSR(fs, 0, ROUNDWD, False, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I32); assign(t0, binop(Iop_F64toI32S, mkU32(0x0), getDReg(fs))); @@ -12823,7 +12867,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("floor.w.s f%d, f%d", fd, fs); calculateFCSR(fs, 0, FLOORWS, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12847,7 +12891,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x11: /* D */ DIP("floor.w.d f%d, f%d", fd, fs); calculateFCSR(fs, 0, FLOORWD, False, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I32); assign(t0, binop(Iop_F64toI32S, mkU32(0x1), getDReg(fs))); @@ -12874,7 +12918,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("trunc.w.s %d, %d", fd, fs); calculateFCSR(fs, 0, TRUNCWS, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12897,7 +12941,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x11: /* D */ DIP("trunc.w.d %d, %d", fd, fs); calculateFCSR(fs, 0, TRUNCWD, False, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I32); assign(t0, binop(Iop_F64toI32S, mkU32(0x3), @@ -12925,7 +12969,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x10: /* S */ DIP("ceil.w.s %d, %d", fd, fs); calculateFCSR(fs, 0, CEILWS, True, 1); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); t3 = newTemp(Ity_F32); @@ -12949,7 +12993,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x11: /* D */ DIP("ceil.w.d %d, %d", fd, fs); calculateFCSR(fs, 0, CEILWD, False, 1); - if (!mode64) { + if (!fp_mode64) { t0 = newTemp(Ity_I32); assign(t0, binop(Iop_F64toI32S, mkU32(0x2), getDReg(fs))); @@ -12972,20 +13016,28 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, switch (fmt) { case 0x10: /* S */ DIP("ceil.l.s %d, %d", fd, fs); - calculateFCSR(fs, 0, CEILLS, True, 1); - t0 = newTemp(Ity_I64); + if (fp_mode64) { + calculateFCSR(fs, 0, CEILLS, True, 1); + t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_F32toI64S, mkU32(0x2), - getLoFromF64(Ity_F64, getFReg(fs)))); + assign(t0, binop(Iop_F32toI64S, mkU32(0x2), + getLoFromF64(tyF, getFReg(fs)))); - putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t0))); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x11: /* D */ DIP("ceil.l.d %d, %d", fd, fs); - calculateFCSR(fs, 0, CEILLD, False, 1); - putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2), - getFReg(fs))); + if (fp_mode64) { + calculateFCSR(fs, 0, CEILLD, False, 1); + putFReg(fd, binop(Iop_RoundF64toInt, mkU32(0x2), + getFReg(fs))); + } else { + ILLEGAL_INSTRUCTON; + } break; default: @@ -13061,17 +13113,24 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x31: /* LWC1 */ /* Load Word to Floating Point - LWC1 (MIPS32) */ DIP("lwc1 f%d, %d(r%d)", ft, imm, rs); - if (mode64) { - t0 = newTemp(Ity_I64); + if (fp_mode64) { t1 = newTemp(Ity_F32); t2 = newTemp(Ity_I64); - /* new LO */ - assign(t0, binop(Iop_Add64, getIReg(rs), - mkU64(extend_s_16to64(imm)))); + if (mode64) { + t0 = newTemp(Ity_I64); + /* new LO */ + assign(t0, binop(Iop_Add64, getIReg(rs), + mkU64(extend_s_16to64(imm)))); + } else { + t0 = newTemp(Ity_I32); + /* new LO */ + assign(t0, binop(Iop_Add32, getIReg(rs), + mkU32(extend_s_16to32(imm)))); + } assign(t1, load(Ity_F32, mkexpr(t0))); - assign(t2, mkWidenFrom32(ty, unop(Iop_ReinterpF32asI32, - mkexpr(t1)), True)); - putFReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2))); + assign(t2, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, + mkexpr(t1)), True)); + putDReg(ft, unop(Iop_ReinterpI64asF64, mkexpr(t2))); } else { t0 = newTemp(Ity_I32); assign(t0, binop(Iop_Add32, getIReg(rs), @@ -13082,7 +13141,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x39: /* SWC1 */ DIP("swc1 f%d, %d(r%d)", ft, imm, rs); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t2 = newTemp(Ity_I32); LOAD_STORE_PATTERN; @@ -13101,22 +13160,16 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x35: /* Load Doubleword to Floating Point - LDC1 (MIPS32) */ - LOAD_STORE_PATTERN; - if (mode64) - putFReg(ft, load(Ity_F64, mkexpr(t1))); - else - putDReg(ft, load(Ity_F64, mkexpr(t1))); DIP("ldc1 f%d, %d(%d)", rt, imm, rs); + LOAD_STORE_PATTERN; + putDReg(ft, load(Ity_F64, mkexpr(t1))); break; case 0x3D: /* Store Doubleword from Floating Point - SDC1 */ - LOAD_STORE_PATTERN; - if (mode64) - store(mkexpr(t1), getFReg(ft)); - else - store(mkexpr(t1), getDReg(ft)); DIP("sdc1 f%d, %d(%d)", ft, imm, rs); + LOAD_STORE_PATTERN; + store(mkexpr(t1), getDReg(ft)); break; case 0x23: /* LW */ @@ -13175,19 +13228,20 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x0: { /* LWXC1 */ /* Load Word Indexed to Floating Point - LWXC1 (MIPS32r2) */ DIP("lwxc1 f%d, r%d(r%d)", fd, rt, rs); - if (mode64) { + if (fp_mode64) { t0 = newTemp(Ity_I64); t1 = newTemp(Ity_I32); - t2 = newTemp(Ity_I64); t3 = newTemp(Ity_F32); t4 = newTemp(Ity_I64); + t2 = newTemp(ty); /* new LO */ - assign(t2, binop(Iop_Add64, getIReg(rs), getIReg(rt))); + assign(t2, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), + getIReg(rt))); assign(t3, load(Ity_F32, mkexpr(t2))); - assign(t4, mkWidenFrom32(ty, unop(Iop_ReinterpF32asI32, - mkexpr(t3)), True)); + assign(t4, mkWidenFrom32(Ity_I64, unop(Iop_ReinterpF32asI32, + mkexpr(t3)), True)); putFReg(fd, unop(Iop_ReinterpI64asF64, mkexpr(t4))); } else { @@ -13201,10 +13255,11 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x1: { /* LDXC1 */ /* Load Doubleword Indexed to Floating Point LDXC1 (MIPS32r2 and MIPS64) */ - if (mode64) { + if (fp_mode64) { DIP("ldxc1 f%d, r%d(r%d)", fd, rt, rs); - t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); + t0 = newTemp(ty); + assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), + getIReg(rt))); putFReg(fd, load(Ity_F64, mkexpr(t0))); break; } else { @@ -13238,10 +13293,10 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0x8: { /* Store Word Indexed from Floating Point - SWXC1 */ DIP("swxc1 f%d, r%d(r%d)", ft, rt, rs); - if (mode64) { - t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); - + if (fp_mode64) { + t0 = newTemp(ty); + assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), + getIReg(rt))); store(mkexpr(t0), getLoFromF64(tyF, getFReg(fs))); } else { @@ -13254,9 +13309,10 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, } case 0x9: { /* Store Doubleword Indexed from Floating Point - SDXC1 */ DIP("sdc1 f%d, %d(%d)", ft, imm, rs); - if (mode64) { - t0 = newTemp(Ity_I64); - assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); + if (fp_mode64) { + t0 = newTemp(ty); + assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, getIReg(rs), + getIReg(rt))); store(mkexpr(t0), getFReg(fs)); } else { t0 = newTemp(Ity_I32); @@ -16693,8 +16749,8 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, decode_failure_dsp: vex_printf("Error occured while trying to decode MIPS32 DSP " - "instruction.\nYour platform probably doesn't support " - "MIPS32 DSP ASE.\n"); + "instruction.\nYour platform probably doesn't support " + "MIPS32 DSP ASE.\n"); decode_failure: /* All decode failures end up here. */ if (sigill_diag) @@ -16797,7 +16853,6 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, /* Disassemble a single instruction into IR. The instruction is located in host memory at &guest_code[delta]. */ - DisResult disInstr_MIPS( IRSB* irsb_IN, Bool (*resteerOkFn) ( void *, Addr64 ), Bool resteerCisOk, @@ -16816,6 +16871,10 @@ DisResult disInstr_MIPS( IRSB* irsb_IN, vassert(guest_arch == VexArchMIPS32 || guest_arch == VexArchMIPS64); mode64 = guest_arch != VexArchMIPS32; +#if (__mips_fpr==64) + fp_mode64 = ((VEX_MIPS_REV(archinfo->hwcaps) == VEX_PRID_CPU_32FPR) + || guest_arch == VexArchMIPS64); +#endif guest_code = guest_code_IN; irsb = irsb_IN; diff --git a/VEX/priv/host_mips_defs.c b/VEX/priv/host_mips_defs.c index 1addd045a4..e708434228 100644 --- a/VEX/priv/host_mips_defs.c +++ b/VEX/priv/host_mips_defs.c @@ -37,7 +37,7 @@ #include "host_mips_defs.h" /* guest_COND offset. */ -#define COND_OFFSET(__mode64) (__mode64 ? 612 : 316) +#define COND_OFFSET(__mode64) (__mode64 ? 612 : 448) /* Register number for guest state pointer in host code. */ #define GuestSP 23 @@ -81,7 +81,7 @@ void ppHRegMIPS(HReg reg, Bool mode64) /* But specific for real regs. */ vassert(hregClass(reg) == HRcInt32 || hregClass(reg) == HRcInt64 || - hregClass(reg) == HRcFlt32 || hregClass(reg) == HRcFlt64); + hregClass(reg) == HRcFlt32 || hregClass(reg) == HRcFlt64); /* But specific for real regs. */ switch (hregClass(reg)) { @@ -91,7 +91,6 @@ void ppHRegMIPS(HReg reg, Bool mode64) vex_printf("%s", ireg32_names[r]); return; case HRcInt64: - vassert(mode64); r = hregNumber (reg); vassert (r >= 0 && r < 32); vex_printf ("%s", ireg32_names[r]); @@ -773,6 +772,12 @@ const HChar *showMIPSFpOp(MIPSFpOp op) case Mfp_CVTWD: ret = "cvt.w.d"; break; + case Mfp_CVTLD: + ret = "cvt.l.d"; + break; + case Mfp_CVTLS: + ret = "cvt.l.s"; + break; case Mfp_TRUWD: ret = "trunc.w.d"; break; @@ -801,6 +806,7 @@ const HChar *showMIPSFpOp(MIPSFpOp op) ret = "C.cond.d"; break; default: + vex_printf("Unknown op: %d", op); vpanic("showMIPSFpOp"); break; } @@ -1864,7 +1870,7 @@ void ppMIPSInstr(MIPSInstr * i, Bool mode64) return; } case Min_FpGpMove: { - vex_printf("%s", showMIPSFpGpMoveOp(i->Min.FpGpMove.op)); + vex_printf("%s ", showMIPSFpGpMoveOp(i->Min.FpGpMove.op)); ppHRegMIPS(i->Min.FpGpMove.dst, mode64); vex_printf(", "); ppHRegMIPS(i->Min.FpGpMove.src, mode64); @@ -2380,7 +2386,6 @@ static UInt iregNo(HReg r, Bool mode64) static UChar fregNo(HReg r, Bool mode64) { UInt n; - vassert(hregClass(r) == (mode64 ? HRcFlt64 : HRcFlt32)); vassert(!hregIsVirtual(r)); n = hregNumber(r); vassert(n <= 31); @@ -2390,7 +2395,6 @@ static UChar fregNo(HReg r, Bool mode64) static UChar dregNo(HReg r) { UInt n; - vassert(hregClass(r) == HRcFlt64); vassert(!hregIsVirtual(r)); n = hregNumber(r); vassert(n <= 31); @@ -3457,6 +3461,7 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, case Ijk_NoDecode: trcval = VEX_TRC_JMP_NODECODE; break; case Ijk_TInval: trcval = VEX_TRC_JMP_TINVAL; break; case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break; + case Ijk_SigILL: trcval = VEX_TRC_JMP_SIGILL; break; case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break; /* case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break; */ case Ijk_SigBUS: trcval = VEX_TRC_JMP_SIGBUS; break; @@ -3886,8 +3891,13 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, p = mkFormR(p, 0x11, 0x15, 0, fr_src, fr_dst, 0x20); break; case Mfp_CVTLS: - fr_dst = fregNo(i->Min.FpConvert.dst, mode64); - fr_src = dregNo(i->Min.FpConvert.src); + if (mode64) { + fr_dst = fregNo(i->Min.FpConvert.dst, mode64); + fr_src = dregNo(i->Min.FpConvert.src); + } else { + fr_dst = dregNo(i->Min.FpConvert.dst); + fr_src = fregNo(i->Min.FpConvert.src, mode64); + } p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x25); break; case Mfp_CVTLD: diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index 346e41120e..088b808c4a 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -47,12 +47,14 @@ ZERO0 Reserved GPR12:22 Allocateable 23 GuestStatePointer - 23 Allocateable SP StackFramePointer RA LinkRegister */ static Bool mode64 = False; +/* Host CPU has FPU and 32 dbl. prec. FP registers. */ +static Bool fp_mode64 = False; + /* GPR register class for mips32/64 */ #define HRcGPR(__mode64) (__mode64 ? HRcInt64 : HRcInt32) @@ -60,7 +62,7 @@ static Bool mode64 = False; #define HRcFPR(__mode64) (__mode64 ? HRcFlt64 : HRcFlt32) /* guest_COND offset */ -#define COND_OFFSET(__mode64) (__mode64 ? 612 : 316) +#define COND_OFFSET(__mode64) (__mode64 ? 612 : 448) /*---------------------------------------------------------*/ /*--- ISelEnv ---*/ @@ -117,6 +119,7 @@ typedef UInt hwcaps; Bool mode64; + Bool fp_mode64; Bool chainingAllowed; Addr64 max_ga; @@ -180,7 +183,7 @@ static HReg newVRegD(ISelEnv * env) static HReg newVRegF(ISelEnv * env) { - HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->mode64), + HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->fp_mode64), True /*virtual reg */ ); env->vreg_ctr++; return reg; @@ -230,13 +233,13 @@ static void sub_from_sp(ISelEnv * env, UInt n) static MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e); static MIPSRH *iselWordExpr_RH(ISelEnv * env, Bool syned, IRExpr * e); -/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter being an immediate in - the range 1 .. 31 inclusive. Used for doing shift amounts. */ +/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter being an + immediate in the range 1 .. 31 inclusive. Used for doing shift amounts. */ static MIPSRH *iselWordExpr_RH5u_wrk(ISelEnv * env, IRExpr * e); static MIPSRH *iselWordExpr_RH5u(ISelEnv * env, IRExpr * e); -/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter being an immediate in - the range 1 .. 63 inclusive. Used for doing shift amounts. */ +/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter being an + immediate in the range 1 .. 63 inclusive. Used for doing shift amounts. */ static MIPSRH *iselWordExpr_RH6u_wrk(ISelEnv * env, IRExpr * e); static MIPSRH *iselWordExpr_RH6u(ISelEnv * env, IRExpr * e); @@ -2754,6 +2757,44 @@ static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr * e) return; } + case Iop_F32toI64S: { + HReg tmpD = newVRegD(env); + HReg valF = iselFltExpr(env, e->Iex.Binop.arg2); + HReg tLo = newVRegI(env); + HReg tHi = newVRegI(env); + MIPSAMode *am_addr; + + /* CVTLS tmpD, valF */ + set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); + addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLS, tmpD, valF)); + set_MIPS_rounding_default(env); + + sub_from_sp(env, 16); /* Move SP down 16 bytes */ + am_addr = MIPSAMode_IR(0, StackPointer(mode64)); + + /* store as F64 */ + addInstr(env, MIPSInstr_FpLdSt(False /*store */ , 8, tmpD, + am_addr)); + /* load as 2xI32 */ +#if defined (_MIPSEL) + addInstr(env, MIPSInstr_Load(4, tLo, am_addr, mode64)); + addInstr(env, MIPSInstr_Load(4, tHi, nextMIPSAModeFloat(am_addr), + mode64)); +#elif defined (_MIPSEB) + addInstr(env, MIPSInstr_Load(4, tHi, am_addr, mode64)); + addInstr(env, MIPSInstr_Load(4, tLo, nextMIPSAModeFloat(am_addr), + mode64)); +#endif + + /* Reset SP */ + add_to_sp(env, 16); + + *rHi = tHi; + *rLo = tLo; + + return; + } + default: break; } @@ -2936,33 +2977,38 @@ static HReg iselFltExpr(ISelEnv * env, IRExpr * e) static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) { IRType ty = typeOfIRExpr(env->type_env, e); - vassert(ty == Ity_F32 || (ty == Ity_F64 && mode64)); + vassert(ty == Ity_F32 || (ty == Ity_F64 && fp_mode64)); if (e->tag == Iex_RdTmp) { return lookupIRTemp(env, e->Iex.RdTmp.tmp); } if (e->tag == Iex_Load) { - MIPSAMode *am_addr; - HReg r_dst = newVRegF(env); vassert(e->Iex.Load.ty == Ity_F32 - || (e->Iex.Load.ty == Ity_F64 && mode64)); - am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, ty); - if (mode64 && e->Iex.Load.ty == Ity_F64) + || (e->Iex.Load.ty == Ity_F64 && fp_mode64)); + HReg r_dst; + MIPSAMode *am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr, ty); + if (e->Iex.Load.ty == Ity_F64) { + r_dst = newVRegD(env); addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, r_dst, am_addr)); - else + } else { + r_dst = newVRegF(env); addInstr(env, MIPSInstr_FpLdSt(True /*load */, 4, r_dst, am_addr)); + } return r_dst; } if (e->tag == Iex_Get) { - HReg r_dst = newVRegF(env); MIPSAMode *am_addr = MIPSAMode_IR(e->Iex.Get.offset, GuestStatePointer(mode64)); - if (mode64) + HReg r_dst; + if (e->Iex.Load.ty == Ity_F64) { + r_dst = newVRegD(env); addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, r_dst, am_addr)); - else + } else { + r_dst = newVRegF(env); addInstr(env, MIPSInstr_FpLdSt(True /*load */, 4, r_dst, am_addr)); + } return r_dst; } @@ -2979,7 +3025,7 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) return r_dst; } case Iop_F32toF64: { - vassert(mode64); + vassert(fp_mode64); HReg src = iselFltExpr(env, e->Iex.Unop.arg); HReg dst = newVRegD(env); @@ -2987,24 +3033,29 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) return dst; } case Iop_ReinterpI64asF64: { - vassert(mode64); - HReg fr_src = iselWordExpr_R(env, e->Iex.Unop.arg); - HReg r_dst = newVRegF(env); - - /* Move Doubleword to Floating Point - dmtc1 r_dst, fr_src */ - addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_dmtc1, r_dst, fr_src)); - + HReg r_dst; + if (mode64) { + HReg fr_src = iselWordExpr_R(env, e->Iex.Unop.arg); + r_dst = newVRegF(env); + /* Move Doubleword to Floating Point + dmtc1 r_dst, fr_src */ + addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_dmtc1, r_dst, fr_src)); + } else { + HReg Hi, Lo; + r_dst = newVRegD(env); + iselInt64Expr(&Hi, &Lo, env, e->Iex.Unop.arg); + r_dst = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ + } return r_dst; } case Iop_I32StoF64: { - vassert(mode64); + vassert(fp_mode64); HReg dst = newVRegF(env); HReg tmp = newVRegF(env); HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); /* Move Word to Floating Point - mtc1 tmp1, r_src */ + mtc1 tmp, r_src */ addInstr(env, MIPSInstr_FpGpMove(MFpGpMove_mtc1, tmp, r_src)); /* and do convert */ @@ -3081,28 +3132,28 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) op = Mfp_DIVS; break; case Iop_DivF64: - vassert(mode64); + vassert(fp_mode64); op = Mfp_DIVD; break; case Iop_MulF32: op = Mfp_MULS; break; case Iop_MulF64: - vassert(mode64); + vassert(fp_mode64); op = Mfp_MULD; break; case Iop_AddF32: op = Mfp_ADDS; break; case Iop_AddF64: - vassert(mode64); + vassert(fp_mode64); op = Mfp_ADDD; break; case Iop_SubF32: op = Mfp_SUBS; break; case Iop_SubF64: - vassert(mode64); + vassert(fp_mode64); op = Mfp_SUBD; break; default: @@ -3172,23 +3223,29 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) case Iop_I64StoF64: { HReg r_dst = newVRegF(env); - MIPSAMode *am_addr; - HReg fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); - HReg tmp = newVRegF(env); - - /* Move SP down 8 bytes */ - sub_from_sp(env, 8); - am_addr = MIPSAMode_IR(0, StackPointer(mode64)); + HReg tmp, fr_src; + if (mode64) { + tmp = newVRegF(env); + fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); + /* Move SP down 8 bytes */ + sub_from_sp(env, 8); + am_addr = MIPSAMode_IR(0, StackPointer(mode64)); - /* store as I64 */ - addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); + /* store as I64 */ + addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); - /* load as Ity_F64 */ - addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); + /* load as Ity_F64 */ + addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); - /* Reset SP */ - add_to_sp(env, 8); + /* Reset SP */ + add_to_sp(env, 8); + } else { + HReg Hi, Lo; + tmp = newVRegD(env); + iselInt64Expr(&Hi, &Lo, env, e->Iex.Binop.arg2); + tmp = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ + } set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); addInstr(env, MIPSInstr_FpConvert(Mfp_CVTDL, r_dst, tmp)); @@ -3199,23 +3256,29 @@ static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e) case Iop_I64StoF32: { HReg r_dst = newVRegF(env); - MIPSAMode *am_addr; - HReg fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); - HReg tmp = newVRegF(env); - - /* Move SP down 8 bytes */ - sub_from_sp(env, 8); - am_addr = MIPSAMode_IR(0, StackPointer(mode64)); + HReg fr_src, tmp; + if (mode64) { + tmp = newVRegF(env); + fr_src = iselWordExpr_R(env, e->Iex.Binop.arg2); + /* Move SP down 8 bytes */ + sub_from_sp(env, 8); + am_addr = MIPSAMode_IR(0, StackPointer(mode64)); - /* store as I64 */ - addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); + /* store as I64 */ + addInstr(env, MIPSInstr_Store(8, am_addr, fr_src, mode64)); - /* load as Ity_F64 */ - addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); + /* load as Ity_F64 */ + addInstr(env, MIPSInstr_FpLdSt(True /*load */, 8, tmp, am_addr)); - /* Reset SP */ - add_to_sp(env, 8); + /* Reset SP */ + add_to_sp(env, 8); + } else { + HReg Hi, Lo; + tmp = newVRegD(env); + iselInt64Expr(&Hi, &Lo, env, e->Iex.Binop.arg2); + tmp = mk_LoadRR32toFPR(env, Hi, Lo); /* 2*I32 -> F64 */ + } set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); addInstr(env, MIPSInstr_FpConvert(Mfp_CVTSL, r_dst, tmp)); @@ -3438,19 +3501,14 @@ static HReg iselDblExpr_wrk(ISelEnv * env, IRExpr * e) if (e->tag == Iex_Binop) { switch (e->Iex.Binop.op) { case Iop_RoundF64toInt: { - HReg valD = iselDblExpr(env, e->Iex.Binop.arg2); - MIPSRH *fmt = iselWordExpr_RH(env, False, e->Iex.Binop.arg1); - HReg valD1 = newVRegD(env); - - if (fmt->Mrh.Imm.imm16 == 0x3) - addInstr(env, MIPSInstr_FpConvert(Mfp_TRULD, valD1, valD)); - else if (fmt->Mrh.Imm.imm16 == 0x2) - addInstr(env, MIPSInstr_FpConvert(Mfp_CEILLD, valD1, valD)); - else if (fmt->Mrh.Imm.imm16 == 0x0) - addInstr(env, MIPSInstr_FpConvert(Mfp_ROUNDLD, valD1, valD)); - else - vassert(0); - return valD1; + HReg src = iselDblExpr(env, e->Iex.Binop.arg2); + HReg dst = newVRegD(env); + + set_MIPS_rounding_mode(env, e->Iex.Binop.arg1); + addInstr(env, MIPSInstr_FpConvert(Mfp_CVTLD, dst, src)); + set_MIPS_rounding_default(env); + + return dst; } case Iop_SqrtF64: { @@ -4047,6 +4105,7 @@ static void iselNext ( ISelEnv* env, case Ijk_NoDecode: case Ijk_NoRedir: case Ijk_SigBUS: + case Ijk_SigILL: case Ijk_SigTRAP: case Ijk_SigFPE_IntDiv: case Ijk_SigFPE_IntOvf: @@ -4097,11 +4156,16 @@ HInstrArray *iselSB_MIPS ( IRSB* bb, || VEX_PRID_COMP_NETLOGIC); mode64 = arch_host != VexArchMIPS32; +#if (__mips_fpr==64) + fp_mode64 = ((VEX_MIPS_REV(hwcaps_host) == VEX_PRID_CPU_32FPR) + || arch_host == VexArchMIPS64); +#endif /* Make up an initial environment to use. */ env = LibVEX_Alloc(sizeof(ISelEnv)); env->vreg_ctr = 0; env->mode64 = mode64; + env->fp_mode64 = fp_mode64; /* Set up output code array. */ env->code = newHInstrArray(); @@ -4166,6 +4230,7 @@ HInstrArray *iselSB_MIPS ( IRSB* bb, default: ppIRType(bb->tyenv->types[i]); vpanic("iselBB(mips): IRTemp type"); + break; } env->vregmap[i] = hreg; env->vregmapHI[i] = hregHI; diff --git a/VEX/priv/ir_defs.c b/VEX/priv/ir_defs.c index 575575c4c3..87b0b63cee 100644 --- a/VEX/priv/ir_defs.c +++ b/VEX/priv/ir_defs.c @@ -1414,6 +1414,7 @@ void ppIRJumpKind ( IRJumpKind kind ) case Ijk_MapFail: vex_printf("MapFail"); break; case Ijk_TInval: vex_printf("Invalidate"); break; case Ijk_NoRedir: vex_printf("NoRedir"); break; + case Ijk_SigILL: vex_printf("SigILL"); break; case Ijk_SigTRAP: vex_printf("SigTRAP"); break; case Ijk_SigSEGV: vex_printf("SigSEGV"); break; case Ijk_SigBUS: vex_printf("SigBUS"); break; diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 4cc6156f99..2d408332ee 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -200,10 +200,15 @@ typedef #define VEX_PRID_IMP_34K 0x9500 #define VEX_PRID_IMP_74K 0x9700 +/* CPU has FPU and 32 dbl. prec. FP registers */ +#define VEX_PRID_CPU_32FPR 0x00000040 + /* Get MIPS Company ID from HWCAPS */ #define VEX_MIPS_COMP_ID(x) ((x) & 0x00FF0000) /* Get MIPS Processor ID from HWCAPS */ -#define VEX_MIPS_PROC_ID(x) ((x) & 0x0000FFFF) +#define VEX_MIPS_PROC_ID(x) ((x) & 0x0000FF00) +/* Get MIPS Revision from HWCAPS */ +#define VEX_MIPS_REV(x) ((x) & 0x000000FF) /* Check if the processor supports DSP ASE Rev 2. */ #define VEX_MIPS_PROC_DSP2(x) ((VEX_MIPS_COMP_ID(x) == VEX_PRID_COMP_MIPS) && \ (VEX_MIPS_PROC_ID(x) == VEX_PRID_IMP_74K)) diff --git a/VEX/pub/libvex_guest_mips32.h b/VEX/pub/libvex_guest_mips32.h index 95c2a58374..65318fe7e7 100644 --- a/VEX/pub/libvex_guest_mips32.h +++ b/VEX/pub/libvex_guest_mips32.h @@ -41,81 +41,81 @@ typedef struct { /* CPU Registers */ - /* 0 */ UInt guest_r0; /* Hardwired to 0 */ - /* 4 */ UInt guest_r1; /* Assembler temporary */ - /* 8 */ UInt guest_r2; /* Values for function returns ...*/ - /* 12 */ UInt guest_r3; /* ...and expression evaluation */ - /* 16 */ UInt guest_r4; /* Function arguments */ - /* 20 */ UInt guest_r5; - /* 24 */ UInt guest_r6; - /* 28 */ UInt guest_r7; - /* 32 */ UInt guest_r8; /* Temporaries */ - /* 36 */ UInt guest_r9; - /* 40 */ UInt guest_r10; - /* 44 */ UInt guest_r11; - /* 48 */ UInt guest_r12; - /* 52 */ UInt guest_r13; - /* 56 */ UInt guest_r14; - /* 60 */ UInt guest_r15; - /* 64 */ UInt guest_r16; /* Saved temporaries */ - /* 68 */ UInt guest_r17; - /* 72 */ UInt guest_r18; - /* 76 */ UInt guest_r19; - /* 80 */ UInt guest_r20; - /* 84 */ UInt guest_r21; - /* 88 */ UInt guest_r22; - /* 92 */ UInt guest_r23; - /* 96 */ UInt guest_r24; /* Temporaries */ - /* 100 */ UInt guest_r25; - /* 104 */ UInt guest_r26; /* Reserved for OS kernel */ - /* 108 */ UInt guest_r27; - /* 112 */ UInt guest_r28; /* Global pointer */ - /* 116 */ UInt guest_r29; /* Stack pointer */ - /* 120 */ UInt guest_r30; /* Frame pointer */ - /* 124 */ UInt guest_r31; /* Return address */ - /* 128 */ UInt guest_PC; /* Program counter */ - /* 132 */ UInt guest_HI;/* Multiply and divide register higher result */ - /* 136 */ UInt guest_LO;/* Multiply and divide register lower result */ + /* 0 */ UInt guest_r0; /* Hardwired to 0 */ + /* 4 */ UInt guest_r1; /* Assembler temporary */ + /* 8 */ UInt guest_r2; /* Values for function returns ...*/ + /* 12 */ UInt guest_r3; /* ...and expression evaluation */ + /* 16 */ UInt guest_r4; /* Function arguments */ + /* 20 */ UInt guest_r5; + /* 24 */ UInt guest_r6; + /* 28 */ UInt guest_r7; + /* 32 */ UInt guest_r8; /* Temporaries */ + /* 36 */ UInt guest_r9; + /* 40 */ UInt guest_r10; + /* 44 */ UInt guest_r11; + /* 48 */ UInt guest_r12; + /* 52 */ UInt guest_r13; + /* 56 */ UInt guest_r14; + /* 60 */ UInt guest_r15; + /* 64 */ UInt guest_r16; /* Saved temporaries */ + /* 68 */ UInt guest_r17; + /* 72 */ UInt guest_r18; + /* 76 */ UInt guest_r19; + /* 80 */ UInt guest_r20; + /* 84 */ UInt guest_r21; + /* 88 */ UInt guest_r22; + /* 92 */ UInt guest_r23; + /* 96 */ UInt guest_r24; /* Temporaries */ + /* 100 */ UInt guest_r25; + /* 104 */ UInt guest_r26; /* Reserved for OS kernel */ + /* 108 */ UInt guest_r27; + /* 112 */ UInt guest_r28; /* Global pointer */ + /* 116 */ UInt guest_r29; /* Stack pointer */ + /* 120 */ UInt guest_r30; /* Frame pointer */ + /* 124 */ UInt guest_r31; /* Return address */ + /* 128 */ UInt guest_PC; /* Program counter */ + /* 132 */ UInt guest_HI; /* Multiply and divide register higher result */ + /* 136 */ UInt guest_LO; /* Multiply and divide register lower result */ /* FPU Registers */ - /* 140 */ UInt guest_f0; /* Floting point general purpose registers */ - /* 144 */ UInt guest_f1; - /* 148 */ UInt guest_f2; - /* 152 */ UInt guest_f3; - /* 156 */ UInt guest_f4; - /* 160 */ UInt guest_f5; - /* 164 */ UInt guest_f6; - /* 168 */ UInt guest_f7; - /* 172 */ UInt guest_f8; - /* 176 */ UInt guest_f9; - /* 180 */ UInt guest_f10; - /* 184 */ UInt guest_f11; - /* 188 */ UInt guest_f12; - /* 192 */ UInt guest_f13; - /* 196 */ UInt guest_f14; - /* 200 */ UInt guest_f15; - /* 204 */ UInt guest_f16; - /* 208 */ UInt guest_f17; - /* 212 */ UInt guest_f18; - /* 216 */ UInt guest_f19; - /* 220 */ UInt guest_f20; - /* 224 */ UInt guest_f21; - /* 228 */ UInt guest_f22; - /* 232 */ UInt guest_f23; - /* 236 */ UInt guest_f24; - /* 240 */ UInt guest_f25; - /* 244 */ UInt guest_f26; - /* 248 */ UInt guest_f27; - /* 252 */ UInt guest_f28; - /* 256 */ UInt guest_f29; - /* 260 */ UInt guest_f30; - /* 264 */ UInt guest_f31; - - /* 268 */ UInt guest_FIR; - /* 272 */ UInt guest_FCCR; - /* 276 */ UInt guest_FEXR; - /* 280 */ UInt guest_FENR; - /* 284 */ UInt guest_FCSR; + /* 144 */ ULong guest_f0; /* Floating point general purpose registers */ + /* 152 */ ULong guest_f1; + /* 160 */ ULong guest_f2; + /* 168 */ ULong guest_f3; + /* 176 */ ULong guest_f4; + /* 184 */ ULong guest_f5; + /* 192 */ ULong guest_f6; + /* 200 */ ULong guest_f7; + /* 208 */ ULong guest_f8; + /* 216 */ ULong guest_f9; + /* 224 */ ULong guest_f10; + /* 232 */ ULong guest_f11; + /* 240 */ ULong guest_f12; + /* 248 */ ULong guest_f13; + /* 256 */ ULong guest_f14; + /* 264 */ ULong guest_f15; + /* 272 */ ULong guest_f16; + /* 280 */ ULong guest_f17; + /* 288 */ ULong guest_f18; + /* 296 */ ULong guest_f19; + /* 304 */ ULong guest_f20; + /* 312 */ ULong guest_f21; + /* 320 */ ULong guest_f22; + /* 328 */ ULong guest_f23; + /* 336 */ ULong guest_f24; + /* 344 */ ULong guest_f25; + /* 352 */ ULong guest_f26; + /* 360 */ ULong guest_f27; + /* 368 */ ULong guest_f28; + /* 376 */ ULong guest_f29; + /* 384 */ ULong guest_f30; + /* 392 */ ULong guest_f31; + + /* 400 */ UInt guest_FIR; + /* 404 */ UInt guest_FCCR; + /* 408 */ UInt guest_FEXR; + /* 412 */ UInt guest_FENR; + /* 416 */ UInt guest_FCSR; /* TLS pointer for the thread. It's read-only in user space. On Linux it is set in user space by various thread-related @@ -126,29 +126,28 @@ typedef environments, the UserLocal register is a pointer to a thread-specific storage block. */ - /* 288 */ UInt guest_ULR; + /* 420 */ UInt guest_ULR; /* Emulation notes */ - UInt guest_EMNOTE; /* 292 */ + /* 424 */ UInt guest_EMNOTE; /* For clflush: record start and length of area to invalidate */ - UInt guest_TISTART; /* 296 */ - UInt guest_TILEN; /* 300 */ - UInt guest_NRADDR; /* 304 */ + /* 428 */ UInt guest_TISTART; + /* 432 */ UInt guest_TILEN; + /* 436 */ UInt guest_NRADDR; - UInt host_EvC_FAILADDR; /* 308 */ - UInt host_EvC_COUNTER; /* 312 */ - UInt guest_COND; /* 316 */ + /* 440 */ UInt host_EvC_FAILADDR; + /* 444 */ UInt host_EvC_COUNTER; + /* 448 */ UInt guest_COND; - UInt padding1; /* MIPS32 DSP ASE(r2) specific registers. */ - UInt guest_DSPControl; /* 324 */ - ULong guest_ac0; /* 328 */ - ULong guest_ac1; /* 336 */ - ULong guest_ac2; /* 344 */ - ULong guest_ac3; /* 352 */ - - UInt padding[2]; + /* 452 */ UInt guest_DSPControl; + /* 456 */ ULong guest_ac0; + /* 464 */ ULong guest_ac1; + /* 472 */ ULong guest_ac2; + /* 480 */ ULong guest_ac3; + + UInt padding; } VexGuestMIPS32State; /*---------------------------------------------------------------*/ /*--- Utility functions for MIPS32 guest stuff. ---*/ diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index c89b6084f2..39d45e4f72 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -2107,6 +2107,7 @@ typedef Ijk_MapFail, /* Vex-provided address translation failed */ Ijk_TInval, /* Invalidate translations before continuing. */ Ijk_NoRedir, /* Jump to un-redirected guest addr */ + Ijk_SigILL, /* current instruction synths SIGILL */ Ijk_SigTRAP, /* current instruction synths SIGTRAP */ Ijk_SigSEGV, /* current instruction synths SIGSEGV */ Ijk_SigBUS, /* current instruction synths SIGBUS */ diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index c0f3cc8b3f..58a8e3006e 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -68,6 +68,9 @@ #define VEX_TRC_JMP_SIGFPE_INTOVF 99 /* deliver SIGFPE (integer overflow) before continuing */ +#define VEX_TRC_JMP_SIGILL 101 /* deliver SIGILL (Illegal instruction) + before continuing */ + #define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before continuing */ #define VEX_TRC_JMP_EMFAIL 83 /* emulation fatal error; abort system */ -- 2.47.2