]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support the DCBZL instruction. Also, query the host CPU at startup
authorJulian Seward <jseward@acm.org>
Fri, 3 Sep 2010 15:49:57 +0000 (15:49 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 3 Sep 2010 15:49:57 +0000 (15:49 +0000)
time to find out how much space DCBZL really clears, and make the
guest CPU act accordingly.  (VEX-side changes)
(Dave Goodell, goodell@mcs.anl.gov)

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

VEX/priv/guest_ppc_toIR.c
VEX/priv/main_main.c
VEX/pub/libvex.h

index b9b11753ecda7920ef9d0fabfaa805bf42304f5a..5d895f84dce93c635070b63c5a20b0ad922c00b2 100644 (file)
@@ -5604,6 +5604,7 @@ static Bool dis_cache_manage ( UInt         theInstr,
    UInt  opc2    = ifieldOPClo10(theInstr);
    UChar b0      = ifieldBIT0(theInstr);
    UInt  lineszB = guest_archinfo->ppc_cache_line_szB;
+   Bool  is_dcbzl = False;
 
    IRType ty     = mode64 ? Ity_I64 : Ity_I32;
 
@@ -5615,6 +5616,16 @@ static Bool dis_cache_manage ( UInt         theInstr,
      /* b21to25 &= ~3; */ /* if the docs were true */
      b21to25 = 0; /* blunt instrument */
    }
+   if (opc1 == 0x1F && opc2 == 0x3F6) { // dcbz
+      if (b21to25 == 1) {
+         is_dcbzl = True;
+         b21to25 = 0;
+         if (!(guest_archinfo->ppc_dcbzl_szB)) {
+            vex_printf("dis_cache_manage(ppc)(dcbzl not supported by host)\n");
+            return False;
+         }
+      }
+   }
 
    if (opc1 != 0x1F || b21to25 != 0 || b0 != 0) {
       if (0) vex_printf("dis_cache_manage %d %d %d\n", 
@@ -5654,12 +5665,21 @@ static Bool dis_cache_manage ( UInt         theInstr,
       break;
       
    case 0x3F6: { // dcbz (Data Cache Block Clear to Zero, PPC32 p387)
+                 // dcbzl (Data Cache Block Clear to Zero Long, bug#135264)
       /* Clear all bytes in cache block at (rA|0) + rB. */
       IRTemp  EA   = newTemp(ty);
       IRTemp  addr = newTemp(ty);
       IRExpr* irx_addr;
       UInt    i;
-      DIP("dcbz r%u,r%u\n", rA_addr, rB_addr);
+      UInt clearszB;
+      if (is_dcbzl) {
+          clearszB = guest_archinfo->ppc_dcbzl_szB;
+          DIP("dcbzl r%u,r%u\n", rA_addr, rB_addr);
+      }
+      else {
+          clearszB = guest_archinfo->ppc_dcbz_szB;
+          DIP("dcbz r%u,r%u\n", rA_addr, rB_addr);
+      }
 
       assign( EA, ea_rAor0_idxd(rA_addr, rB_addr) );
 
@@ -5667,9 +5687,9 @@ static Bool dis_cache_manage ( UInt         theInstr,
          /* Round EA down to the start of the containing block. */
          assign( addr, binop( Iop_And64,
                               mkexpr(EA),
-                              mkU64( ~((ULong)lineszB-1) )) );
+                              mkU64( ~((ULong)clearszB-1) )) );
          
-         for (i = 0; i < lineszB / 8; i++) {
+         for (i = 0; i < clearszB / 8; i++) {
             irx_addr = binop( Iop_Add64, mkexpr(addr), mkU64(i*8) );
             storeBE( irx_addr, mkU64(0) );
          }
@@ -5677,9 +5697,9 @@ static Bool dis_cache_manage ( UInt         theInstr,
          /* Round EA down to the start of the containing block. */
          assign( addr, binop( Iop_And32,
                               mkexpr(EA),
-                              mkU32( ~(lineszB-1) )) );
+                              mkU32( ~(clearszB-1) )) );
          
-         for (i = 0; i < lineszB / 4; i++) {
+         for (i = 0; i < clearszB / 4; i++) {
             irx_addr = binop( Iop_Add32, mkexpr(addr), mkU32(i*4) );
             storeBE( irx_addr, mkU32(0) );
          }
index ea0e5d0f559c39bdfa30b2eb384d38296cb5b9ba..1e80972ba3020e87558cf5f6e45b001f3681bf3e 100644 (file)
@@ -732,6 +732,9 @@ void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
 {
    vai->hwcaps             = 0;
    vai->ppc_cache_line_szB = 0;
+   vai->ppc_dcbz_szB       = 0;
+   vai->ppc_dcbzl_szB      = 0;
+
 }
 
 /* Write default settings info *vbi. */
index edc9f17bcd0d9950c823a2b71011a0b4e25dc308..a9e9bcefb136151f26040be553c9a1815cc85653 100644 (file)
@@ -120,6 +120,10 @@ typedef
       UInt hwcaps;
       /* PPC32/PPC64 only: size of cache line */
       Int ppc_cache_line_szB;
+      /* PPC32/PPC64 only: sizes zeroed by the dcbz/dcbzl instructions
+       * (bug#135264) */
+      UInt ppc_dcbz_szB;
+      UInt ppc_dcbzl_szB; /* 0 means unsupported (SIGILL) */
    }
    VexArchInfo;