diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index bc8c9f1cd7f2e..6d4c264b7ede6 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -656,39 +656,34 @@ class Assembler : public AbstractAssembler { #undef INSN -#define INSN(NAME, op) \ - void NAME(Register Rd, const int32_t offset) { \ - guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid."); \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch_reg((address)&insn, 7, Rd); \ - patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff)); \ - patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1)); \ - patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff)); \ - patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1)); \ - emit(insn); \ + private: + // Format J-type + void _jal(Register Rd, const int32_t offset) { + guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid."); + unsigned insn = 0; + patch((address)&insn, 6, 0, 0b1101111); + patch_reg((address)&insn, 7, Rd); + patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff)); + patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1)); + patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff)); + patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1)); + emit(insn); } - INSN(jal, 0b1101111); - -#undef INSN - -#define INSN(NAME, op, funct) \ - void NAME(Register Rd, Register Rs, const int32_t offset) { \ - guarantee(is_simm12(offset), "offset is invalid."); \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch_reg((address)&insn, 7, Rd); \ - patch((address)&insn, 14, 12, funct); \ - patch_reg((address)&insn, 15, Rs); \ - int32_t val = offset & 0xfff; \ - patch((address)&insn, 31, 20, val); \ - emit(insn); \ + // Format I-type + void _jalr(Register Rd, Register Rs, const int32_t offset) { + guarantee(is_simm12(offset), "offset is invalid."); + unsigned insn = 0; + patch((address)&insn, 6, 0, 0b1100111); + patch_reg((address)&insn, 7, Rd); + patch((address)&insn, 14, 12, 0b000); + patch_reg((address)&insn, 15, Rs); + int32_t val = offset & 0xfff; + patch((address)&insn, 31, 20, val); + emit(insn); } - INSN(_jalr, 0b1100111, 0b000); - -#undef INSN + public: enum barrier { i = 0b1000, o = 0b0100, r = 0b0010, w = 0b0001, @@ -2286,21 +2281,22 @@ enum Nf { #undef INSN -#define INSN(NAME, funct4, op) \ - void NAME(Register Rs1) { \ - assert_cond(Rs1 != x0); \ - uint16_t insn = 0; \ - c_patch((address)&insn, 1, 0, op); \ - c_patch_reg((address)&insn, 2, x0); \ - c_patch_reg((address)&insn, 7, Rs1); \ - c_patch((address)&insn, 15, 12, funct4); \ - emit_int16(insn); \ + private: + // Format CR, c.jr/c.jalr + // Note C instruction can't be changed, i.e. relocation patching. + template + void c_cr_if(Register Rs1) { + assert_cond(Rs1 != x0); + uint16_t insn = 0; + c_patch((address)&insn, 1, 0, FunctionType); + c_patch_reg((address)&insn, 2, x0); + c_patch_reg((address)&insn, 7, Rs1); + c_patch((address)&insn, 15, 12, InstructionType); + emit_int16(insn); } - INSN(c_jr, 0b1000, 0b10); - INSN(c_jalr, 0b1001, 0b10); - -#undef INSN + void c_jr(Register Rs1) { c_cr_if<0b1000, 0b10>(Rs1); } + void c_jalr(Register Rs1) { c_cr_if<0b1001, 0b10>(Rs1); } typedef void (Assembler::* j_c_insn)(address dest); typedef void (Assembler::* compare_and_branch_c_insn)(Register Rs1, address dest); @@ -2323,35 +2319,36 @@ enum Nf { } } -#define INSN(NAME, funct3, op) \ - void NAME(int32_t offset) { \ - assert(is_simm12(offset) && ((offset % 2) == 0), "invalid encoding"); \ - uint16_t insn = 0; \ - c_patch((address)&insn, 1, 0, op); \ - c_patch((address)&insn, 2, 2, (offset & nth_bit(5)) >> 5); \ - c_patch((address)&insn, 5, 3, (offset & right_n_bits(4)) >> 1); \ - c_patch((address)&insn, 6, 6, (offset & nth_bit(7)) >> 7); \ - c_patch((address)&insn, 7, 7, (offset & nth_bit(6)) >> 6); \ - c_patch((address)&insn, 8, 8, (offset & nth_bit(10)) >> 10); \ - c_patch((address)&insn, 10, 9, (offset & right_n_bits(10)) >> 8); \ - c_patch((address)&insn, 11, 11, (offset & nth_bit(4)) >> 4); \ - c_patch((address)&insn, 12, 12, (offset & nth_bit(11)) >> 11); \ - c_patch((address)&insn, 15, 13, funct3); \ - emit_int16(insn); \ - } \ - void NAME(address dest) { \ - assert_cond(dest != nullptr); \ - int64_t distance = dest - pc(); \ - assert(is_simm12(distance) && ((distance % 2) == 0), "invalid encoding"); \ - c_j(distance); \ - } \ - void NAME(Label &L) { \ - wrap_label(L, &Assembler::NAME); \ + // Format CJ, c.j (c.jal) + // Note C instruction can't be changed, i.e. relocation patching. + void c_j(int32_t offset) { + assert(is_simm12(offset) && ((offset % 2) == 0), "invalid encoding"); + uint16_t insn = 0; + c_patch((address)&insn, 1, 0, 0b01); + c_patch((address)&insn, 2, 2, (offset & nth_bit(5)) >> 5); + c_patch((address)&insn, 5, 3, (offset & right_n_bits(4)) >> 1); + c_patch((address)&insn, 6, 6, (offset & nth_bit(7)) >> 7); + c_patch((address)&insn, 7, 7, (offset & nth_bit(6)) >> 6); + c_patch((address)&insn, 8, 8, (offset & nth_bit(10)) >> 10); + c_patch((address)&insn, 10, 9, (offset & right_n_bits(10)) >> 8); + c_patch((address)&insn, 11, 11, (offset & nth_bit(4)) >> 4); + c_patch((address)&insn, 12, 12, (offset & nth_bit(11)) >> 11); + c_patch((address)&insn, 15, 13, 0b101); + emit_int16(insn); } - INSN(c_j, 0b101, 0b01); + void c_j(address dest) { + assert_cond(dest != nullptr); + int64_t distance = dest - pc(); + assert(is_simm12(distance) && ((distance % 2) == 0), "invalid encoding"); + c_j(distance); + } -#undef INSN + void c_j(Label &L) { + wrap_label(L, &Assembler::c_j); + } + + public: #define INSN(NAME, funct3, op) \ void NAME(Register Rs1, int32_t imm) { \ @@ -2804,24 +2801,34 @@ enum Nf { // -------------------------- // Unconditional branch instructions // -------------------------- -#define INSN(NAME) \ - void NAME(Register Rd, Register Rs, const int32_t offset) { \ - /* jalr -> c.jr/c.jalr */ \ - if (do_compress() && (offset == 0 && Rs != x0)) { \ - if (Rd == x1) { \ - c_jalr(Rs); \ - return; \ - } else if (Rd == x0) { \ - c_jr(Rs); \ - return; \ - } \ - } \ - _jalr(Rd, Rs, offset); \ + protected: + void jalr(Register Rd, Register Rs, const int32_t offset) { + /* jalr -> c.jr/c.jalr */ + if (do_compress() && (offset == 0 && Rs != x0)) { + if (Rd == x1) { + c_jalr(Rs); + return; + } else if (Rd == x0) { + c_jr(Rs); + return; + } + } + _jalr(Rd, Rs, offset); } - INSN(jalr); + void jal(Register Rd, const int32_t offset) { + /* jalr -> c.jr/c.jalr */ + if (do_compress() && + Rd == x0 && + is_simm12(offset) && ((offset % 2) == 0)) { + c_j(offset); + return; + } -#undef INSN + _jal(Rd, offset); + } + + public: // -------------------------- // Miscellaneous Instructions @@ -3001,18 +3008,6 @@ enum Nf { #undef INSN -// --------------------------------------------------------------------------------------- - -#define INSN(NAME, REGISTER) \ - void NAME(Register Rs) { \ - jalr(REGISTER, Rs, 0); \ - } - - INSN(jr, x0); - INSN(jalr, x1); - -#undef INSN - // -------------- ZCB Instruction Definitions -------------- // Zcb additional C instructions private: diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index 5d0fa3fad3cec..a15405f532302 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -1841,17 +1841,7 @@ void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, C void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { assert(!tmp->is_valid(), "don't need temporary"); - CodeBlob *cb = CodeCache::find_blob(dest); - if (cb != nullptr) { - __ far_call(RuntimeAddress(dest)); - } else { - RuntimeAddress target(dest); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ movptr(t0, target.target(), offset); - __ jalr(x1, t0, offset); - }); - } + __ rt_call(dest); if (info != nullptr) { add_call_info_here(info); diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index 26d60441c2d2c..a93bf5394ce94 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -300,7 +300,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, assert(!is_narrow, "phantom access cannot be narrow"); target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); } - __ call(target); + __ rt_call(target); __ mv(t0, x10); __ pop_call_clobbered_registers(); __ mv(x10, t0); @@ -703,7 +703,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s assert(is_native, "phantom must only be called off-heap"); target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom); } - __ call(target); + __ rt_call(target); __ mv(t0, x10); __ pop_call_clobbered_registers(); __ mv(x10, t0); diff --git a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp index fd1701c8188b8..a49c7d02e8e01 100644 --- a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp @@ -175,9 +175,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { __ enter(); ExternalAddress target(slow_case_addr); __ relocate(target.rspec(), [&] { - int32_t offset; - __ la(t0, target.target(), offset); - __ jalr(x1, t0, offset); + __ call(target.target()); }); __ leave(); __ ret(); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 4459356d3b132..039a6265fc498 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -343,7 +343,7 @@ void MacroAssembler::call_VM_base(Register oop_result, relocate(target.rspec(), [&] { int32_t offset; la(t0, target.target(), offset); - jalr(x0, t0, offset); + Assembler::jalr(x0, t0, offset); }); bind(ok); } @@ -645,14 +645,16 @@ void MacroAssembler::emit_static_call_stub() { // Jump to the entry point of the c2i stub. int32_t offset = 0; movptr(t0, 0, offset); - jalr(x0, t0, offset); + Assembler::jalr(x0, t0, offset); } void MacroAssembler::call_VM_leaf_base(address entry_point, int number_of_arguments, Label *retaddr) { + int32_t offset = 0; push_reg(RegSet::of(t0, xmethod), sp); // push << t0 & xmethod >> to sp - call(entry_point); + movptr(t0, entry_point, offset); + Assembler::jalr(x1, t0, offset); if (retaddr != nullptr) { bind(*retaddr); } @@ -720,30 +722,14 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg } void MacroAssembler::la(Register Rd, const address addr) { - int64_t offset = addr - pc(); - if (is_simm32(offset)) { - auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit - addi(Rd, Rd, ((int64_t)offset << 52) >> 52); - } else { - movptr(Rd, addr); - } + int32_t offset; + la(Rd, addr, offset); + addi(Rd, Rd, offset); } void MacroAssembler::la(Register Rd, const address addr, int32_t &offset) { - assert((uintptr_t)addr < (1ull << 48), "bad address"); - - unsigned long target_address = (uintptr_t)addr; - unsigned long low_address = (uintptr_t)CodeCache::low_bound(); - unsigned long high_address = (uintptr_t)CodeCache::high_bound(); - long offset_low = target_address - low_address; - long offset_high = target_address - high_address; - - // RISC-V doesn't compute a page-aligned address, in order to partially - // compensate for the use of *signed* offsets in its base+disp12 - // addressing mode (RISC-V's PC-relative reach remains asymmetric - // [-(2G + 2K), 2G - 2K). - if (offset_high >= -((1L << 31) + (1L << 11)) && offset_low < (1L << 31) - (1L << 11)) { - int64_t distance = addr - pc(); + int64_t distance = addr - pc(); + if (is_simm32(distance)) { auipc(Rd, (int32_t)distance + 0x800); offset = ((int32_t)distance << 20) >> 20; } else { @@ -863,88 +849,114 @@ void MacroAssembler::li(Register Rd, int64_t imm) { } } -#define INSN(NAME, REGISTER) \ - void MacroAssembler::NAME(const address dest, Register temp) { \ - assert_cond(dest != nullptr); \ - int64_t distance = dest - pc(); \ - if (is_simm21(distance) && ((distance % 2) == 0)) { \ - Assembler::jal(REGISTER, distance); \ - } else { \ - assert(temp != noreg, "expecting a register"); \ - int32_t offset = 0; \ - movptr(temp, dest, offset); \ - Assembler::jalr(REGISTER, temp, offset); \ - } \ - } \ - - INSN(j, x0); - INSN(jal, x1); - -#undef INSN +void MacroAssembler::jump_link(const address dest, Register temp) { + assert_cond(dest != nullptr); + int64_t distance = dest - pc(); + if (is_simm21(distance) && ((distance % 2) == 0)) { + Assembler::jal(x1, distance); + } else { + assert(temp != noreg && temp != x0, "expecting a register"); + int32_t offset = 0; + movptr(temp, dest, offset); + Assembler::jalr(x1, temp, offset); + } +} -#define INSN(NAME, REGISTER) \ - void MacroAssembler::NAME(const Address &adr, Register temp) { \ - switch (adr.getMode()) { \ - case Address::literal: { \ - relocate(adr.rspec(), [&] { \ - NAME(adr.target(), temp); \ - }); \ - break; \ - } \ - case Address::base_plus_offset: { \ - int32_t offset = ((int32_t)adr.offset() << 20) >> 20; \ - la(temp, Address(adr.base(), adr.offset() - offset)); \ - Assembler::jalr(REGISTER, temp, offset); \ - break; \ - } \ - default: \ - ShouldNotReachHere(); \ - } \ - } - - INSN(j, x0); - INSN(jal, x1); +void MacroAssembler::jump_link(const Address &adr, Register temp) { + switch (adr.getMode()) { + case Address::literal: { + relocate(adr.rspec(), [&] { + jump_link(adr.target(), temp); + }); + break; + } + case Address::base_plus_offset: { + int32_t offset = ((int32_t)adr.offset() << 20) >> 20; + la(temp, Address(adr.base(), adr.offset() - offset)); + Assembler::jalr(x1, temp, offset); + break; + } + default: + ShouldNotReachHere(); + } +} -#undef INSN +void MacroAssembler::j(const address dest, Register temp) { + assert(CodeCache::contains(dest), "Must be"); + assert_cond(dest != nullptr); + int64_t distance = dest - pc(); -#define INSN(NAME) \ - void MacroAssembler::NAME(Register Rd, const address dest, Register temp) { \ - assert_cond(dest != nullptr); \ - int64_t distance = dest - pc(); \ - if (is_simm21(distance) && ((distance % 2) == 0)) { \ - Assembler::NAME(Rd, distance); \ - } else { \ - assert_different_registers(Rd, temp); \ - int32_t offset = 0; \ - movptr(temp, dest, offset); \ - jalr(Rd, temp, offset); \ - } \ - } \ - void MacroAssembler::NAME(Register Rd, Label &L, Register temp) { \ - assert_different_registers(Rd, temp); \ - wrap_label(Rd, L, temp, &MacroAssembler::NAME); \ + // We can't patch C, i.e. if Label wasn't bound we need to patch this jump. + IncompressibleRegion ir(this); + if (is_simm21(distance) && ((distance % 2) == 0)) { + Assembler::jal(x0, distance); + } else { + assert(temp != noreg && temp != x0, "expecting a register"); + int32_t offset = 0; + la(temp, dest, offset); + Assembler::jalr(x0, temp, offset); } +} - INSN(jal); +void MacroAssembler::j(const Address &adr, Register temp) { + switch (adr.getMode()) { + case Address::literal: { + relocate(adr.rspec(), [&] { + j(adr.target(), temp); + }); + break; + } + case Address::base_plus_offset: { + // TODO: This case 'never' happens, as is for now. + int32_t offset = ((int32_t)adr.offset() << 20) >> 20; + la(temp, Address(adr.base(), adr.offset() - offset)); + Assembler::jalr(x0, temp, offset); + break; + } + default: + ShouldNotReachHere(); + } +} -#undef INSN +void MacroAssembler::j(Label &lab, Register temp) { + assert_different_registers(x0, temp); + if (lab.is_bound()) { + MacroAssembler::j(target(lab), temp); + } else { + lab.add_patch_at(code(), locator()); + MacroAssembler::j(pc(), temp); + } +} -#define INSN(NAME, REGISTER) \ - void MacroAssembler::NAME(Label &l, Register temp) { \ - jal(REGISTER, l, temp); \ - } \ +void MacroAssembler::jr(Register Rd, int32_t offset) { + assert(Rd != noreg, "expecting a register"); + Assembler::jalr(x0, Rd, offset); +} - INSN(j, x0); - INSN(jal, x1); +void MacroAssembler::call(const address dest, Register temp) { + assert_cond(dest != nullptr); + assert(temp != noreg, "expecting a register"); + int32_t offset = 0; + la(temp, dest, offset); + Assembler::jalr(x1, temp, offset); +} -#undef INSN +void MacroAssembler::jalr(Register Rd, int32_t offset) { + assert(Rd != noreg, "expecting a register"); + Assembler::jalr(x1, Rd, offset); +} -void MacroAssembler::wrap_label(Register Rt, Label &L, Register tmp, load_insn_by_temp insn) { - if (L.is_bound()) { - (this->*insn)(Rt, target(L), tmp); +void MacroAssembler::rt_call(address dest, Register tmp) { + CodeBlob *cb = CodeCache::find_blob(dest); + RuntimeAddress target(dest); + if (cb) { + far_call(target, tmp); } else { - L.add_patch_at(code(), locator()); - (this->*insn)(Rt, pc(), tmp); + relocate(target.rspec(), [&] { + int32_t offset; + movptr(tmp, target.target(), offset); + Assembler::jalr(x1, tmp, offset); + }); } } @@ -3160,7 +3172,6 @@ void MacroAssembler::atomic_cas( } void MacroAssembler::far_jump(const Address &entry, Register tmp) { - assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type @@ -3170,12 +3181,11 @@ void MacroAssembler::far_jump(const Address &entry, Register tmp) { relocate(entry.rspec(), [&] { int32_t offset; la(tmp, entry.target(), offset); - jalr(x0, tmp, offset); + Assembler::jalr(x0, tmp, offset); }); } void MacroAssembler::far_call(const Address &entry, Register tmp) { - assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type @@ -3187,7 +3197,7 @@ void MacroAssembler::far_call(const Address &entry, Register tmp) { relocate(entry.rspec(), [&] { int32_t offset; la(tmp, entry.target(), offset); - jalr(x1, tmp, offset); // link + Assembler::jalr(x1, tmp, offset); // link }); } @@ -3447,7 +3457,7 @@ void MacroAssembler::reserved_stack_check() { relocate(target.rspec(), [&] { int32_t offset; movptr(t0, target.target(), offset); - jalr(x0, t0, offset); + Assembler::jalr(x0, t0, offset); }); should_not_reach_here(); @@ -3529,7 +3539,7 @@ address MacroAssembler::trampoline_call(Address entry) { } #endif relocate(entry.rspec(), [&] { - jal(target); + jump_link(target, t0); }); postcond(pc() != badAddress); @@ -4368,7 +4378,7 @@ address MacroAssembler::zero_words(Register ptr, Register cnt) { return nullptr; } } else { - jal(zero_blocks); + jump_link(zero_blocks, t0); } } bind(around); @@ -5013,20 +5023,6 @@ void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) { } } -void MacroAssembler::rt_call(address dest, Register tmp) { - CodeBlob *cb = CodeCache::find_blob(dest); - RuntimeAddress target(dest); - if (cb) { - far_call(target, tmp); - } else { - relocate(target.rspec(), [&] { - int32_t offset; - movptr(tmp, target.target(), offset); - jalr(x1, tmp, offset); - }); - } -} - void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) { assert(bit_pos < 64, "invalid bit range"); if (UseZbs) { diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 75c0f9ba30596..8f9c86a92f1bc 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -589,14 +589,26 @@ class MacroAssembler: public Assembler { void bltz(Register Rs, const address dest); void bgtz(Register Rs, const address dest); - void j(Label &l, Register temp = t0); + private: + void jump_link(const address dest, Register temp); + void jump_link(const Address &adr, Register temp); + public: + void j(const address dest, Register temp = t0); void j(const Address &adr, Register temp = t0); - void jal(Label &l, Register temp = t0); - void jal(const address dest, Register temp = t0); - void jal(const Address &adr, Register temp = t0); - void jal(Register Rd, Label &L, Register temp = t0); - void jal(Register Rd, const address dest, Register temp = t0); + void j(Label &l, Register temp = t0); + void jr(Register Rd, int32_t offset = 0); + + void call(const address dest, Register temp = t0); + void jalr(Register Rd, int32_t offset = 0); + + // Emit a runtime call. Only invalidates the tmp register which + // is used to keep the entry address for jalr/movptr. + void rt_call(address dest, Register tmp = t0); + + inline void ret() { + Assembler::jalr(x0, x1, 0); + } //label void beqz(Register Rs, Label &l, bool is_far = false); @@ -724,7 +736,6 @@ class MacroAssembler: public Assembler { typedef void (MacroAssembler::* jal_jalr_insn)(Register Rt, address dest); typedef void (MacroAssembler::* load_insn_by_temp)(Register Rt, address dest, Register temp); - void wrap_label(Register r, Label &L, Register t, load_insn_by_temp insn); void wrap_label(Register r, Label &L, jal_jalr_insn insn); void wrap_label(Register r1, Register r2, Label &L, compare_and_branch_insn insn, @@ -1465,21 +1476,6 @@ class MacroAssembler: public Assembler { VMRegPair dst, bool is_receiver, int* receiver_offset); - // Emit a runtime call. Only invalidates the tmp register which - // is used to keep the entry address for jalr/movptr. - void rt_call(address dest, Register tmp = t0); - - void call(const address dest, Register temp = t0) { - assert_cond(dest != nullptr); - assert(temp != noreg, "expecting a register"); - int32_t offset = 0; - mv(temp, dest, offset); - jalr(x1, temp, offset); - } - - inline void ret() { - jalr(x0, x1, 0); - } #ifdef ASSERT // Template short-hand support to clean-up after a failed call to trampoline diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp index c4048f66e0d3e..399de3a2805d2 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp @@ -400,7 +400,7 @@ void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { int32_t offset = 0; a.movptr(t0, entry, offset); // lui, addi, slli, addi, slli - a.jalr(x0, t0, offset); // jalr + a.jr(t0, offset); // jalr ICache::invalidate_range(code_pos, instruction_size); } @@ -410,7 +410,6 @@ void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) ShouldNotCallThis(); } - address NativeCallTrampolineStub::destination(nmethod *nm) const { return ptr_at(data_offset); } diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index df447abaa068a..7512655d45d23 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -634,7 +634,7 @@ class StubGenerator: public StubCodeGenerator { assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); #endif BLOCK_COMMENT("call MacroAssembler::debug"); - __ call(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)); + __ rt_call(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)); __ ebreak(); return start; @@ -5432,7 +5432,7 @@ static const int64_t right_3_bits = right_n_bits(3); } __ mv(c_rarg0, xthread); BLOCK_COMMENT("call runtime_entry"); - __ call(runtime_entry); + __ rt_call(runtime_entry); // Generate oop map OopMap* map = new OopMap(framesize, 0); diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index 860a7afb5e332..ab351ddb1c39f 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1203,7 +1203,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // hand. // __ mv(c_rarg0, xthread); - __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); + __ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); __ get_method(xmethod); __ reinit_heapbase(); __ bind(Continue); @@ -1252,7 +1252,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ push_call_clobbered_registers(); __ mv(c_rarg0, xthread); - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); + __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); __ pop_call_clobbered_registers(); __ bind(no_reguard); } @@ -1812,7 +1812,7 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) { // the tosca in-state for the given template. assert(Interpreter::trace_code(t->tos_in()) != nullptr, "entry must have been generated"); - __ jal(Interpreter::trace_code(t->tos_in())); + __ call(Interpreter::trace_code(t->tos_in())); __ reinit_heapbase(); }