Skip to content

Commit c3bc23f

Browse files
committedMay 22, 2024
8326306: RISC-V: Re-structure MASM calls and jumps
Reviewed-by: fyang, luhenry
1 parent 8a9d77d commit c3bc23f

9 files changed

+257
-256
lines changed
 

‎src/hotspot/cpu/riscv/assembler_riscv.hpp

+93-95
Original file line numberDiff line numberDiff line change
@@ -656,39 +656,35 @@ class Assembler : public AbstractAssembler {
656656

657657
#undef INSN
658658

659-
#define INSN(NAME, op) \
660-
void NAME(Register Rd, const int32_t offset) { \
661-
guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid."); \
662-
unsigned insn = 0; \
663-
patch((address)&insn, 6, 0, op); \
664-
patch_reg((address)&insn, 7, Rd); \
665-
patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff)); \
666-
patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1)); \
667-
patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff)); \
668-
patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1)); \
669-
emit(insn); \
659+
private:
660+
// All calls and jumps must go via MASM.
661+
// Format J-type
662+
void _jal(Register Rd, const int32_t offset) {
663+
guarantee(is_simm21(offset) && ((offset % 2) == 0), "offset is invalid.");
664+
unsigned insn = 0;
665+
patch((address)&insn, 6, 0, 0b1101111);
666+
patch_reg((address)&insn, 7, Rd);
667+
patch((address)&insn, 19, 12, (uint32_t)((offset >> 12) & 0xff));
668+
patch((address)&insn, 20, (uint32_t)((offset >> 11) & 0x1));
669+
patch((address)&insn, 30, 21, (uint32_t)((offset >> 1) & 0x3ff));
670+
patch((address)&insn, 31, (uint32_t)((offset >> 20) & 0x1));
671+
emit(insn);
670672
}
671673

672-
INSN(jal, 0b1101111);
673-
674-
#undef INSN
675-
676-
#define INSN(NAME, op, funct) \
677-
void NAME(Register Rd, Register Rs, const int32_t offset) { \
678-
guarantee(is_simm12(offset), "offset is invalid."); \
679-
unsigned insn = 0; \
680-
patch((address)&insn, 6, 0, op); \
681-
patch_reg((address)&insn, 7, Rd); \
682-
patch((address)&insn, 14, 12, funct); \
683-
patch_reg((address)&insn, 15, Rs); \
684-
int32_t val = offset & 0xfff; \
685-
patch((address)&insn, 31, 20, val); \
686-
emit(insn); \
674+
// Format I-type
675+
void _jalr(Register Rd, Register Rs, const int32_t offset) {
676+
guarantee(is_simm12(offset), "offset is invalid.");
677+
unsigned insn = 0;
678+
patch((address)&insn, 6, 0, 0b1100111);
679+
patch_reg((address)&insn, 7, Rd);
680+
patch((address)&insn, 14, 12, 0b000);
681+
patch_reg((address)&insn, 15, Rs);
682+
int32_t val = offset & 0xfff;
683+
patch((address)&insn, 31, 20, val);
684+
emit(insn);
687685
}
688686

689-
INSN(_jalr, 0b1100111, 0b000);
690-
691-
#undef INSN
687+
public:
692688

693689
enum barrier {
694690
i = 0b1000, o = 0b0100, r = 0b0010, w = 0b0001,
@@ -2294,21 +2290,23 @@ enum Nf {
22942290

22952291
#undef INSN
22962292

2297-
#define INSN(NAME, funct4, op) \
2298-
void NAME(Register Rs1) { \
2299-
assert_cond(Rs1 != x0); \
2300-
uint16_t insn = 0; \
2301-
c_patch((address)&insn, 1, 0, op); \
2302-
c_patch_reg((address)&insn, 2, x0); \
2303-
c_patch_reg((address)&insn, 7, Rs1); \
2304-
c_patch((address)&insn, 15, 12, funct4); \
2305-
emit_int16(insn); \
2293+
private:
2294+
// All calls and jumps must go via MASM.
2295+
// Format CR, c.jr/c.jalr
2296+
// Note C instruction can't be changed, i.e. relocation patching.
2297+
template <uint8_t InstructionType, uint8_t FunctionType>
2298+
void c_cr_if(Register Rs1) {
2299+
assert_cond(Rs1 != x0);
2300+
uint16_t insn = 0;
2301+
c_patch((address)&insn, 1, 0, FunctionType);
2302+
c_patch_reg((address)&insn, 2, x0);
2303+
c_patch_reg((address)&insn, 7, Rs1);
2304+
c_patch((address)&insn, 15, 12, InstructionType);
2305+
emit_int16(insn);
23062306
}
23072307

2308-
INSN(c_jr, 0b1000, 0b10);
2309-
INSN(c_jalr, 0b1001, 0b10);
2310-
2311-
#undef INSN
2308+
void c_jr(Register Rs1) { c_cr_if<0b1000, 0b10>(Rs1); }
2309+
void c_jalr(Register Rs1) { c_cr_if<0b1001, 0b10>(Rs1); }
23122310

23132311
typedef void (Assembler::* j_c_insn)(address dest);
23142312
typedef void (Assembler::* compare_and_branch_c_insn)(Register Rs1, address dest);
@@ -2331,35 +2329,36 @@ enum Nf {
23312329
}
23322330
}
23332331

2334-
#define INSN(NAME, funct3, op) \
2335-
void NAME(int32_t offset) { \
2336-
assert(is_simm12(offset) && ((offset % 2) == 0), "invalid encoding"); \
2337-
uint16_t insn = 0; \
2338-
c_patch((address)&insn, 1, 0, op); \
2339-
c_patch((address)&insn, 2, 2, (offset & nth_bit(5)) >> 5); \
2340-
c_patch((address)&insn, 5, 3, (offset & right_n_bits(4)) >> 1); \
2341-
c_patch((address)&insn, 6, 6, (offset & nth_bit(7)) >> 7); \
2342-
c_patch((address)&insn, 7, 7, (offset & nth_bit(6)) >> 6); \
2343-
c_patch((address)&insn, 8, 8, (offset & nth_bit(10)) >> 10); \
2344-
c_patch((address)&insn, 10, 9, (offset & right_n_bits(10)) >> 8); \
2345-
c_patch((address)&insn, 11, 11, (offset & nth_bit(4)) >> 4); \
2346-
c_patch((address)&insn, 12, 12, (offset & nth_bit(11)) >> 11); \
2347-
c_patch((address)&insn, 15, 13, funct3); \
2348-
emit_int16(insn); \
2349-
} \
2350-
void NAME(address dest) { \
2351-
assert_cond(dest != nullptr); \
2352-
int64_t distance = dest - pc(); \
2353-
assert(is_simm12(distance) && ((distance % 2) == 0), "invalid encoding"); \
2354-
c_j(distance); \
2355-
} \
2356-
void NAME(Label &L) { \
2357-
wrap_label(L, &Assembler::NAME); \
2332+
// Format CJ, c.j (c.jal)
2333+
// Note C instruction can't be changed, i.e. relocation patching.
2334+
void c_j(int32_t offset) {
2335+
assert(is_simm12(offset) && ((offset % 2) == 0), "invalid encoding");
2336+
uint16_t insn = 0;
2337+
c_patch((address)&insn, 1, 0, 0b01);
2338+
c_patch((address)&insn, 2, 2, (offset & nth_bit(5)) >> 5);
2339+
c_patch((address)&insn, 5, 3, (offset & right_n_bits(4)) >> 1);
2340+
c_patch((address)&insn, 6, 6, (offset & nth_bit(7)) >> 7);
2341+
c_patch((address)&insn, 7, 7, (offset & nth_bit(6)) >> 6);
2342+
c_patch((address)&insn, 8, 8, (offset & nth_bit(10)) >> 10);
2343+
c_patch((address)&insn, 10, 9, (offset & right_n_bits(10)) >> 8);
2344+
c_patch((address)&insn, 11, 11, (offset & nth_bit(4)) >> 4);
2345+
c_patch((address)&insn, 12, 12, (offset & nth_bit(11)) >> 11);
2346+
c_patch((address)&insn, 15, 13, 0b101);
2347+
emit_int16(insn);
23582348
}
23592349

2360-
INSN(c_j, 0b101, 0b01);
2350+
void c_j(address dest) {
2351+
assert_cond(dest != nullptr);
2352+
int64_t distance = dest - pc();
2353+
assert(is_simm12(distance) && ((distance % 2) == 0), "invalid encoding");
2354+
c_j(distance);
2355+
}
23612356

2362-
#undef INSN
2357+
void c_j(Label &L) {
2358+
wrap_label(L, &Assembler::c_j);
2359+
}
2360+
2361+
public:
23632362

23642363
#define INSN(NAME, funct3, op) \
23652364
void NAME(Register Rs1, int32_t imm) { \
@@ -2812,24 +2811,35 @@ enum Nf {
28122811
// --------------------------
28132812
// Unconditional branch instructions
28142813
// --------------------------
2815-
#define INSN(NAME) \
2816-
void NAME(Register Rd, Register Rs, const int32_t offset) { \
2817-
/* jalr -> c.jr/c.jalr */ \
2818-
if (do_compress() && (offset == 0 && Rs != x0)) { \
2819-
if (Rd == x1) { \
2820-
c_jalr(Rs); \
2821-
return; \
2822-
} else if (Rd == x0) { \
2823-
c_jr(Rs); \
2824-
return; \
2825-
} \
2826-
} \
2827-
_jalr(Rd, Rs, offset); \
2814+
protected:
2815+
// All calls and jumps must go via MASM.
2816+
void jalr(Register Rd, Register Rs, const int32_t offset) {
2817+
/* jalr -> c.jr/c.jalr */
2818+
if (do_compress() && (offset == 0 && Rs != x0)) {
2819+
if (Rd == x1) {
2820+
c_jalr(Rs);
2821+
return;
2822+
} else if (Rd == x0) {
2823+
c_jr(Rs);
2824+
return;
2825+
}
2826+
}
2827+
_jalr(Rd, Rs, offset);
28282828
}
28292829

2830-
INSN(jalr);
2830+
void jal(Register Rd, const int32_t offset) {
2831+
/* jal -> c.j, note c.jal is RV32C only */
2832+
if (do_compress() &&
2833+
Rd == x0 &&
2834+
is_simm12(offset) && ((offset % 2) == 0)) {
2835+
c_j(offset);
2836+
return;
2837+
}
28312838

2832-
#undef INSN
2839+
_jal(Rd, offset);
2840+
}
2841+
2842+
public:
28332843

28342844
// --------------------------
28352845
// Miscellaneous Instructions
@@ -3009,18 +3019,6 @@ enum Nf {
30093019

30103020
#undef INSN
30113021

3012-
// ---------------------------------------------------------------------------------------
3013-
3014-
#define INSN(NAME, REGISTER) \
3015-
void NAME(Register Rs) { \
3016-
jalr(REGISTER, Rs, 0); \
3017-
}
3018-
3019-
INSN(jr, x0);
3020-
INSN(jalr, x1);
3021-
3022-
#undef INSN
3023-
30243022
// -------------- ZCB Instruction Definitions --------------
30253023
// Zcb additional C instructions
30263024
private:

‎src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

+1-11
Original file line numberDiff line numberDiff line change
@@ -1841,17 +1841,7 @@ void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, C
18411841
void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
18421842
assert(!tmp->is_valid(), "don't need temporary");
18431843

1844-
CodeBlob *cb = CodeCache::find_blob(dest);
1845-
if (cb != nullptr) {
1846-
__ far_call(RuntimeAddress(dest));
1847-
} else {
1848-
RuntimeAddress target(dest);
1849-
__ relocate(target.rspec(), [&] {
1850-
int32_t offset;
1851-
__ movptr(t0, target.target(), offset);
1852-
__ jalr(x1, t0, offset);
1853-
});
1854-
}
1844+
__ rt_call(dest);
18551845

18561846
if (info != nullptr) {
18571847
add_call_info_here(info);

‎src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
300300
assert(!is_narrow, "phantom access cannot be narrow");
301301
target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak);
302302
}
303-
__ call(target);
303+
__ rt_call(target);
304304
__ mv(t0, x10);
305305
__ pop_call_clobbered_registers();
306306
__ mv(x10, t0);
@@ -703,7 +703,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s
703703
assert(is_native, "phantom must only be called off-heap");
704704
target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom);
705705
}
706-
__ call(target);
706+
__ rt_call(target);
707707
__ mv(t0, x10);
708708
__ pop_call_clobbered_registers();
709709
__ mv(x10, t0);

‎src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
177177
__ relocate(target.rspec(), [&] {
178178
int32_t offset;
179179
__ la(t0, target.target(), offset);
180-
__ jalr(x1, t0, offset);
180+
__ jalr(t0, offset);
181181
});
182182
__ leave();
183183
__ ret();

0 commit comments

Comments
 (0)
Please sign in to comment.