]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: add support for Iop_Shr16 and Iop_Sar16
authorPetar Jovanovic <mips32r2@gmail.com>
Wed, 31 Jan 2018 16:27:13 +0000 (17:27 +0100)
committerPetar Jovanovic <mips32r2@gmail.com>
Wed, 31 Jan 2018 16:27:13 +0000 (17:27 +0100)
This should fix memcheck/tests/vbit-test/vbit-test on mips32/64 platforms.

VEX/priv/host_mips_isel.c
memcheck/tests/vbit-test/irops.c

index 9e9bcb59bab1a18b5dca1020625a0295d6341e96..ebc25a4ae188b6c23db3ce7ad91b1273be2cad40 100644 (file)
@@ -991,10 +991,12 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
             case Iop_Shl64:
                shftOp = Mshft_SLL;
                break;
+            case Iop_Shr16:
             case Iop_Shr32:
             case Iop_Shr64:
                shftOp = Mshft_SRL;
                break;
+            case Iop_Sar16:
             case Iop_Sar32:
             case Iop_Sar64:
                shftOp = Mshft_SRA;
@@ -1016,6 +1018,25 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
 
             if (ty == Ity_I8) {
                vassert(0);
+            } else if (ty == Ity_I16) {
+               if (shftOp == Mshft_SRA) {
+                  HReg tmp = newVRegI(env);
+                  HReg r_srcL_se = newVRegI(env);
+                  addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp,
+                                               r_srcL, MIPSRH_Imm(False, 16)));
+                  addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, r_srcL_se,
+                                               tmp, MIPSRH_Imm(False, 16)));
+                  addInstr(env, MIPSInstr_Shft(shftOp, True,
+                                               r_dst, r_srcL_se, ri_srcR));
+               } else if (shftOp == Mshft_SRL) {
+                  HReg r_srcL_se = newVRegI(env);
+                  addInstr(env, MIPSInstr_Alu(Malu_AND, r_srcL_se, r_srcL,
+                                              MIPSRH_Imm(False, 0xFFFF)));
+                  addInstr(env, MIPSInstr_Shft(shftOp, True,
+                                               r_dst, r_srcL_se, ri_srcR));
+               } else {
+                  vassert(0);
+               }
             } else if (ty == Ity_I32) {
                if (mode64 && (shftOp == Mshft_SRA || shftOp == Mshft_SRL)) {
                   HReg tmp = newVRegI(env);
index 5eea89bfc21f12320fd44614bbe86c324d869de7..a969a14b2694fec0503db41157b69792f6f3728e 100644 (file)
@@ -65,11 +65,11 @@ static irop_t irops[] = {
   { DEFOP(Iop_Shl32,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
   { DEFOP(Iop_Shl64,   UNDEF_SHL),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
   { DEFOP(Iop_Shr8,    UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Shr16,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Shr16,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 }, // ppc32/64 assert
   { DEFOP(Iop_Shr32,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
   { DEFOP(Iop_Shr64,   UNDEF_SHR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
   { DEFOP(Iop_Sar8,    UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
-  { DEFOP(Iop_Sar16,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 }, // ppc32/64 assert
+  { DEFOP(Iop_Sar16,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1 }, // ppc32/64 assert
   { DEFOP(Iop_Sar32,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 1, .ppc64 = 1, .ppc32 = 1, .mips32 = 1, .mips64 = 1 },
   { DEFOP(Iop_Sar64,   UNDEF_SAR),  .s390x = 1, .amd64 = 1, .x86 = 0, .arm = 1, .ppc64 = 1, .ppc32 = 0, .mips32 = 0, .mips64 = 1 }, // ppc32 asserts
   { DEFOP(Iop_CmpEQ8,  UNDEF_CMP_EQ_NE), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0 },