]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Minor altivec changes:
authorJulian Seward <jseward@acm.org>
Sat, 22 Oct 2005 02:01:16 +0000 (02:01 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 22 Oct 2005 02:01:16 +0000 (02:01 +0000)
- vsplt{b,h,w}: guarantee to always produce in-range shifts
- lvs{l,r}: mask second arg to helper so assertion in helper doesn't fire.
  Also pass in offset to dest rather than reg #.

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

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

index db854cc0c645880d92f55e87414a835f734279a9..ce7df23211c50bb938cc9d99d9b312d9a32e60dd 100644 (file)
@@ -135,7 +135,7 @@ extern ULong ppc32g_dirtyhelper_MFTB ( void );
 
 extern void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
                                      UInt vD_idx, UInt sh,
-                                     UInt dirn );
+                                     UInt shift_right );
 
 #endif /* ndef __LIBVEX_GUEST_PPC32_DEFS_H */
 
index 2558a467466d8afb9884e84d0f6afa1cbd787453..d74739d49ef13201e6ce1c2dbbc831c859103e60 100644 (file)
@@ -102,7 +102,7 @@ ULong ppc32g_dirtyhelper_MFTB ( void )
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (reads guest state, writes guest mem) */
 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
-                              UInt vD_idx, UInt sh, UInt dirn )
+                              UInt vD_off, UInt sh, UInt shift_right )
 {
   static
   UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -112,15 +112,15 @@ void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
   U128* pU128_src;
   U128* pU128_dst;
 
-  vassert( vD_idx <= 31 );
-  vassert( sh     <= 15 );
-  vassert( dirn   <=  1 );
-  if (dirn == 1) /* shift right */
+  vassert( vD_off       <= sizeof(VexGuestPPC32State)-8 );
+  vassert( sh           <= 15 );
+  vassert( shift_right  <=  1 );
+  if (shift_right)
      sh = 16-sh;
   /* else shift left  */
 
   pU128_src = (U128*)&ref[sh];
-  pU128_dst = &gst->guest_VR0 + (vD_idx*sizeof(gst->guest_VR0));
+  pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
 
   (*pU128_dst)[0] = (*pU128_src)[0];
   (*pU128_dst)[1] = (*pU128_src)[1];
index f0a93e45a832e590c67c94233206b850c48da6a4..0732193bb939811eaf72e7dfe9da79c2ebaa2880 100644 (file)
@@ -4966,7 +4966,11 @@ static Bool dis_av_load ( UInt theInstr )
    switch (opc2) {
 
    case 0x006: { // lvsl (Load Vector for Shift Left, AV p123)
-      IRExpr** args = mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(0));
+      UInt vD_off = vectorGuestRegOffset(vD_addr);
+      IRExpr** args = mkIRExprVec_3(
+                         mkU32(vD_off), 
+                         binop(Iop_And32, mkexpr(EA), mkU32(0xF)),
+                         mkU32(0)/*left*/ );
       IRDirty* d = unsafeIRDirty_0_N (
                       0/*regparms*/, 
                       "ppc32g_dirtyhelper_LVS",
@@ -4977,7 +4981,7 @@ static Bool dis_av_load ( UInt theInstr )
       d->needsBBP = True;
       d->nFxState = 1;
       d->fxState[0].fx     = Ifx_Write;
-      d->fxState[0].offset = vectorGuestRegOffset(vD_addr);
+      d->fxState[0].offset = vD_off;
       d->fxState[0].size   = sizeof(U128);
 
       /* execute the dirty call, side-effecting guest state */
@@ -4985,7 +4989,11 @@ static Bool dis_av_load ( UInt theInstr )
       break;
    }
    case 0x026: { // lvsr (Load Vector for Shift Right, AV p125)
-      IRExpr** args = mkIRExprVec_3(mkU32(vD_addr), mkexpr(EA), mkU32(1));
+      UInt vD_off = vectorGuestRegOffset(vD_addr);
+      IRExpr** args = mkIRExprVec_3(
+                         mkU32(vD_off), 
+                         binop(Iop_And32, mkexpr(EA), mkU32(0xF)),
+                         mkU32(1)/*right*/ );
       IRDirty*    d = unsafeIRDirty_0_N (
                          0/*regparms*/, 
                          "ppc32g_dirtyhelper_LVS",
@@ -4996,7 +5004,7 @@ static Bool dis_av_load ( UInt theInstr )
       d->needsBBP = True;
       d->nFxState = 1;
       d->fxState[0].fx     = Ifx_Write;
-      d->fxState[0].offset = vectorGuestRegOffset(vD_addr);
+      d->fxState[0].offset = vD_off;
       d->fxState[0].size   = sizeof(U128);
 
       /* execute the dirty call, side-effecting guest state */
@@ -6050,7 +6058,7 @@ static Bool dis_av_permute ( UInt theInstr )
    /* Splat */
    case 0x20C: { // vspltb (Splat Byte, AV p245)
       /* vD = Dup8x16( vB[UIMM_5] ) */
-      UChar sh_uimm = (15-UIMM_5)*8;
+      UChar sh_uimm = (15 - (UIMM_5 & 15)) * 8;
       DIP("vspltb v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
       putVReg( vD_addr, unop(Iop_Dup8x16,
            unop(Iop_32to8, unop(Iop_V128to32, 
@@ -6058,7 +6066,7 @@ static Bool dis_av_permute ( UInt theInstr )
       break;
    }
    case 0x24C: { // vsplth (Splat Half Word, AV p246)
-      UChar sh_uimm = (7-UIMM_5)*16;
+      UChar sh_uimm = (7 - (UIMM_5 & 7)) * 16;
       DIP("vsplth v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
       putVReg( vD_addr, unop(Iop_Dup16x8,
            unop(Iop_32to16, unop(Iop_V128to32, 
@@ -6067,7 +6075,7 @@ static Bool dis_av_permute ( UInt theInstr )
    }
    case 0x28C: { // vspltw (Splat Word, AV p250)
       /* vD = Dup32x4( vB[UIMM_5] ) */
-      UChar sh_uimm = (3-UIMM_5)*32;
+      UChar sh_uimm = (3 - (UIMM_5 & 3)) * 32;
       DIP("vspltw v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
       putVReg( vD_addr, unop(Iop_Dup32x4,
          unop(Iop_V128to32,