Skip to content

Commit

Permalink
JALR
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Mar 20, 2024
1 parent eebcc21 commit ac8a72b
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 256 deletions.
185 changes: 90 additions & 95 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 <uint8_t InstructionType, uint8_t FunctionType>
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);
Expand All @@ -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) { \
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
12 changes: 1 addition & 11 deletions src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 1 addition & 3 deletions src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading

0 comments on commit ac8a72b

Please sign in to comment.