]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement mftb{,u}.
authorJulian Seward <jseward@acm.org>
Tue, 6 Sep 2005 10:25:46 +0000 (10:25 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 6 Sep 2005 10:25:46 +0000 (10:25 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@1371

VEX/priv/guest-ppc32/gdefs.h
VEX/priv/guest-ppc32/ghelpers.c
VEX/priv/guest-ppc32/toIR.c

index 6ee087a10184d9e015c4835580c60d70b576261c..22725e39d340e11526a772224257c81118a2d2c3 100644 (file)
@@ -101,14 +101,6 @@ typedef
    }
    PPC32CmpF64Result;
 
-
-/*---------------------------------------------------------*/
-/*--- ppc32 guest helpers                                 ---*/
-/*---------------------------------------------------------*/
-
-/* --- CLEAN HELPERS --- */
-
-
 /*
   Enumeration for xer_ca/ov calculation helper functions
 */
@@ -129,6 +121,19 @@ enum {
 };
 
 
+/*---------------------------------------------------------*/
+/*--- ppc32 guest helpers                                 ---*/
+/*---------------------------------------------------------*/
+
+/* --- CLEAN HELPERS --- */
+
+/* none, right now */
+
+/* --- DIRTY HELPERS --- */
+
+extern ULong ppc32g_dirtyhelper_MFTB ( void );
+
+
 #endif /* ndef __LIBVEX_GUEST_PPC32_DEFS_H */
 
 /*---------------------------------------------------------------*/
index 8794cb176e7ba6a280c63f0d6bc2a7be7d29e649..d5b97eb313c89c687a4442bebd06e32921bc0299 100644 (file)
 */
 
 
+/*---------------------------------------------------------------*/
+/*--- Misc integer helpers.                                   ---*/
+/*---------------------------------------------------------------*/
+
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (non-referentially-transparent) */
+/* Horrible hack.  On non-ppc32 platforms, return 1. */
+/* Reads a complete, consistent 64-bit TB value. */
+ULong ppc32g_dirtyhelper_MFTB ( void )
+{
+#  if defined(__powerpc__)
+   ULong res;
+   UInt  lo, hi1, hi2;
+   while (1) {
+      __asm__ __volatile__ ("\n"
+         "\tmftbu %0\n"
+         "\tmftb %1\n"
+         "\tmftbu %2\n"
+         : "=r" (hi1), "=r" (lo), "=r" (hi2)
+      );
+      if (hi1 == hi2) break;
+   }
+   res = ((ULong)hi1) << 32;
+   res |= (ULong)lo;
+   return res;
+#  else
+   return 1ULL;
+#  endif
+}
+
+
+/* Helper-function specialiser. */
 
 IRExpr* guest_ppc32_spechelper ( HChar* function_name,
                                  IRExpr** args )
index 18809fdf3793ea77bf5e9a5b84e99276f5d6fda9..e3b2c7bc975c50f8b02e99d83135278fd65c9a1d 100644 (file)
@@ -3446,7 +3446,7 @@ static Bool dis_proc_ctl ( UInt theInstr )
    /* XFX-Form */
    UChar Rs_addr  = toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:25] */
    UInt  SPR      =         (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */
-//uu   UInt  TBR      =         (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */
+   UInt  TBR      =         (theInstr >> 11) & 0x3FF; /* theInstr[11:20] */
    UChar b20      = toUChar((theInstr >> 11) & 0x1);  /* theInstr[11]    */
    UInt  CRM      =         (theInstr >> 12) & 0xFF;  /* theInstr[12:19] */
    UChar b11      = toUChar((theInstr >> 11) & 0x1);  /* theInstr[20]    */
@@ -3459,6 +3459,9 @@ static Bool dis_proc_ctl ( UInt theInstr )
    IRTemp Rs  = newTemp(Ity_I32);
 //uu   IRTemp tmp = newTemp(Ity_I32);
 
+   /* Reorder TBR field as per PPC32 p475 */
+   TBR = ((TBR & 31) << 5) | ((TBR >> 5) & 31);
+
    assign( Rs, getIReg(Rs_addr) );
    
    if (opc1 != 0x1F || b0 != 0) {
@@ -3569,12 +3572,34 @@ static Bool dis_proc_ctl ( UInt theInstr )
       }
       break;
       
-//zz    case 0x173: // mftb (Move from Time Base, PPC32 p475)
-//zz vassert(0);
-//zz 
-//zz       DIP("mftb r%d,0x%x\n", Rd_addr, TBR);
-//zz       return False;
-      
+   case 0x173: { // mftb (Move from Time Base, PPC32 p475)
+      IRTemp   val  = newTemp(Ity_I64);
+      IRExpr** args = mkIRExprVec_0();
+      IRDirty* d    = unsafeIRDirty_1_N ( 
+                         val, 
+                         0/*regparms*/, 
+                         "ppc32g_dirtyhelper_MFTB", 
+                         &ppc32g_dirtyhelper_MFTB, 
+                         args 
+                      );
+      /* execute the dirty call, dumping the result in val. */
+      stmt( IRStmt_Dirty(d) );
+
+      switch (TBR) {
+         case 269: 
+            putIReg( Rd_addr, unop(Iop_64HIto32, mkexpr(val)) );
+            DIP("mftbu r%d", Rd_addr);
+            break;
+         case 268: 
+            putIReg( Rd_addr, unop(Iop_64to32, mkexpr(val)) );
+            DIP("mftb r%d", Rd_addr);
+            break;
+         default:
+            return False; /* illegal instruction */
+      }
+      break;
+   }
+
    case 0x090: // mtcrf (Move to Condition Register Fields, PPC32 p477)
       if (b11 != 0 || b20 != 0) {
          vex_printf("dis_proc_ctl(PPC32)(mtcrf,b11|b20)\n");