8293566: RISC-V: Clean up push and pop registers

Reviewed-by: fyang, shade
This commit is contained in:
Feilong Jiang 2022-09-13 01:07:04 +00:00 committed by Fei Yang
parent 526eb54fc3
commit 68645ebffb
5 changed files with 45 additions and 50 deletions

View file

@ -262,12 +262,12 @@ public:
// Save registers // Save registers
__ push_reg(_gp_regs, sp); __ push_reg(_gp_regs, sp);
__ push_fp(_fp_regs, sp); __ push_fp(_fp_regs, sp);
__ push_vp(_vp_regs, sp); __ push_v(_vp_regs, sp);
} }
~ZSaveLiveRegisters() { ~ZSaveLiveRegisters() {
// Restore registers // Restore registers
__ pop_vp(_vp_regs, sp); __ pop_v(_vp_regs, sp);
__ pop_fp(_fp_regs, sp); __ pop_fp(_fp_regs, sp);
__ pop_reg(_gp_regs, sp); __ pop_reg(_gp_regs, sp);
} }

View file

@ -915,7 +915,7 @@ void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
assert(ProfileInterpreter, "must be profiling interpreter"); assert(ProfileInterpreter, "must be profiling interpreter");
Label set_mdp; Label set_mdp;
push_reg(0xc00, sp); // save x10, x11 push_reg(RegSet::of(x10, x11), sp); // save x10, x11
// Test MDO to avoid the call if it is NULL. // Test MDO to avoid the call if it is NULL.
ld(x10, Address(xmethod, in_bytes(Method::method_data_offset()))); ld(x10, Address(xmethod, in_bytes(Method::method_data_offset())));
@ -928,7 +928,7 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
add(x10, x11, x10); add(x10, x11, x10);
sd(x10, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); sd(x10, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
bind(set_mdp); bind(set_mdp);
pop_reg(0xc00, sp); pop_reg(RegSet::of(x10, x11), sp);
} }
void InterpreterMacroAssembler::verify_method_data_pointer() { void InterpreterMacroAssembler::verify_method_data_pointer() {

View file

@ -946,7 +946,7 @@ int MacroAssembler::bitset_to_regs(unsigned int bitset, unsigned char* regs) {
return count; return count;
} }
// Push lots of registers in the bit set supplied. Don't push sp. // Push integer registers in the bitset supplied. Don't push sp.
// Return the number of words pushed // Return the number of words pushed
int MacroAssembler::push_reg(unsigned int bitset, Register stack) { int MacroAssembler::push_reg(unsigned int bitset, Register stack) {
DEBUG_ONLY(int words_pushed = 0;) DEBUG_ONLY(int words_pushed = 0;)
@ -958,11 +958,11 @@ int MacroAssembler::push_reg(unsigned int bitset, Register stack) {
int offset = is_even(count) ? 0 : wordSize; int offset = is_even(count) ? 0 : wordSize;
if (count) { if (count) {
addi(stack, stack, - count * wordSize - offset); addi(stack, stack, -count * wordSize - offset);
} }
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
sd(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); sd(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset));
DEBUG_ONLY(words_pushed ++;) DEBUG_ONLY(words_pushed++;)
} }
assert(words_pushed == count, "oops, pushed != count"); assert(words_pushed == count, "oops, pushed != count");
@ -981,7 +981,7 @@ int MacroAssembler::pop_reg(unsigned int bitset, Register stack) {
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
ld(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); ld(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset));
DEBUG_ONLY(words_popped ++;) DEBUG_ONLY(words_popped++;)
} }
if (count) { if (count) {
@ -992,11 +992,11 @@ int MacroAssembler::pop_reg(unsigned int bitset, Register stack) {
return count; return count;
} }
// Push float registers in the bitset, except sp. // Push floating-point registers in the bitset supplied.
// Return the number of heapwords pushed. // Return the number of words pushed
int MacroAssembler::push_fp(unsigned int bitset, Register stack) { int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this); CompressibleRegion cr(this);
int words_pushed = 0; DEBUG_ONLY(int words_pushed = 0;)
unsigned char regs[32]; unsigned char regs[32];
int count = bitset_to_regs(bitset, regs); int count = bitset_to_regs(bitset, regs);
int push_slots = count + (count & 1); int push_slots = count + (count & 1);
@ -1007,23 +1007,24 @@ int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
fsd(as_FloatRegister(regs[i]), Address(stack, (push_slots - 1 - i) * wordSize)); fsd(as_FloatRegister(regs[i]), Address(stack, (push_slots - 1 - i) * wordSize));
words_pushed++; DEBUG_ONLY(words_pushed++;)
} }
assert(words_pushed == count, "oops, pushed(%d) != count(%d)", words_pushed, count); assert(words_pushed == count, "oops, pushed(%d) != count(%d)", words_pushed, count);
return count; return count;
} }
int MacroAssembler::pop_fp(unsigned int bitset, Register stack) { int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this); CompressibleRegion cr(this);
int words_popped = 0; DEBUG_ONLY(int words_popped = 0;)
unsigned char regs[32]; unsigned char regs[32];
int count = bitset_to_regs(bitset, regs); int count = bitset_to_regs(bitset, regs);
int pop_slots = count + (count & 1); int pop_slots = count + (count & 1);
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
fld(as_FloatRegister(regs[i]), Address(stack, (pop_slots - 1 - i) * wordSize)); fld(as_FloatRegister(regs[i]), Address(stack, (pop_slots - 1 - i) * wordSize));
words_popped++; DEBUG_ONLY(words_popped++;)
} }
if (count) { if (count) {
@ -1031,23 +1032,20 @@ int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
} }
assert(words_popped == count, "oops, popped(%d) != count(%d)", words_popped, count); assert(words_popped == count, "oops, popped(%d) != count(%d)", words_popped, count);
return count; return count;
} }
#ifdef COMPILER2 #ifdef COMPILER2
int MacroAssembler::push_vp(unsigned int bitset, Register stack) { // Push vector registers in the bitset supplied.
// Return the number of words pushed
int MacroAssembler::push_v(unsigned int bitset, Register stack) {
CompressibleRegion cr(this); CompressibleRegion cr(this);
int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
// Scan bitset to accumulate register pairs // Scan bitset to accumulate register pairs
unsigned char regs[32]; unsigned char regs[32];
int count = 0; int count = bitset_to_regs(bitset, regs);
for (int reg = 31; reg >= 0; reg--) {
if ((1U << 31) & bitset) {
regs[count++] = reg;
}
bitset <<= 1;
}
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
sub(stack, stack, vector_size_in_bytes); sub(stack, stack, vector_size_in_bytes);
@ -1057,19 +1055,13 @@ int MacroAssembler::push_vp(unsigned int bitset, Register stack) {
return count * vector_size_in_bytes / wordSize; return count * vector_size_in_bytes / wordSize;
} }
int MacroAssembler::pop_vp(unsigned int bitset, Register stack) { int MacroAssembler::pop_v(unsigned int bitset, Register stack) {
CompressibleRegion cr(this); CompressibleRegion cr(this);
int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
// Scan bitset to accumulate register pairs // Scan bitset to accumulate register pairs
unsigned char regs[32]; unsigned char regs[32];
int count = 0; int count = bitset_to_regs(bitset, regs);
for (int reg = 31; reg >= 0; reg--) {
if ((1U << 31) & bitset) {
regs[count++] = reg;
}
bitset <<= 1;
}
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--) {
vl1r_v(as_VectorRegister(regs[i]), stack); vl1r_v(as_VectorRegister(regs[i]), stack);
@ -1090,7 +1082,7 @@ void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) {
int offset = 0; int offset = 0;
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) {
fsd(as_FloatRegister(i), Address(sp, wordSize * (offset ++))); fsd(as_FloatRegister(i), Address(sp, wordSize * (offset++)));
} }
} }
} }
@ -1100,7 +1092,7 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
int offset = 0; int offset = 0;
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) {
fld(as_FloatRegister(i), Address(sp, wordSize * (offset ++))); fld(as_FloatRegister(i), Address(sp, wordSize * (offset++)));
} }
} }
addi(sp, sp, wordSize * 20); addi(sp, sp, wordSize * 20);
@ -1111,7 +1103,7 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) { void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) {
CompressibleRegion cr(this); CompressibleRegion cr(this);
// integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4) // integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4)
push_reg(0xffffffe0, sp); push_reg(RegSet::range(x5, x31), sp);
// float registers // float registers
addi(sp, sp, - 32 * wordSize); addi(sp, sp, - 32 * wordSize);
@ -1148,7 +1140,7 @@ void MacroAssembler::pop_CPU_state(bool restore_vectors, int vector_size_in_byte
addi(sp, sp, 32 * wordSize); addi(sp, sp, 32 * wordSize);
// integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4) // integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4)
pop_reg(0xffffffe0, sp); pop_reg(RegSet::range(x5, x31), sp);
} }
static int patch_offset_in_jal(address branch, int64_t offset) { static int patch_offset_in_jal(address branch, int64_t offset) {

View file

@ -473,17 +473,26 @@ class MacroAssembler: public Assembler {
void double_blt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); void double_blt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false);
void double_bgt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false); void double_bgt(FloatRegister Rs1, FloatRegister Rs2, Label &l, bool is_far = false, bool is_unordered = false);
void push_reg(RegSet regs, Register stack) { if (regs.bits()) { push_reg(regs.bits(), stack); } } private:
void pop_reg(RegSet regs, Register stack) { if (regs.bits()) { pop_reg(regs.bits(), stack); } }
void push_reg(Register Rs);
void pop_reg(Register Rd);
int push_reg(unsigned int bitset, Register stack); int push_reg(unsigned int bitset, Register stack);
int pop_reg(unsigned int bitset, Register stack); int pop_reg(unsigned int bitset, Register stack);
int push_fp(unsigned int bitset, Register stack);
int pop_fp(unsigned int bitset, Register stack);
#ifdef COMPILER2
int push_v(unsigned int bitset, Register stack);
int pop_v(unsigned int bitset, Register stack);
#endif // COMPILER2
public:
void push_reg(Register Rs);
void pop_reg(Register Rd);
void push_reg(RegSet regs, Register stack) { if (regs.bits()) push_reg(regs.bits(), stack); }
void pop_reg(RegSet regs, Register stack) { if (regs.bits()) pop_reg(regs.bits(), stack); }
void push_fp(FloatRegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); } void push_fp(FloatRegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
void pop_fp(FloatRegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); } void pop_fp(FloatRegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
#ifdef COMPILER2 #ifdef COMPILER2
void push_vp(VectorRegSet regs, Register stack) { if (regs.bits()) push_vp(regs.bits(), stack); } void push_v(VectorRegSet regs, Register stack) { if (regs.bits()) push_v(regs.bits(), stack); }
void pop_vp(VectorRegSet regs, Register stack) { if (regs.bits()) pop_vp(regs.bits(), stack); } void pop_v(VectorRegSet regs, Register stack) { if (regs.bits()) pop_v(regs.bits(), stack); }
#endif // COMPILER2 #endif // COMPILER2
// Push and pop everything that might be clobbered by a native // Push and pop everything that might be clobbered by a native
@ -783,12 +792,6 @@ class MacroAssembler: public Assembler {
// if [src1 < src2], dst = -1; // if [src1 < src2], dst = -1;
void cmp_l2i(Register dst, Register src1, Register src2, Register tmp = t0); void cmp_l2i(Register dst, Register src1, Register src2, Register tmp = t0);
int push_fp(unsigned int bitset, Register stack);
int pop_fp(unsigned int bitset, Register stack);
int push_vp(unsigned int bitset, Register stack);
int pop_vp(unsigned int bitset, Register stack);
// vext // vext
void vmnot_m(VectorRegister vd, VectorRegister vs); void vmnot_m(VectorRegister vd, VectorRegister vs);
void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm = unmasked); void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm = unmasked);

View file

@ -599,7 +599,7 @@ class StubGenerator: public StubCodeGenerator {
Label exit, error; Label exit, error;
__ push_reg(0x3000, sp); // save c_rarg2 and c_rarg3 __ push_reg(RegSet::of(c_rarg2, c_rarg3), sp); // save c_rarg2 and c_rarg3
__ la(c_rarg2, ExternalAddress((address) StubRoutines::verify_oop_count_addr())); __ la(c_rarg2, ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
__ ld(c_rarg3, Address(c_rarg2)); __ ld(c_rarg3, Address(c_rarg2));
@ -635,12 +635,12 @@ class StubGenerator: public StubCodeGenerator {
// return if everything seems ok // return if everything seems ok
__ bind(exit); __ bind(exit);
__ pop_reg(0x3000, sp); // pop c_rarg2 and c_rarg3 __ pop_reg(RegSet::of(c_rarg2, c_rarg3), sp); // pop c_rarg2 and c_rarg3
__ ret(); __ ret();
// handle errors // handle errors
__ bind(error); __ bind(error);
__ pop_reg(0x3000, sp); // pop c_rarg2 and c_rarg3 __ pop_reg(RegSet::of(c_rarg2, c_rarg3), sp); // pop c_rarg2 and c_rarg3
__ push_reg(RegSet::range(x0, x31), sp); __ push_reg(RegSet::range(x0, x31), sp);
// debug(char* msg, int64_t pc, int64_t regs[]) // debug(char* msg, int64_t pc, int64_t regs[])