PPC: Fix constant pool overflow access in Get/SetRelocatedValue.
authormbrandy <mbrandy@us.ibm.com>
Tue, 30 Jun 2015 18:57:13 +0000 (11:57 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 30 Jun 2015 18:57:27 +0000 (18:57 +0000)
This resolves the mirror-object test failure.

R=dstence@us.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1214903009

Cr-Commit-Position: refs/heads/master@{#29391}

src/ppc/macro-assembler-ppc.cc
src/ppc/macro-assembler-ppc.h

index d0960cc..7cd8955 100644 (file)
@@ -3242,6 +3242,35 @@ void MacroAssembler::FlushICache(Register address, size_t size,
 }
 
 
+void MacroAssembler::DecodeConstantPoolOffset(Register result,
+                                              Register location) {
+  Label overflow_access, done;
+  DCHECK(!AreAliased(result, location, r0));
+
+  // Determine constant pool access type
+  // Caller has already placed the instruction word at location in result.
+  ExtractBitRange(r0, result, 31, 26);
+  cmpi(r0, Operand(ADDIS >> 26));
+  beq(&overflow_access);
+
+  // Regular constant pool access
+  // extract the load offset
+  andi(result, result, Operand(kImm16Mask));
+  b(&done);
+
+  bind(&overflow_access);
+  // Overflow constant pool access
+  // shift addis immediate
+  slwi(r0, result, Operand(16));
+  // sign-extend and add the load offset
+  lwz(result, MemOperand(location, kInstrSize));
+  extsh(result, result);
+  add(result, r0, result);
+
+  bind(&done);
+}
+
+
 void MacroAssembler::SetRelocatedValue(Register location, Register scratch,
                                        Register new_value) {
   lwz(scratch, MemOperand(location));
@@ -3255,8 +3284,7 @@ void MacroAssembler::SetRelocatedValue(Register location, Register scratch,
       // Scratch was clobbered. Restore it.
       lwz(scratch, MemOperand(location));
     }
-    // Get the address of the constant and patch it.
-    andi(scratch, scratch, Operand(kImm16Mask));
+    DecodeConstantPoolOffset(scratch, location);
     StorePX(new_value, MemOperand(kConstantPoolRegister, scratch));
     return;
   }
@@ -3352,8 +3380,7 @@ void MacroAssembler::GetRelocatedValue(Register location, Register result,
       Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
       lwz(result, MemOperand(location));
     }
-    // Get the address of the constant and retrieve it.
-    andi(result, result, Operand(kImm16Mask));
+    DecodeConstantPoolOffset(result, location);
     LoadPX(result, MemOperand(kConstantPoolRegister, result));
     return;
   }
index 019ca22..c0992c9 100644 (file)
@@ -1367,6 +1367,10 @@ class MacroAssembler : public Assembler {
   // ---------------------------------------------------------------------------
   // Patching helpers.
 
+  // Decode offset from constant pool load instruction(s).
+  // Caller must place the instruction word at <location> in <result>.
+  void DecodeConstantPoolOffset(Register result, Register location);
+
   // Retrieve/patch the relocated value (lis/ori pair or constant pool load).
   void GetRelocatedValue(Register location, Register result, Register scratch);
   void SetRelocatedValue(Register location, Register scratch,