< prev index next >

src/cpu/s390/vm/macroAssembler_s390.cpp

Print this page

        

@@ -2020,22 +2020,58 @@
 
   z_sgr(Z_SP, offset);
   z_stg(fp, _z_abi(callers_sp), Z_SP);
 }
 
-// Resize_frame with SP(new) = [addr].
-void MacroAssembler::resize_frame_absolute(Register addr, Register fp, bool load_fp) {
-  assert_different_registers(addr, fp, Z_SP);
-  if (load_fp) { z_lg(fp, _z_abi(callers_sp), Z_SP); }
-
-  if (addr != Z_R0) {
-    // Minimize stalls by not using Z_SP immediately after update.
-    z_stg(fp, _z_abi(callers_sp), addr);
-    z_lgr(Z_SP, addr);
+// Resize_frame with SP(new) = [newSP] + offset.
+//   This emitter is useful if we already have calculated a pointer
+//   into the to-be-allocated stack space, e.g. with special alignment properties,
+//   but need some additional space, e.g. for spilling.
+//   newSP    is the pre-calculated pointer. It must not be modified.
+//   fp       holds, or is filled with, the frame pointer.
+//   offset   is the additional increment which is added to addr to form the new SP.
+//            Note: specify a negative value to reserve more space!
+//   load_fp == true  only indicates that fp is not pre-filled with the frame pointer.
+//                    It does not guarantee that fp contains the frame pointer at the end.
+void MacroAssembler::resize_frame_abs_with_offset(Register newSP, Register fp, int offset, bool load_fp) {
+  assert_different_registers(newSP, fp, Z_SP);
+
+  if (load_fp) {
+    z_lg(fp, _z_abi(callers_sp), Z_SP);
+  }
+
+  if (newSP == Z_R0) {
+    add2reg(Z_SP, offset, newSP);
+    z_stg(fp, _z_abi(callers_sp), Z_SP);
+  } else {
+    z_stg(fp, _z_abi(callers_sp)+offset, newSP);
+    add2reg(Z_SP, offset, newSP);
+  }
+}
+
+// Resize_frame with SP(new) = [newSP].
+//   load_fp == true  only indicates that fp is not pre-filled with the frame pointer.
+//                    It does not guarantee that fp contains the frame pointer at the end.
+void MacroAssembler::resize_frame_absolute(Register newSP, Register fp, bool load_fp) {
+  assert_different_registers(newSP, fp, Z_SP);
+
+  if (load_fp) {
+    if (newSP == Z_R0) {
+      z_lg(fp, _z_abi(callers_sp), Z_SP); // need to use load/store.
   } else {
-    z_lgr(Z_SP, addr);
+      DEBUG_ONLY(z_lghi(fp, -1);)         // safety net
+      z_mvc(_z_abi(callers_sp), sizeof(void*)-1, newSP, _z_abi(callers_sp), Z_SP);
+    }
+  }
+
+  z_lgr(Z_SP, newSP);
+  if (newSP == Z_R0) {
     z_stg(fp, _z_abi(callers_sp), Z_SP);
+  } else {
+    if (!load_fp) {
+      z_stg(fp, _z_abi(callers_sp), newSP);
+    }
   }
 }
 
 // Resize_frame with SP(new) = SP(old) + offset.
 void MacroAssembler::resize_frame(RegisterOrConstant offset, Register fp, bool load_fp) {
< prev index next >