Skip to content

Commit

Permalink
Draft
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Nov 26, 2024
1 parent 57d35f9 commit 15154e7
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 4 deletions.
32 changes: 32 additions & 0 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3107,6 +3107,38 @@ enum Nf {

#undef INSN

// -------------- Zicond Instruction Definitions --------------
// Zicond conditional operations extension
private:
enum CZERO_OP : unsigned int {
CZERO_NEZ = 0b111,
CZERO_EQZ = 0b101
};

template <CZERO_OP OP_VALUE>
void czero(Register Rd, Register Rs1, Register Rs2) {
assert_cond(UseZicond);
uint32_t insn = 0;
patch ((address)&insn, 6, 0, 0b0110011); // bits: 7, name: 0x33, attr: ['OP']
patch_reg((address)&insn, 7, Rd); // bits: 5, name: 'rd'
patch ((address)&insn, 14, 12, OP_VALUE); // bits: 3, name: 0x7, attr: ['CZERO.NEZ'] / 0x5, attr: ['CZERO.EQZ']}
patch_reg((address)&insn, 15, Rs1); // bits: 5, name: 'rs1', attr: ['value']
patch_reg((address)&insn, 20, Rs2); // bits: 5, name: 'rs2', attr: ['condition']
patch ((address)&insn, 31, 25, 0b0000111); // bits: 7, name: 0x7, attr: ['CZERO']
emit_int32(insn);
}

public:
// Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd.
void czero_eqz(Register rd, Register rs1_value, Register rs2_condition) {
czero<CZERO_EQZ>(rd, rs1_value, rs2_condition);
}

// Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd.
void czero_nez(Register rd, Register rs1_value, Register rs2_condition) {
czero<CZERO_NEZ>(rd, rs1_value, rs2_condition);
}

// -------------- ZCB Instruction Definitions --------------
// Zcb additional C instructions
private:
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
}
}

// Consider using cmov (Zicond)
void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type,
LIR_Opr cmp_opr1, LIR_Opr cmp_opr2) {
Label label;
Expand Down
46 changes: 42 additions & 4 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2003,10 +2003,48 @@ void C2_MacroAssembler::enc_cmpEqNe_imm0_branch(int cmpFlag, Register op1, Label
}

void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Register dst, Register src) {
Label L;
cmp_branch(cmpFlag ^ (1 << neg_cond_bits), op1, op2, L);
mv(dst, src);
bind(L);
bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask ? true : false;
int op_select = cmpFlag & (~unsigned_branch_mask);

switch (op_select) {
case BoolTest::eq:
cmov_eq(op1, op2, dst, src);
break;
case BoolTest::ne:
cmov_ne(op1, op2, dst, src);
break;
case BoolTest::le:
if (is_unsigned) {
cmov_leu(op1, op2, dst, src);
} else {
cmov_le(op1, op2, dst, src);
}
break;
case BoolTest::ge:
if (is_unsigned) {
cmov_geu(op1, op2, dst, src);
} else {
cmov_ge(op1, op2, dst, src);
}
break;
case BoolTest::lt:
if (is_unsigned) {
cmov_ltu(op1, op2, dst, src);
} else {
cmov_lt(op1, op2, dst, src);
}
break;
case BoolTest::gt:
if (is_unsigned) {
cmov_gtu(op1, op2, dst, src);
} else {
cmov_gt(op1, op2, dst, src);
}
break;
default:
assert(false, "unsupported compare condition");
ShouldNotReachHere();
}
}

// Set dst to NaN if any NaN input.
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/cpu/riscv/globals_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \
product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \
product(bool, UseZicboz, false, EXPERIMENTAL, "Use Zicboz instructions") \
product(bool, UseZicond, false, DIAGNOSTIC, "Use Zicond instructions") \
product(bool, UseZihintpause, false, EXPERIMENTAL, \
"Use Zihintpause instructions") \
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
Expand Down
141 changes: 141 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,147 @@ void MacroAssembler::wrap_label(Register r1, Register r2, Label &L,

#undef INSN

// cmov
void MacroAssembler::cmov_eq(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
xorr(t0, cmp1, cmp2);
czero_eqz(dst, dst, t0);
czero_nez(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bne(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_ne(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
xorr(t0, cmp1, cmp2);
czero_nez(dst, dst, t0);
czero_eqz(t0 , src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
beq(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_le(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
slt(t0, cmp2, cmp1);
czero_eqz(dst, dst, t0);
czero_nez(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bgt(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_leu(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
sltu(t0, cmp2, cmp1);
czero_eqz(dst, dst, t0);
czero_nez(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bgtu(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_ge(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
slt(t0, cmp1, cmp2);
czero_eqz(dst, dst, t0);
czero_nez(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
blt(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_geu(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
sltu(t0, cmp1, cmp2);
czero_eqz(dst, dst, t0);
czero_nez(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bltu(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_lt(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
slt(t0, cmp1, cmp2);
czero_nez(dst, dst, t0);
czero_eqz(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bge(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
sltu(t0, cmp1, cmp2);
czero_nez(dst, dst, t0);
czero_eqz(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bgeu(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_gt(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
slt(t0, cmp2, cmp1);
czero_nez(dst, dst, t0);
czero_eqz(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
ble(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src) {
if (UseZicond) {
sltu(t0, cmp2, cmp1);
czero_nez(dst, dst, t0);
czero_eqz(t0, src, t0);
orr(dst, dst, t0);
return;
}
Label no_set;
bleu(cmp1, cmp2, no_set);
mv(dst, src);
bind(no_set);
}

// Float compare branch instructions

#define INSN(NAME, FLOATCMP, BRANCH) \
Expand Down
11 changes: 11 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,17 @@ class MacroAssembler: public Assembler {
void bltz(Register Rs, const address dest);
void bgtz(Register Rs, const address dest);

void cmov_eq(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_ne(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_le(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_leu(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_ge(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_geu(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_lt(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_gt(Register cmp1, Register cmp2, Register dst, Register src);
void cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src);

public:
// We try to follow risc-v asm menomics.
// But as we don't layout a reachable GOT,
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/cpu/riscv/vm_version_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ class VM_Version : public Abstract_VM_Version {
//
// Zfh Half-Precision Floating-Point instructions
//
// Zicond Conditional operations
//
// Zicsr Control and Status Register (CSR) Instructions
// Zifencei Instruction-Fetch Fence
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
Expand Down Expand Up @@ -164,6 +166,7 @@ class VM_Version : public Abstract_VM_Version {
decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvbb)) \
decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvfh)) \
decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvkn)) \
decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
Expand Down Expand Up @@ -223,6 +226,7 @@ class VM_Version : public Abstract_VM_Version {
RV_ENABLE_EXTENSION(UseZicbom) \
RV_ENABLE_EXTENSION(UseZicbop) \
RV_ENABLE_EXTENSION(UseZicboz) \
RV_ENABLE_EXTENSION(UseZicond) \
RV_ENABLE_EXTENSION(UseZihintpause) \

static void useRVA23U64Profile();
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) {
VM_Version::ext_Zvfh.enable_feature();
}
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICOND)) {
VM_Version::ext_Zicond.enable_feature();
}
if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) {
VM_Version::unaligned_access.enable_feature(
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
Expand Down
Loading

0 comments on commit 15154e7

Please sign in to comment.