]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix backend bug: the immediate on PPC32AMode_IR is 16 bits signed, not
authorJulian Seward <jseward@acm.org>
Sat, 2 Jul 2005 01:29:32 +0000 (01:29 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 2 Jul 2005 01:29:32 +0000 (01:29 +0000)
unsigned.

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

VEX/priv/host-ppc32/hdefs.c
VEX/priv/host-ppc32/hdefs.h
VEX/priv/host-ppc32/isel.c

index a06c09a71214f6447f0df2a465dcd862cbbb3754..d465ecfd7e251018bfd99813f0f6639d65052592 100644 (file)
@@ -320,9 +320,9 @@ PPC32CondTest invertCondTest ( PPC32CondTest ct )
 
 /* --------- PPCAMode: memory address expressions. --------- */
 
-PPC32AMode* PPC32AMode_IR ( UInt idx, HReg base ) {
+PPC32AMode* PPC32AMode_IR ( Int idx, HReg base ) {
    PPC32AMode* am = LibVEX_Alloc(sizeof(PPC32AMode));
-   vassert(idx < 0x10000);
+   vassert(idx >= -0x8000 && idx < 0x8000);
    am->tag = Pam_IR;
    am->Pam.IR.base = base;
    am->Pam.IR.index = idx;
@@ -353,7 +353,7 @@ void ppPPC32AMode ( PPC32AMode* am ) {
       if (am->Pam.IR.index == 0)
          vex_printf("0(");
       else
-         vex_printf("0x%x(", am->Pam.IR.index);
+         vex_printf("%d(", (Int)am->Pam.IR.index);
       ppHRegPPC32(am->Pam.IR.base);
       vex_printf(")");
       return;
index 0b123fd4910b704d1f1e164c8f0112e70b7e37c2..4c34385ba65d12ad72d7b1fe8c0b0027a23e3991 100644 (file)
@@ -202,7 +202,7 @@ extern PPC32CondTest invertCondTest ( PPC32CondTest );
 
 typedef
    enum {
-     Pam_IR,        /* Immediate + Reg */
+     Pam_IR,        /* Immediate (signed 16-bit) + Reg */
      Pam_RR         /* Reg1 + Reg2     */
    }
    PPC32AModeTag;
@@ -213,7 +213,7 @@ typedef
       union {
          struct {
             HReg base;
-            UInt index;
+            Int  index;
          } IR;
          struct {
             HReg base;
@@ -223,7 +223,7 @@ typedef
    }
    PPC32AMode;
 
-extern PPC32AMode* PPC32AMode_IR ( UInt, HReg );
+extern PPC32AMode* PPC32AMode_IR ( Int,  HReg );
 extern PPC32AMode* PPC32AMode_RR ( HReg, HReg );
 
 extern PPC32AMode* dopyPPC32AMode ( PPC32AMode* );
index 81533858dab4530d6c24f1485edc2ed436a126b8..4a9e58bc03648a90ef353498a2673de1a56486b3 100644 (file)
@@ -1471,13 +1471,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
    result.  The expression may only be a 32-bit one.
 */
 
+static Bool fits16bits ( UInt u ) 
+{
+   /* Is u the same as the sign-extend of its lower 16 bits? */
+   Int i = u & 0xFFFF;
+   i <<= 16;
+   i >>= 16;
+   return u == (UInt)i;
+}
+
 static Bool sane_AMode ( PPC32AMode* am )
 {
    switch (am->tag) {
    case Pam_IR:
       return (hregClass(am->Pam.IR.base) == HRcInt32
               && hregIsVirtual(am->Pam.IR.base)
-              && (am->Pam.IR.index < 0x10000));
+              && fits16bits(am->Pam.IR.index));
    case Pam_RR:
       return (hregClass(am->Pam.RR.base) == HRcInt32
               && hregIsVirtual(am->Pam.IR.base)
@@ -1501,14 +1510,14 @@ static PPC32AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e )
    IRType ty = typeOfIRExpr(env->type_env,e);
    vassert(ty == Ity_I32);
    
-   /* Add32(expr,i), where i<0x10000 */
+   /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */
    if (e->tag == Iex_Binop 
        && e->Iex.Binop.op == Iop_Add32
        && e->Iex.Binop.arg2->tag == Iex_Const
        && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
-       && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 < 0x10000) {
+       && fits16bits(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) {
       return PPC32AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32,
-                           iselIntExpr_R(env,  e->Iex.Binop.arg1));
+                           iselIntExpr_R(env, e->Iex.Binop.arg1));
    }
       
    /* Add32(expr,expr) */