< prev index next >
src/cpu/s390/vm/macroAssembler_s390.cpp
Print this page
*** 2020,2058 ****
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);
} else {
- z_lgr(Z_SP, addr);
z_stg(fp, _z_abi(callers_sp), Z_SP);
}
}
// Resize_frame with SP(new) = SP(old) + offset.
void MacroAssembler::resize_frame(RegisterOrConstant offset, Register fp, bool load_fp) {
assert_different_registers(fp, Z_SP);
- if (load_fp) z_lg(fp, _z_abi(callers_sp), Z_SP);
! if (Displacement::is_validDisp((int)_z_abi(callers_sp) + offset.constant_or_zero())) {
! // Minimize stalls by first using, then updating Z_SP.
! // Do that only if we have a small positive offset or if ExtImm are available.
! z_stg(fp, Address(Z_SP, offset, _z_abi(callers_sp)));
! add64(Z_SP, offset);
! } else {
add64(Z_SP, offset);
z_stg(fp, _z_abi(callers_sp), Z_SP);
- }
}
void MacroAssembler::push_frame(Register bytes, Register old_sp, bool copy_sp, bool bytes_with_inverted_sign) {
#ifdef ASSERT
assert_different_registers(bytes, old_sp, Z_SP);
--- 2020,2076 ----
z_sgr(Z_SP, offset);
z_stg(fp, _z_abi(callers_sp), Z_SP);
}
! // 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);
! }
! add2reg(Z_SP, offset, newSP);
! z_stg(fp, _z_abi(callers_sp), Z_SP);
! }
!
! // 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) {
! z_lg(fp, _z_abi(callers_sp), Z_SP); // need to use load/store.
! }
!
! z_lgr(Z_SP, newSP);
! if (newSP != Z_R0) { // make sure we generate correct code, no matter what register newSP uses.
! z_stg(fp, _z_abi(callers_sp), newSP);
} else {
z_stg(fp, _z_abi(callers_sp), Z_SP);
}
}
// Resize_frame with SP(new) = SP(old) + offset.
void MacroAssembler::resize_frame(RegisterOrConstant offset, Register fp, bool load_fp) {
assert_different_registers(fp, Z_SP);
! if (load_fp) {
! z_lg(fp, _z_abi(callers_sp), Z_SP);
! }
add64(Z_SP, offset);
z_stg(fp, _z_abi(callers_sp), Z_SP);
}
void MacroAssembler::push_frame(Register bytes, Register old_sp, bool copy_sp, bool bytes_with_inverted_sign) {
#ifdef ASSERT
assert_different_registers(bytes, old_sp, Z_SP);
*** 2061,2096 ****
asm_assert_eq("[old_sp]!=[Z_SP]", 0x211);
}
#endif
if (copy_sp) { z_lgr(old_sp, Z_SP); }
if (bytes_with_inverted_sign) {
! z_stg(old_sp, 0, bytes, Z_SP);
! add2reg_with_index(Z_SP, 0, bytes, Z_SP);
} else {
z_sgr(Z_SP, bytes); // Z_sgfr sufficient, but probably not faster.
z_stg(old_sp, 0, Z_SP);
}
}
unsigned int MacroAssembler::push_frame(unsigned int bytes, Register scratch) {
long offset = Assembler::align(bytes, frame::alignment_in_bytes);
- if (Displacement::is_validDisp(-offset)) {
- // Minimize stalls by first using, then updating Z_SP.
- // Do that only if we have ExtImm available.
- z_stg(Z_SP, -offset, Z_SP);
- add2reg(Z_SP, -offset);
- } else {
- if (scratch != Z_R0 && scratch != Z_R1) {
- z_stg(Z_SP, -offset, Z_SP);
- add2reg(Z_SP, -offset);
- } else { // scratch == Z_R0 || scratch == Z_R1
z_lgr(scratch, Z_SP);
add2reg(Z_SP, -offset);
z_stg(scratch, 0, Z_SP);
- }
- }
return offset;
}
// Push a frame of size `bytes' plus abi160 on top.
unsigned int MacroAssembler::push_frame_abi160(unsigned int bytes) {
--- 2079,2102 ----
asm_assert_eq("[old_sp]!=[Z_SP]", 0x211);
}
#endif
if (copy_sp) { z_lgr(old_sp, Z_SP); }
if (bytes_with_inverted_sign) {
! z_agr(Z_SP, bytes);
! z_stg(old_sp, 0, Z_SP);
} else {
z_sgr(Z_SP, bytes); // Z_sgfr sufficient, but probably not faster.
z_stg(old_sp, 0, Z_SP);
}
}
unsigned int MacroAssembler::push_frame(unsigned int bytes, Register scratch) {
long offset = Assembler::align(bytes, frame::alignment_in_bytes);
z_lgr(scratch, Z_SP);
add2reg(Z_SP, -offset);
z_stg(scratch, 0, Z_SP);
return offset;
}
// Push a frame of size `bytes' plus abi160 on top.
unsigned int MacroAssembler::push_frame_abi160(unsigned int bytes) {
*** 2104,2113 ****
--- 2110,2133 ----
void MacroAssembler::pop_frame() {
BLOCK_COMMENT("pop_frame:");
Assembler::z_lg(Z_SP, _z_abi(callers_sp), Z_SP);
}
+ // Pop current C frame and restore return PC register (Z_R14).
+ void MacroAssembler::pop_frame_restore_retPC(int frame_size_in_bytes) {
+ BLOCK_COMMENT("pop_frame:");
+ int retPC_offset = _z_abi16(return_pc) + frame_size_in_bytes;
+ // If possible, pop frame by add instead of load (a penny saved is a penny got :-).
+ if (Displacement::is_validDisp(retPC_offset)) {
+ z_lg(Z_R14, retPC_offset, Z_SP);
+ add2reg(Z_SP, frame_size_in_bytes);
+ } else {
+ add2reg(Z_SP, frame_size_in_bytes);
+ restore_return_pc();
+ }
+ }
+
void MacroAssembler::call_VM_leaf_base(address entry_point, bool allow_relocation) {
if (allow_relocation) {
call_c(entry_point);
} else {
call_c_static(entry_point);
< prev index next >