]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: rewrite parts of mips_dirtyhelper_rdhwr
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 16 May 2017 15:21:35 +0000 (15:21 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 16 May 2017 15:21:35 +0000 (15:21 +0000)
The idea behind this change is to be less dependent on build-flags, and
more dependent on runtime environment.
So, if the code is compiled for mips32r1, it should be able to execute
mips32r2 code if the platforms supports it.

git-svn-id: svn://svn.valgrind.org/vex/trunk@3373

VEX/priv/guest_mips_defs.h
VEX/priv/guest_mips_helpers.c
VEX/priv/guest_mips_toIR.c

index a748657b83f5a6a8c6c10aa6806e39ab69b33f63..5ea213d2223ee38abd3aea4b8c192db89077bd1d 100644 (file)
@@ -100,9 +100,7 @@ typedef enum {
    #define MIPS_IEND Iend_BE
 #endif
 
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-extern HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd );
-#endif
+extern HWord mips_dirtyhelper_rdhwr ( UInt rd );
 
 /* Calculate FCSR in fp32 mode. */
 extern UInt mips_dirtyhelper_calculate_FCSR_fp32 ( void* guest_state, UInt fs,
index fdc00bd57d066caa3e44bf03683425ff12987d5c..00a92c3ac73bc6ece73305ca3d54d3803cabc421 100644 (file)
@@ -424,29 +424,35 @@ VexGuestLayout mips64Guest_layout = {
                   }
 };
 
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd )
+#define ASM_VOLATILE_RDHWR(opcode)                                 \
+   __asm__ __volatile__(".word 0x7C02003B | "#opcode" << 11  \n\t" \
+                        : "+r" (x) : :                             \
+                       )
+
+HWord mips_dirtyhelper_rdhwr ( UInt rd )
 {
-   HWord x = 0;
+#if defined(__mips__)
+   register HWord x __asm__("v0") = 0;
+
    switch (rd) {
       case 0:  /* x = CPUNum() */
-         __asm__ __volatile__("rdhwr %0, $0\n\t" : "=r" (x) );
+         ASM_VOLATILE_RDHWR(0); /* rdhwr v0, $0 */
          break;
 
       case 1:  /* x = SYNCI_Step() */
-         __asm__ __volatile__("rdhwr %0, $1\n\t" : "=r" (x) );
+         ASM_VOLATILE_RDHWR(1); /* rdhwr v0, $1 */
          break;
 
       case 2:  /* x = CC() */
-         __asm__ __volatile__("rdhwr %0, $2\n\t" : "=r" (x) );
+         ASM_VOLATILE_RDHWR(2); /* rdhwr v0, $2 */
          break;
 
       case 3:  /* x = CCRes() */
-         __asm__ __volatile__("rdhwr %0, $3\n\t" : "=r" (x) );
+         ASM_VOLATILE_RDHWR(3); /* rdhwr v0, $3 */
          break;
 
       case 31:  /* x = CVMX_get_cycles() */
-         __asm__ __volatile__("rdhwr %0, $31\n\t" : "=r" (x) );
+         ASM_VOLATILE_RDHWR(31); /* rdhwr v0, $31 */
          break;
 
       default:
@@ -454,8 +460,10 @@ HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd )
          break;
    }
    return x;
-}
+#else
+   return 0;
 #endif
+}
 
 #define ASM_VOLATILE_UNARY32(inst)                                  \
    __asm__ volatile(".set  push"        "\n\t"                      \
@@ -648,7 +656,8 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
                                                    flt_op inst )
 {
    UInt ret = 0;
-#if defined(__mips__)
+#if defined(__mips__) && ((__mips == 64) ||                                  \
+                          (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)))
 #if defined(VGA_mips32)
    VexGuestMIPS32State* guest_state = (VexGuestMIPS32State*)gs;
 #else
@@ -699,8 +708,6 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
       case ROUNDWS:
          ASM_VOLATILE_UNARY64(round.w.s)
          break;
-#if ((__mips == 32) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) \
-    || (__mips == 64)
       case CEILLS:
          ASM_VOLATILE_UNARY64(ceil.l.s)
          break;
@@ -737,7 +744,6 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
       case TRUNCLD:
          ASM_VOLATILE_UNARY64(trunc.l.d)
          break;
-#endif
       case ADDS:
           ASM_VOLATILE_BINARY64(add.s)
           break;
index 46e3824321cb2d71f9f92fecd6db9cefd3f11072..a73b5dc3440fc912af8e842fc4886ffa38d5818a 100644 (file)
@@ -15091,29 +15091,31 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
             goto decode_failure;;
          }
          break;
-      case 0x3B: {  /* RDHWR */
+      case 0x3B: /* RDHWR */
          DIP("rdhwr r%u, r%u", rt, rd);
+         if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
+             (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
             if (rd == 29) {
                putIReg(rt, getULR());
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
             } else if (rd <= 3
                        || (rd == 31
                            && VEX_MIPS_COMP_ID(archinfo->hwcaps)
                                                     == VEX_PRID_COMP_CAVIUM)) {
-               IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
+               IRExpr** arg = mkIRExprVec_1(mkU32(rd));
                IRTemp   val  = newTemp(ty);
                IRDirty *d = unsafeIRDirty_1_N(val,
                                               0,
                                               "mips_dirtyhelper_rdhwr",
                                               &mips_dirtyhelper_rdhwr,
-                                              args);
+                                              arg);
                stmt(IRStmt_Dirty(d));
                putIReg(rt, mkexpr(val));
-#endif
             } else
                goto decode_failure;
-            break;
+         } else {
+            ILLEGAL_INSTRUCTON;
          }
+         break;
       case 0x04:  /* INS */
          msb = get_msb(cins);
          lsb = get_lsb(cins);
@@ -17299,6 +17301,8 @@ DisResult disInstr_MIPS( IRSB*        irsb_IN,
    mode64 = guest_arch != VexArchMIPS32;
    fp_mode64 = abiinfo->guest_mips_fp_mode64;
 
+   vassert(VEX_MIPS_HOST_FP_MODE(archinfo->hwcaps) >= fp_mode64);
+
    guest_code = guest_code_IN;
    irsb = irsb_IN;
    host_endness = host_endness_IN;