Mark Wielaard 5c9a40
commit 6a55b1e82ccda3f0d663d2cc89eb543ae2d096bf
Mark Wielaard 5c9a40
Author: Carl Love <carll@us.ibm.com>
Mark Wielaard 5c9a40
Date:   Tue Oct 31 13:45:28 2017 -0500
Mark Wielaard 5c9a40
Mark Wielaard 5c9a40
    Fix access to time base register to return 64-bits.
Mark Wielaard 5c9a40
Mark Wielaard 5c9a40
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 5c9a40
index f63146e7e..4ec37f5f9 100644
Mark Wielaard 5c9a40
--- a/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 5c9a40
+++ b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 5c9a40
@@ -9419,26 +9419,60 @@ static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt theInstr )
Mark Wielaard 5c9a40
          putIReg( rD_addr, getGST( PPC_GST_SPRG3_RO ) );
Mark Wielaard 5c9a40
          break;
Mark Wielaard 5c9a40
 
Mark Wielaard 5c9a40
-      /* Even a lowly PPC7400 can run the associated helper, so no
Mark Wielaard 5c9a40
-         obvious need for feature testing at this point. */
Mark Wielaard 5c9a40
-      case 268 /* 0x10C */:
Mark Wielaard 5c9a40
-      case 269 /* 0x10D */: {
Mark Wielaard 5c9a40
-         UInt     arg  = SPR==268 ? 0 : 1;
Mark Wielaard 5c9a40
-         IRTemp   val  = newTemp(Ity_I32);
Mark Wielaard 5c9a40
-         IRExpr** args = mkIRExprVec_1( mkU32(arg) );
Mark Wielaard 5c9a40
+      case 268 /* 0x10C  TB  - 64 bit time base register */:
Mark Wielaard 5c9a40
+      {
Mark Wielaard 5c9a40
+         IRTemp   val  = newTemp(Ity_I64);
Mark Wielaard 5c9a40
+         IRExpr** args = mkIRExprVec_0();
Mark Wielaard 5c9a40
          IRDirty* d    = unsafeIRDirty_1_N(
Mark Wielaard 5c9a40
-                            val,
Mark Wielaard 5c9a40
-                            0/*regparms*/,
Mark Wielaard 5c9a40
-                            "ppc32g_dirtyhelper_MFSPR_268_269",
Mark Wielaard 5c9a40
-                            fnptr_to_fnentry
Mark Wielaard 5c9a40
-                               (vbi, &ppc32g_dirtyhelper_MFSPR_268_269),
Mark Wielaard 5c9a40
-                            args
Mark Wielaard 5c9a40
-                         );
Mark Wielaard 5c9a40
+                                           val,
Mark Wielaard 5c9a40
+                                           0/*regparms*/,
Mark Wielaard 5c9a40
+                                           "ppcg_dirtyhelper_MFTB",
Mark Wielaard 5c9a40
+                                           fnptr_to_fnentry(vbi,
Mark Wielaard 5c9a40
+                                                            &ppcg_dirtyhelper_MFTB),
Mark Wielaard 5c9a40
+                                           args );
Mark Wielaard 5c9a40
+         /* execute the dirty call, dumping the result in val. */
Mark Wielaard 5c9a40
+         stmt( IRStmt_Dirty(d) );
Mark Wielaard 5c9a40
+         putIReg( rD_addr, (mode64) ? mkexpr(val) :
Mark Wielaard 5c9a40
+                                      unop(Iop_64to32, mkexpr(val)) );
Mark Wielaard 5c9a40
+
Mark Wielaard 5c9a40
+         break;
Mark Wielaard 5c9a40
+      }
Mark Wielaard 5c9a40
+      case 269 /* 0x10D  TBU - upper 32-bits of time base register */:
Mark Wielaard 5c9a40
+      {
Mark Wielaard 5c9a40
+         DIP("mfspr r%u,%u", rD_addr, SPR);
Mark Wielaard 5c9a40
+         IRTemp   val  = newTemp(Ity_I64);
Mark Wielaard 5c9a40
+         IRExpr** args = mkIRExprVec_0();
Mark Wielaard 5c9a40
+         IRDirty* d    = unsafeIRDirty_1_N(
Mark Wielaard 5c9a40
+                                           val,
Mark Wielaard 5c9a40
+                                           0/*regparms*/,
Mark Wielaard 5c9a40
+                                           "ppcg_dirtyhelper_MFTB",
Mark Wielaard 5c9a40
+                                           fnptr_to_fnentry(vbi,
Mark Wielaard 5c9a40
+                                                            &ppcg_dirtyhelper_MFTB),
Mark Wielaard 5c9a40
+                                           args );
Mark Wielaard 5c9a40
          /* execute the dirty call, dumping the result in val. */
Mark Wielaard 5c9a40
          stmt( IRStmt_Dirty(d) );
Mark Wielaard 5c9a40
          putIReg( rD_addr,
Mark Wielaard 5c9a40
-                  mkWidenFrom32(ty, mkexpr(val), False/*unsigned*/) );
Mark Wielaard 5c9a40
+                  mkWidenFrom32(ty, unop(Iop_64HIto32, mkexpr(val)),
Mark Wielaard 5c9a40
+                                /* Signed */False) );
Mark Wielaard 5c9a40
+         break;
Mark Wielaard 5c9a40
+      }
Mark Wielaard 5c9a40
+      case 284 /* 0x1  TBL - lower 32-bits of time base register */:
Mark Wielaard 5c9a40
+      {
Mark Wielaard 5c9a40
          DIP("mfspr r%u,%u", rD_addr, SPR);
Mark Wielaard 5c9a40
+         IRTemp   val  = newTemp(Ity_I64);
Mark Wielaard 5c9a40
+         IRExpr** args = mkIRExprVec_0();
Mark Wielaard 5c9a40
+         IRDirty* d    = unsafeIRDirty_1_N(
Mark Wielaard 5c9a40
+                                           val,
Mark Wielaard 5c9a40
+                                           0/*regparms*/,
Mark Wielaard 5c9a40
+                                           "ppcg_dirtyhelper_MFTB",
Mark Wielaard 5c9a40
+                                           fnptr_to_fnentry(vbi,
Mark Wielaard 5c9a40
+                                                            &ppcg_dirtyhelper_MFTB),
Mark Wielaard 5c9a40
+                                           args );
Mark Wielaard 5c9a40
+         /* execute the dirty call, dumping the result in val. */
Mark Wielaard 5c9a40
+         stmt( IRStmt_Dirty(d) );
Mark Wielaard 5c9a40
+         putIReg( rD_addr,
Mark Wielaard 5c9a40
+                  mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(val)),
Mark Wielaard 5c9a40
+                                /* Signed */False) );
Mark Wielaard 5c9a40
          break;
Mark Wielaard 5c9a40
       }
Mark Wielaard 5c9a40
 
Mark Wielaard 5c9a40
@@ -9493,6 +9527,12 @@ static Bool dis_proc_ctl ( const VexAbiInfo* vbi, UInt theInstr )
Mark Wielaard 5c9a40
          putIReg( rD_addr, (mode64) ? mkexpr(val) :
Mark Wielaard 5c9a40
                                       unop(Iop_64to32, mkexpr(val)) );
Mark Wielaard 5c9a40
          break;
Mark Wielaard 5c9a40
+      case 284:
Mark Wielaard 5c9a40
+         DIP("mftbl r%u", rD_addr);
Mark Wielaard 5c9a40
+         putIReg( rD_addr,
Mark Wielaard 5c9a40
+                  mkWidenFrom32(ty, unop(Iop_64to32, mkexpr(val)),
Mark Wielaard 5c9a40
+                                /* Signed */False) );
Mark Wielaard 5c9a40
+         break;
Mark Wielaard 5c9a40
       default:
Mark Wielaard 5c9a40
          return False; /* illegal instruction */
Mark Wielaard 5c9a40
       }