From: Petar Jovanovic Date: Tue, 14 Jan 2020 12:40:09 +0000 (+0000) Subject: mips: Add Iop_ROTX for nanoMIPS X-Git-Tag: VALGRIND_3_16_0~142 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab8807ee5398408fe09a9ea5a2ea8804e4cbade2;p=thirdparty%2Fvalgrind.git mips: Add Iop_ROTX for nanoMIPS Implement Iop_ROTX and use it for ROTX instruction. Fixes libvexmultiarch_test and libvex_test. Patch by: Aleksandra Karadzic and Nikola Milutinovic. --- diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 7233a73691..f06370ffd6 100755 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -216,11 +216,6 @@ static IRExpr *mkU32(UInt i) return IRExpr_Const(IRConst_U32(i)); } -static IRExpr *mkU64(ULong i) -{ - return IRExpr_Const(IRConst_U64(i)); -} - static void putPC(IRExpr * e) { stmt(IRStmt_Put(OFFB_PC, e)); @@ -285,6 +280,11 @@ static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2) return IRExpr_Binop(op, a1, a2); } +static IRExpr *qop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3, IRExpr * a4) +{ + return IRExpr_Qop(op, a1, a2, a3, a4); +} + /* Generate a new temporary of the given type. */ static IRTemp newTemp(IRType ty) { @@ -466,11 +466,23 @@ static void nano_pl32a0(DisResult *dres, UInt cins) IRConst_U32(guest_PC_curr_instr + 4), OFFB_PC)); } else { /* teq */ - DIP("teq r%u, r%u", rs, rt); - stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), - getIReg(rt)), Ijk_SigTRAP, - IRConst_U32(guest_PC_curr_instr + 4), - OFFB_PC)); + UChar trap_code = (cins >> 11) & 0x1F; + DIP("teq r%u, r%u %u", rs, rt, trap_code); + if (trap_code == 7) + stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), + getIReg(rt)), Ijk_SigFPE_IntDiv, + IRConst_U32(guest_PC_curr_instr + 4), + OFFB_PC)); + else if (trap_code == 6) + stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), + getIReg(rt)), Ijk_SigFPE_IntOvf, + IRConst_U32(guest_PC_curr_instr + 4), + OFFB_PC)); + else + stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), + getIReg(rt)), Ijk_SigTRAP, + IRConst_U32(guest_PC_curr_instr + 4), + OFFB_PC)); } break; @@ -1232,118 +1244,9 @@ static void nano_protx(UInt cins) switch ((cins >> 5) & 0x41) { case 0x00: { /* rotx */ - int i; - IRTemp t0 = newTemp(Ity_I64); - IRTemp t1 = newTemp(Ity_I64); - IRTemp t2 = newTemp(Ity_I64); - IRTemp t3 = newTemp(Ity_I64); - IRTemp t4 = newTemp(Ity_I64); - IRTemp t5 = newTemp(Ity_I64); - IRTemp tmp = newTemp(Ity_I64); - IRTemp s = newTemp(Ity_I32); DIP("rotx r%u, r%u, %u, %u, %u", rt, rs, shift, shiftx, stripe); - assign(t0, binop(Iop_Or64, getIReg(rs), binop(Iop_Shl64, - getIReg(rs), mkU8(32)))); - assign(t1, mkexpr(t0)); - - for (i = 0; i < 46; i++) { - assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x08)), - mkU32(shift), mkU32(shiftx))); - assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(stripe), - binop(Iop_CmpNE32, mkU32(0x0), - binop(Iop_And32, - mkU32(i), mkU32(0x04)))), - unop(Iop_Not32, mkU32(s)), mkexpr(s))); - assign(tmp, binop(Iop_Or64, binop(Iop_And64, - binop(Iop_Shr64, mkexpr(t0), - mkU8(0x10)), - binop(Iop_Shl64, mkU64(0x01), - mkU8(i))), - binop(Iop_And64, mkexpr(t1), - unop(Iop_Not64, - binop(Iop_Shl64, mkU64(0x01), - mkU8(i)))))); - assign(t1, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x10)), - mkexpr(tmp), - mkexpr(t1))); - - } - - assign(t2, mkexpr(t1)); - - for (i = 0; i < 38; i++) { - assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x04)), - mkU32(shift), mkU32(shiftx))); - assign(tmp, binop(Iop_Or64, - binop(Iop_And64, - binop(Iop_Shr64, mkexpr(t1), mkU8(0x08)), - binop(Iop_Shl64, mkU64(0x01), mkU8(i))), - binop(Iop_And64, mkexpr(t2), - unop(Iop_Not64, binop(Iop_Shl64, - mkU64(0x01), - mkU8(i)))))); - assign(t2, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x08)), - mkexpr(tmp), - mkexpr(t2))); - - } - - assign(t3, mkexpr(t2)); - - for (i = 0; i < 34; i++) { - assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x02)), - mkU32(shift), mkU32(shiftx))); - assign(tmp, binop(Iop_Or64, - binop(Iop_And64, - binop(Iop_Shr64, mkexpr(t2), mkU8(0x04)), - binop(Iop_Shl64, mkU64(0x01), mkU8(i))), - binop(Iop_And64, mkexpr(t3), - unop(Iop_Not64, binop(Iop_Shl64, - mkU64(0x01), - mkU8(i)))))); - assign(t3, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x04)), - mkexpr(tmp), - mkexpr(t3))); - - } - - assign(t4, mkexpr(t3)); - - for (i = 0; i < 32; i++) { - assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x01)), - mkU32(shift), mkU32(shiftx))); - assign(tmp, binop(Iop_Or64, - binop(Iop_And64, - binop(Iop_Shr64, mkexpr(t3), mkU8(0x02)), - binop(Iop_Shl64, mkU64(0x01), mkU8(i))), - binop(Iop_And64, mkexpr(t4), - unop(Iop_Not64, binop(Iop_Shl64, - mkU64(0x01), - mkU8(i)))))); - assign(t4, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x02)), - mkexpr(tmp), - mkexpr(t4))); - - } - - assign(t5, mkexpr(t4)); - - for (i = 0; i < 32; i++) { - assign(tmp, binop(Iop_Or64, - binop(Iop_And64, - binop(Iop_Shr64, mkexpr(t4), mkU8(0x01)), - binop(Iop_Shl64, mkU64(0x01), mkU8(i))), - binop(Iop_And64, mkexpr(t5), - unop(Iop_Not64, binop(Iop_Shl64, - mkU64(0x01), - mkU8(i)))))); - assign(t4, IRExpr_ITE(binop(Iop_And32, mkexpr(shift), mkU32(0x02)), - mkexpr(tmp), - mkexpr(t5))); - - } - - putIReg(rt, mkexpr(t5)); + putIReg(rt, qop(Iop_Rotx32, getIReg(rs), mkU8(shift), + mkU8(shiftx), mkU8(stripe))); break; } diff --git a/VEX/priv/host_nanomips_defs.c b/VEX/priv/host_nanomips_defs.c old mode 100644 new mode 100755 index 9f0b975df3..1b669470a1 --- a/VEX/priv/host_nanomips_defs.c +++ b/VEX/priv/host_nanomips_defs.c @@ -304,6 +304,9 @@ void ppNANOMIPSInstr(const NANOMIPSInstr* i) case NMimm_ANDI: vex_printf("andi "); break; + case NMimm_ROTX: + vex_printf("rotx "); + break; default: vassert(0); @@ -317,8 +320,11 @@ void ppNANOMIPSInstr(const NANOMIPSInstr* i) vex_printf(", "); } - vex_printf("0x%X (%d)", i->NMin.Imm.imm, (Int)i->NMin.Imm.imm); - + if (i->NMin.Imm.op == NMimm_ROTX) + vex_printf("%u, %u, %u", (i->NMin.Imm.imm >> 7) & 0xF, + (i->NMin.Imm.imm >> 6) & 1, i->NMin.Imm.imm & 0x1F); + else + vex_printf("0x%X (%d)", i->NMin.Imm.imm, (Int)i->NMin.Imm.imm); break; case NMin_Alu: @@ -1202,6 +1208,7 @@ static UChar *mkFormNanoPU12(UChar * p, UInt rt, UInt rs, UInt opc2, UInt imm) case PU12_ORI: /* ORI */ case PU12_SLTIU: /* SLTIU */ case PU12_XORI: /* XORI */ + case PU12_PROTX: /* ROTX */ theInstr = ((PU12 << 26) | (rt << 21) | (rs << 16) | (opc2 << 12) | (imm)); return emit32(p, theInstr); @@ -1380,6 +1387,9 @@ Int emit_NANOMIPSInstr ( /*MB_MOD*/Bool* is_profInc, p = mkFormNanoPU12(p, r_dst, r_src, i->NMin.Imm.op - 0x6, i->NMin.Imm.imm); break; + case NMimm_ROTX: + p = mkFormNanoPU12(p, r_dst, r_src, PU12_PROTX, i->NMin.Imm.imm); + break; default: goto bad; diff --git a/VEX/priv/host_nanomips_defs.h b/VEX/priv/host_nanomips_defs.h index d1b49395ab..6690ad08a6 100644 --- a/VEX/priv/host_nanomips_defs.h +++ b/VEX/priv/host_nanomips_defs.h @@ -179,6 +179,7 @@ typedef enum { NMimm_ORI = 0x06, /* Logical or */ NMimm_XORI = 0x07, /* Logical xor */ NMimm_ANDI = 0x08, /* Logical and */ + NMimm_ROTX = 0x09, /* Rotx */ } NANOMIPSImmOp; typedef enum { diff --git a/VEX/priv/host_nanomips_isel.c b/VEX/priv/host_nanomips_isel.c index fe60a495de..59adf5868b 100644 --- a/VEX/priv/host_nanomips_isel.c +++ b/VEX/priv/host_nanomips_isel.c @@ -840,6 +840,23 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) vpanic("\n"); } + case Iex_Qop: { + HReg dst = newVRegI(env); + HReg src1 = iselWordExpr_R(env, e->Iex.Qop.details->arg1); + UChar src2 = e->Iex.Qop.details->arg2->Iex.Const.con->Ico.U8; + UChar src3 = e->Iex.Qop.details->arg3->Iex.Const.con->Ico.U8; + UChar src4 = e->Iex.Qop.details->arg4->Iex.Const.con->Ico.U8; + UInt imm = (src3 << 6) | (src4 << 6) | src2; + switch (e->Iex.Qop.details->op) { + case Iop_Rotx32: + addInstr(env, NANOMIPSInstr_Imm(NMimm_ROTX, dst, src1, imm)); + return dst; + default: + break; + } + break; + } + case Iex_ITE: { vassert(typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1); HReg r0 = iselWordExpr_R(env, e->Iex.ITE.iffalse);