]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: Add Iop_ROTX for nanoMIPS
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 14 Jan 2020 12:40:09 +0000 (12:40 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 14 Jan 2020 12:40:09 +0000 (12:40 +0000)
Implement Iop_ROTX and use it for ROTX instruction.
Fixes libvexmultiarch_test and libvex_test.

Patch by: Aleksandra Karadzic and Nikola Milutinovic.

VEX/priv/guest_nanomips_toIR.c
VEX/priv/host_nanomips_defs.c [changed mode: 0644->0755]
VEX/priv/host_nanomips_defs.h
VEX/priv/host_nanomips_isel.c

index 7233a736913fd214cb7fc024ff43b5a20312acb5..f06370ffd6349657630620311fb1dcc0574bae5a 100755 (executable)
@@ -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;
       }
 
old mode 100644 (file)
new mode 100755 (executable)
index 9f0b975..1b66947
@@ -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;
index d1b49395abe048daab1f0f28d5014502e517bdb7..6690ad08a624acc0c1deeed534ca04097c0e4431 100644 (file)
@@ -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 {
index fe60a495de7b0ab8401a0dc739fbf850bc29ea7e..59adf5868bfbbf44dd84d11f34299b8793ab0048 100644 (file)
@@ -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);