Generate code to handle 64-bit integer loads and stores on 32-bit
targets, as this is needed by Massif in Valgrind 3.3.0.



git-svn-id: svn://svn.valgrind.org/vex/trunk@1804 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host-ppc/isel.c b/priv/host-ppc/isel.c
index 631d363..c3c400b 100644
--- a/priv/host-ppc/isel.c
+++ b/priv/host-ppc/isel.c
@@ -2552,6 +2552,23 @@
    vassert(e);
    vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
 
+   /* 64-bit load */
+   if (e->tag == Iex_Load) {
+      HReg tLo    = newVRegI(env);
+      HReg tHi    = newVRegI(env);
+      HReg r_addr = iselWordExpr_R(env, e->Iex.Load.addr);
+      vassert(!env->mode64);
+      addInstr(env, PPCInstr_Load( 4/*byte-load*/,
+                                   tHi, PPCAMode_IR( 0, r_addr ), 
+                                   False/*32-bit insn please*/) );
+      addInstr(env, PPCInstr_Load( 4/*byte-load*/, 
+                                   tLo, PPCAMode_IR( 4, r_addr ), 
+                                   False/*32-bit insn please*/) );
+      *rHi = tHi;
+      *rLo = tLo;
+      return;
+   }
+
    /* 64-bit literal */
    if (e->tag == Iex_Const) {
       ULong w64 = e->Iex.Const.con->Ico.U64;
@@ -3668,7 +3685,6 @@
 
    /* --------- STORE --------- */
    case Ist_Store: {
-      PPCAMode* am_addr;
       IRType    tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
       IRType    tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
       IREndness end = stmt->Ist.Store.end;
@@ -3678,32 +3694,56 @@
            ( mode64 && (tya != Ity_I64)) )
          goto stmt_fail;
 
-      am_addr = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/);
       if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32 ||
           (mode64 && (tyd == Ity_I64))) {
+         PPCAMode* am_addr
+            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/);
          HReg r_src = iselWordExpr_R(env, stmt->Ist.Store.data);
          addInstr(env, PPCInstr_Store( toUChar(sizeofIRType(tyd)), 
-                                         am_addr, r_src, mode64 ));
+                                       am_addr, r_src, mode64 ));
          return;
       }
       if (tyd == Ity_F64) {
+         PPCAMode* am_addr
+            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/);
          HReg fr_src = iselDblExpr(env, stmt->Ist.Store.data);
          addInstr(env,
                   PPCInstr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
          return;
       }
       if (tyd == Ity_F32) {
+         PPCAMode* am_addr
+            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/);
          HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data);
          addInstr(env,
                   PPCInstr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
          return;
       }
       if (tyd == Ity_V128) {
+         PPCAMode* am_addr
+            = iselWordExpr_AMode(env, stmt->Ist.Store.addr, tyd/*of xfer*/);
          HReg v_src = iselVecExpr(env, stmt->Ist.Store.data);
          addInstr(env,
                   PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
          return;
       }
+      if (tyd == Ity_I64 && !mode64) {
+         /* Just calculate the address in the register.  Life is too
+            short to arse around trying and possibly failing to adjust
+            the offset in a 'reg+offset' style amode. */
+         HReg rHi32, rLo32;
+         HReg r_addr = iselWordExpr_R(env, stmt->Ist.Store.addr);
+         iselInt64Expr( &rHi32, &rLo32, env, stmt->Ist.Store.data );
+         addInstr(env, PPCInstr_Store( 4/*byte-store*/,
+                                       PPCAMode_IR( 0, r_addr ), 
+                                       rHi32,
+                                       False/*32-bit insn please*/) );
+         addInstr(env, PPCInstr_Store( 4/*byte-store*/, 
+                                       PPCAMode_IR( 4, r_addr ), 
+                                       rLo32,
+                                       False/*32-bit insn please*/) );
+         return;
+      }
       break;
    }