< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.hpp

Print this page
rev 8690 : 8131362: aarch64: C2 does not handle large stack offsets
Summary: change spill code to allow large offsets
Reviewed-by: duke

@@ -466,10 +466,14 @@
 
   void movptr(Register r, uintptr_t imm64);
 
   void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
 
+  void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
+    orr(Vd, T, Vn, Vn);
+  }
+
   // macro instructions for accessing and updating floating point
   // status register
   //
   // FPSR : op1 == 011
   //        CRn == 0100

@@ -1159,10 +1163,49 @@
 private:
   // Return the effective address r + (r1 << ext) + offset.
   // Uses rscratch2.
   Address offsetted_address(Register r, Register r1, Address::extend ext,
                             int offset, int size);
+
+private:
+  // Returns an address on the stack which is reachable with a ldr/str of size
+  // Uses rscratch2 if the address is not directly reachable
+  Address spill_address(int size, int offset);
+
+public:
+  void spill(Register Rx, bool is64, int offset) {
+    if (is64) {
+      str(Rx, spill_address(8, offset));
+    } else {
+      strw(Rx, spill_address(4, offset));
+    }
+  }
+  void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
+    str(Vx, T, spill_address(1 << (int)T, offset));
+  }
+  void unspill(Register Rx, bool is64, int offset) {
+    if (is64) {
+      ldr(Rx, spill_address(8, offset));
+    } else {
+      ldrw(Rx, spill_address(4, offset));
+    }
+  }
+  void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
+    ldr(Vx, T, spill_address(1 << (int)T, offset));
+  }
+  void spill_copy128(int src_offset, int dst_offset) {
+    if (src_offset < 512 && (src_offset & 7) == 0 &&
+        dst_offset < 512 && (dst_offset & 7) == 0) {
+      ldp(rscratch1, rscratch2, Address(sp, src_offset));
+      stp(rscratch1, rscratch2, Address(sp, dst_offset));
+    } else {
+      unspill(rscratch1, true, src_offset);
+      spill(rscratch1, true, dst_offset);
+      unspill(rscratch1, true, src_offset+4);
+      spill(rscratch1, true, dst_offset+4);
+    }
+  }
 };
 
 #ifdef ASSERT
 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
 #endif
< prev index next >