Skip to content

8278994: riscv: RVC support #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d1178a6
RVC: basic instruction set
zhengxiaolinX Nov 8, 2021
f68f2cb
Enable RVC instructions (based on the basic patch)
zhengxiaolinX Dec 23, 2021
4254d3e
Revise as proposed comments, including
zhengxiaolinX Dec 23, 2021
ce8866d
Cover most RVC instructions by using CompressibleRegion to cover mini…
zhengxiaolinX Dec 24, 2021
4ddf759
Update licenses to the new year
zhengxiaolinX Jan 4, 2022
f152578
Remove Alignment-related changes as discussions
zhengxiaolinX Jan 5, 2022
a74cbeb
Fix remaining CEXT -> RVC
zhengxiaolinX Jan 5, 2022
b2e3ac5
Remove COMPRESSIBLE & NOT_COMPRESSIBLE macros by adding one layer as …
zhengxiaolinX Jan 5, 2022
3a8adfa
Remove assembler_riscv_c.hpp as discussions
zhengxiaolinX Jan 5, 2022
654000f
Manually inline all macros into functions as discussions
zhengxiaolinX Jan 6, 2022
d915c7b
Remain an 'minimum_alignment' unchanged
zhengxiaolinX Jan 6, 2022
8daf01f
Remove remaining macros as discussions
zhengxiaolinX Jan 6, 2022
b9b3632
Rename misc functions and change the positions of some comments
zhengxiaolinX Jan 6, 2022
2069567
Move RVC code to the proper location after rebasing (#42)
zhengxiaolinX Jan 7, 2022
7accc38
Remove useless and polish comments
zhengxiaolinX Jan 7, 2022
807513d
Split c_ldsp and c_fldsp
zhengxiaolinX Jan 10, 2022
03b947f
Remove `nmethod_entry_barrier`-related things
zhengxiaolinX Jan 10, 2022
4d1abfc
Polish `nmethod_entry_barrier` and RISC-V CAS related comments
zhengxiaolinX Jan 10, 2022
e5d89f4
Polish comments: remove the 'RVC:' prefix
zhengxiaolinX Jan 13, 2022
3789930
Add an assertion for patchable jals' alignment
zhengxiaolinX Jan 15, 2022
502ff3d
Polish English comments as suggestions
zhengxiaolinX Jan 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/assembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void Assembler::zext_w(Register Rd, Register Rs) {
add_uw(Rd, Rs, zr);
}

void Assembler::li(Register Rd, int64_t imm) {
void Assembler::_li(Register Rd, int64_t imm) {
// int64_t is in range 0x8000 0000 0000 0000 ~ 0x7fff ffff ffff ffff
int shift = 12;
int64_t upper = imm, lower = imm;
Expand Down
1,117 changes: 1,060 additions & 57 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,11 @@ void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Op
}
}

void LIR_Assembler::align_call(LIR_Code code) { }
void LIR_Assembler::align_call(LIR_Code code) {
// With RVC a call instruction (which will be patched later) may get 2-byte aligned and could
// span multiple cache lines. See CallStaticJavaDirectNode::compute_padding() for more info.
__ align(4);
}

void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
address call = __ trampoline_call(Address(op->addr(), rtype));
Expand All @@ -1344,6 +1348,7 @@ void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {

void LIR_Assembler::emit_static_call_stub() {
address call_pc = __ pc();
assert((__ offset() % 4) == 0, "call sites must be properly aligned");
address stub = __ start_a_stub(call_stub_size());
if (stub == NULL) {
bailout("static call stub overflow");
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
return;
}

// RISCV's amoswap instructions require that the memory address must be naturally aligned.
__ align(4);

Label skip, guard;
Address thread_disarmed_addr(xthread, in_bytes(bs_nm->thread_disarmed_offset()));

Expand All @@ -256,6 +259,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {

__ bind(guard);

assert(__ offset() % 4 == 0, "bad alignment");
__ emit_int32(0); // nmethod guard value. Skipped over in common case.

__ bind(skip);
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/riscv/globals_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, AvoidUnalignedAccesses, true, \
"Avoid generating unaligned memory accesses") \
product(bool, UseRVV, false, EXPERIMENTAL, "Use RVV instructions") \
product(bool, UseRVB, false, EXPERIMENTAL, "Use RVB instructions")
product(bool, UseRVB, false, EXPERIMENTAL, "Use RVB instructions") \
product(bool, UseRVC, false, EXPERIMENTAL, "Use RVC instructions")

#endif // CPU_RISCV_GLOBALS_RISCV_HPP
27 changes: 23 additions & 4 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ static void pass_arg3(MacroAssembler* masm, Register arg) {
}
}

void MacroAssembler::align(int modulus) {
while (offset() % modulus != 0) { nop(); }
void MacroAssembler::align(int modulus, int extra_offset) {
CompressibleRegion cr(this);
while ((offset() + extra_offset) % modulus != 0) { nop(); }
}

void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) {
Expand Down Expand Up @@ -801,6 +802,7 @@ void MacroAssembler::la(Register Rd, Label &label) {

INSN(beq, feq, bnez);
INSN(bne, feq, beqz);

#undef INSN


Expand Down Expand Up @@ -960,6 +962,7 @@ int MacroAssembler::bitset_to_regs(unsigned int bitset, unsigned char* regs) {
// Return the number of words pushed
int MacroAssembler::push_reg(unsigned int bitset, Register stack) {
DEBUG_ONLY(int words_pushed = 0;)
CompressibleRegion cr(this);

unsigned char regs[32];
int count = bitset_to_regs(bitset, regs);
Expand All @@ -981,6 +984,7 @@ int MacroAssembler::push_reg(unsigned int bitset, Register stack) {

int MacroAssembler::pop_reg(unsigned int bitset, Register stack) {
DEBUG_ONLY(int words_popped = 0;)
CompressibleRegion cr(this);

unsigned char regs[32];
int count = bitset_to_regs(bitset, regs);
Expand All @@ -1003,6 +1007,7 @@ int MacroAssembler::pop_reg(unsigned int bitset, Register stack) {
// Push float registers in the bitset, except sp.
// Return the number of heapwords pushed.
int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this);
int words_pushed = 0;
unsigned char regs[32];
int count = bitset_to_regs(bitset, regs);
Expand All @@ -1022,6 +1027,7 @@ int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
}

int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this);
int words_popped = 0;
unsigned char regs[32];
int count = bitset_to_regs(bitset, regs);
Expand All @@ -1042,6 +1048,7 @@ int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {

#ifdef COMPILER2
int MacroAssembler::push_vp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this);
int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);

// Scan bitset to accumulate register pairs
Expand All @@ -1063,6 +1070,7 @@ int MacroAssembler::push_vp(unsigned int bitset, Register stack) {
}

int MacroAssembler::pop_vp(unsigned int bitset, Register stack) {
CompressibleRegion cr(this);
int vector_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);

// Scan bitset to accumulate register pairs
Expand All @@ -1085,6 +1093,7 @@ int MacroAssembler::pop_vp(unsigned int bitset, Register stack) {
#endif // COMPILER2

void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) {
CompressibleRegion cr(this);
// Push integer registers x7, x10-x17, x28-x31.
push_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp);

Expand All @@ -1099,6 +1108,7 @@ void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) {
}

void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
CompressibleRegion cr(this);
int offset = 0;
for (int i = 0; i < 32; i++) {
if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) {
Expand All @@ -1112,15 +1122,18 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {

// Push all the integer registers, except zr(x0) & sp(x2) & gp(x3) & tp(x4).
void MacroAssembler::pusha() {
CompressibleRegion cr(this);
push_reg(0xffffffe2, sp);
}

// Pop all the integer registers, except zr(x0) & sp(x2) & gp(x3) & tp(x4).
void MacroAssembler::popa() {
CompressibleRegion cr(this);
pop_reg(0xffffffe2, sp);
}

void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) {
CompressibleRegion cr(this);
// integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4)
push_reg(0xffffffe0, sp);

Expand All @@ -1142,6 +1155,7 @@ void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes)
}

void MacroAssembler::pop_CPU_state(bool restore_vectors, int vector_size_in_bytes) {
CompressibleRegion cr(this);
// vector registers
if (restore_vectors) {
vsetvli(t0, x0, Assembler::e64, Assembler::m8);
Expand Down Expand Up @@ -1308,7 +1322,10 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
int64_t imm = (intptr_t)target;
return patch_imm_in_li32(branch, (int32_t)imm);
} else {
tty->print_cr("pd_patch_instruction_size: instruction 0x%x could not be patched!\n", *(unsigned*)branch);
#ifdef ASSERT
tty->print_cr("pd_patch_instruction_size: instruction 0x%x at " INTPTR_FORMAT " could not be patched!\n", *(unsigned*)branch, p2i(branch));
Disassembler::decode(branch - 10, branch + 10);
#endif
ShouldNotReachHere();
}
return -1;
Expand Down Expand Up @@ -2917,7 +2934,8 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,

// make sure 4 byte aligned here, so that the destination address would be
// 8 byte aligned after 3 intructions
while (offset() % wordSize == 0) { nop(); }
// when we reach here we may get a 2-byte alignment so need to align it
align(wordSize, NativeCallTrampolineStub::data_offset);

relocate(trampoline_stub_Relocation::spec(code()->insts()->start() +
insts_call_instruction_offset));
Expand All @@ -2932,6 +2950,7 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,
bind(target);
assert(offset() - stub_start_offset == NativeCallTrampolineStub::data_offset,
"should be");
assert(offset() % wordSize == 0, "address loaded by ld must be 8-byte aligned under riscv64");
emit_int64((intptr_t)dest);

const address stub_start_addr = addr_at(stub_start_offset);
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class MacroAssembler: public Assembler {
void safepoint_ifence();

// Alignment
void align(int modulus);
void align(int modulus, int extra_offset = 0);

// Stack frame creation/removal
void enter() {
Expand Down Expand Up @@ -445,11 +445,11 @@ class MacroAssembler: public Assembler {
void fsflagsi(unsigned imm);

void beqz(Register Rs, const address &dest);
void bnez(Register Rs, const address &dest);
void blez(Register Rs, const address &dest);
void bgez(Register Rs, const address &dest);
void bltz(Register Rs, const address &dest);
void bgtz(Register Rs, const address &dest);
void bnez(Register Rs, const address &dest);
void la(Register Rd, Label &label);
void la(Register Rd, const address &dest);
void la(Register Rd, const Address &adr);
Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/cpu/riscv/nativeInst_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class NativeInstruction {
friend bool is_NativeCallTrampolineStub_at(address);
public:
enum {
instruction_size = 4
instruction_size = 4,
compressed_instruction_size = 2,
};

juint encoding() const {
Expand Down Expand Up @@ -422,10 +423,10 @@ inline NativeMovRegMem* nativeMovRegMem_at (address addr) {
class NativeJump: public NativeInstruction {
public:
enum RISCV64_specific_constants {
instruction_size = 4,
instruction_size = NativeInstruction::instruction_size,
instruction_offset = 0,
data_offset = 0,
next_instruction_offset = 4
next_instruction_offset = NativeInstruction::instruction_size
};

address instruction_address() const { return addr_at(instruction_offset); }
Expand Down
18 changes: 16 additions & 2 deletions src/hotspot/cpu/riscv/register_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ class RegisterImpl: public AbstractRegisterImpl {
enum {
number_of_registers = 32,
number_of_byte_registers = 32,
max_slots_per_register = 2
max_slots_per_register = 2,

// integer registers in the range of [x8~x15] correspond to RVC. Please see Table 16.2 in spec.
compressed_register_base = 8,
compressed_register_top = 15,
};

// derived registers, offsets, and addresses
Expand All @@ -71,10 +75,13 @@ class RegisterImpl: public AbstractRegisterImpl {

// accessors
int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; }
int compressed_encoding() const { assert(is_compressed_valid(), "invalid compressed register"); return ((intptr_t)this - compressed_register_base); }
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
bool is_compressed_valid() const { return compressed_register_base <= (intptr_t)this && (intptr_t)this <= compressed_register_top; }
bool has_byte_register() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; }
const char* name() const;
int encoding_nocheck() const { return (intptr_t)this; }
int compressed_encoding_nocheck() const { return ((intptr_t)this - compressed_register_base); }

// Return the bit which represents this register. This is intended
// to be ORed into a bitmask: for usage see class RegSet below.
Expand Down Expand Up @@ -131,7 +138,11 @@ class FloatRegisterImpl: public AbstractRegisterImpl {
public:
enum {
number_of_registers = 32,
max_slots_per_register = 2
max_slots_per_register = 2,

// float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec.
compressed_register_base = 8,
compressed_register_top = 15,
};

// construction
Expand All @@ -144,8 +155,11 @@ class FloatRegisterImpl: public AbstractRegisterImpl {

// accessors
int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; }
int compressed_encoding() const { assert(is_compressed_valid(), "invalid compressed register"); return ((intptr_t)this - compressed_register_base); }
int encoding_nocheck() const { return (intptr_t)this; }
int compressed_encoding_nocheck() const { return ((intptr_t)this - compressed_register_base); }
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
bool is_compressed_valid() const { return compressed_register_base <= (intptr_t)this && (intptr_t)this <= compressed_register_top; }
const char* name() const;

};
Expand Down
Loading