mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-14 14:58:07 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
14
VEX/priv/host_nanomips_defs.c
Normal file → Executable file
14
VEX/priv/host_nanomips_defs.c
Normal file → Executable file
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user