Skip to content

Commit edfe285

Browse files
committedNov 28, 2024
8344306: RISC-V: Add zicond
Reviewed-by: fyang, luhenry, mli
1 parent d33ad07 commit edfe285

10 files changed

+344
-5
lines changed
 

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

+32
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,38 @@ enum Nf {
31073107

31083108
#undef INSN
31093109

3110+
// -------------- Zicond Instruction Definitions --------------
3111+
// Zicond conditional operations extension
3112+
private:
3113+
enum CZERO_OP : unsigned int {
3114+
CZERO_NEZ = 0b111,
3115+
CZERO_EQZ = 0b101
3116+
};
3117+
3118+
template <CZERO_OP OP_VALUE>
3119+
void czero(Register Rd, Register Rs1, Register Rs2) {
3120+
assert_cond(UseZicond);
3121+
uint32_t insn = 0;
3122+
patch ((address)&insn, 6, 0, 0b0110011); // bits: 7, name: 0x33, attr: ['OP']
3123+
patch_reg((address)&insn, 7, Rd); // bits: 5, name: 'rd'
3124+
patch ((address)&insn, 14, 12, OP_VALUE); // bits: 3, name: 0x7, attr: ['CZERO.NEZ'] / 0x5, attr: ['CZERO.EQZ']}
3125+
patch_reg((address)&insn, 15, Rs1); // bits: 5, name: 'rs1', attr: ['value']
3126+
patch_reg((address)&insn, 20, Rs2); // bits: 5, name: 'rs2', attr: ['condition']
3127+
patch ((address)&insn, 31, 25, 0b0000111); // bits: 7, name: 0x7, attr: ['CZERO']
3128+
emit_int32(insn);
3129+
}
3130+
3131+
public:
3132+
// Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd.
3133+
void czero_eqz(Register rd, Register rs1_value, Register rs2_condition) {
3134+
czero<CZERO_EQZ>(rd, rs1_value, rs2_condition);
3135+
}
3136+
3137+
// Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd.
3138+
void czero_nez(Register rd, Register rs1_value, Register rs2_condition) {
3139+
czero<CZERO_NEZ>(rd, rs1_value, rs2_condition);
3140+
}
3141+
31103142
// -------------- ZCB Instruction Definitions --------------
31113143
// Zcb additional C instructions
31123144
private:

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

+1
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
870870
}
871871
}
872872

873+
// Consider using cmov (Zicond)
873874
void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type,
874875
LIR_Opr cmp_opr1, LIR_Opr cmp_opr2) {
875876
Label label;

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

+42-4
Original file line numberDiff line numberDiff line change
@@ -2003,10 +2003,48 @@ void C2_MacroAssembler::enc_cmpEqNe_imm0_branch(int cmpFlag, Register op1, Label
20032003
}
20042004

20052005
void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Register dst, Register src) {
2006-
Label L;
2007-
cmp_branch(cmpFlag ^ (1 << neg_cond_bits), op1, op2, L);
2008-
mv(dst, src);
2009-
bind(L);
2006+
bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask;
2007+
int op_select = cmpFlag & (~unsigned_branch_mask);
2008+
2009+
switch (op_select) {
2010+
case BoolTest::eq:
2011+
cmov_eq(op1, op2, dst, src);
2012+
break;
2013+
case BoolTest::ne:
2014+
cmov_ne(op1, op2, dst, src);
2015+
break;
2016+
case BoolTest::le:
2017+
if (is_unsigned) {
2018+
cmov_leu(op1, op2, dst, src);
2019+
} else {
2020+
cmov_le(op1, op2, dst, src);
2021+
}
2022+
break;
2023+
case BoolTest::ge:
2024+
if (is_unsigned) {
2025+
cmov_geu(op1, op2, dst, src);
2026+
} else {
2027+
cmov_ge(op1, op2, dst, src);
2028+
}
2029+
break;
2030+
case BoolTest::lt:
2031+
if (is_unsigned) {
2032+
cmov_ltu(op1, op2, dst, src);
2033+
} else {
2034+
cmov_lt(op1, op2, dst, src);
2035+
}
2036+
break;
2037+
case BoolTest::gt:
2038+
if (is_unsigned) {
2039+
cmov_gtu(op1, op2, dst, src);
2040+
} else {
2041+
cmov_gt(op1, op2, dst, src);
2042+
}
2043+
break;
2044+
default:
2045+
assert(false, "unsupported compare condition");
2046+
ShouldNotReachHere();
2047+
}
20102048
}
20112049

20122050
// Set dst to NaN if any NaN input.

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

-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898

9999
// refer to conditional_branches and float_conditional_branches
100100
static const int bool_test_bits = 3;
101-
static const int neg_cond_bits = 2;
102101
static const int unsigned_branch_mask = 1 << bool_test_bits;
103102
static const int double_branch_mask = 1 << bool_test_bits;
104103

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

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
110110
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \
111111
product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \
112112
product(bool, UseZicboz, false, EXPERIMENTAL, "Use Zicboz instructions") \
113+
product(bool, UseZicond, false, DIAGNOSTIC, "Use Zicond instructions") \
113114
product(bool, UseZihintpause, false, EXPERIMENTAL, \
114115
"Use Zihintpause instructions") \
115116
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \

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

+141
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,147 @@ void MacroAssembler::wrap_label(Register r1, Register r2, Label &L,
11281128

11291129
#undef INSN
11301130

1131+
// cmov
1132+
void MacroAssembler::cmov_eq(Register cmp1, Register cmp2, Register dst, Register src) {
1133+
if (UseZicond) {
1134+
xorr(t0, cmp1, cmp2);
1135+
czero_eqz(dst, dst, t0);
1136+
czero_nez(t0 , src, t0);
1137+
orr(dst, dst, t0);
1138+
return;
1139+
}
1140+
Label no_set;
1141+
bne(cmp1, cmp2, no_set);
1142+
mv(dst, src);
1143+
bind(no_set);
1144+
}
1145+
1146+
void MacroAssembler::cmov_ne(Register cmp1, Register cmp2, Register dst, Register src) {
1147+
if (UseZicond) {
1148+
xorr(t0, cmp1, cmp2);
1149+
czero_nez(dst, dst, t0);
1150+
czero_eqz(t0 , src, t0);
1151+
orr(dst, dst, t0);
1152+
return;
1153+
}
1154+
Label no_set;
1155+
beq(cmp1, cmp2, no_set);
1156+
mv(dst, src);
1157+
bind(no_set);
1158+
}
1159+
1160+
void MacroAssembler::cmov_le(Register cmp1, Register cmp2, Register dst, Register src) {
1161+
if (UseZicond) {
1162+
slt(t0, cmp2, cmp1);
1163+
czero_eqz(dst, dst, t0);
1164+
czero_nez(t0, src, t0);
1165+
orr(dst, dst, t0);
1166+
return;
1167+
}
1168+
Label no_set;
1169+
bgt(cmp1, cmp2, no_set);
1170+
mv(dst, src);
1171+
bind(no_set);
1172+
}
1173+
1174+
void MacroAssembler::cmov_leu(Register cmp1, Register cmp2, Register dst, Register src) {
1175+
if (UseZicond) {
1176+
sltu(t0, cmp2, cmp1);
1177+
czero_eqz(dst, dst, t0);
1178+
czero_nez(t0, src, t0);
1179+
orr(dst, dst, t0);
1180+
return;
1181+
}
1182+
Label no_set;
1183+
bgtu(cmp1, cmp2, no_set);
1184+
mv(dst, src);
1185+
bind(no_set);
1186+
}
1187+
1188+
void MacroAssembler::cmov_ge(Register cmp1, Register cmp2, Register dst, Register src) {
1189+
if (UseZicond) {
1190+
slt(t0, cmp1, cmp2);
1191+
czero_eqz(dst, dst, t0);
1192+
czero_nez(t0, src, t0);
1193+
orr(dst, dst, t0);
1194+
return;
1195+
}
1196+
Label no_set;
1197+
blt(cmp1, cmp2, no_set);
1198+
mv(dst, src);
1199+
bind(no_set);
1200+
}
1201+
1202+
void MacroAssembler::cmov_geu(Register cmp1, Register cmp2, Register dst, Register src) {
1203+
if (UseZicond) {
1204+
sltu(t0, cmp1, cmp2);
1205+
czero_eqz(dst, dst, t0);
1206+
czero_nez(t0, src, t0);
1207+
orr(dst, dst, t0);
1208+
return;
1209+
}
1210+
Label no_set;
1211+
bltu(cmp1, cmp2, no_set);
1212+
mv(dst, src);
1213+
bind(no_set);
1214+
}
1215+
1216+
void MacroAssembler::cmov_lt(Register cmp1, Register cmp2, Register dst, Register src) {
1217+
if (UseZicond) {
1218+
slt(t0, cmp1, cmp2);
1219+
czero_nez(dst, dst, t0);
1220+
czero_eqz(t0, src, t0);
1221+
orr(dst, dst, t0);
1222+
return;
1223+
}
1224+
Label no_set;
1225+
bge(cmp1, cmp2, no_set);
1226+
mv(dst, src);
1227+
bind(no_set);
1228+
}
1229+
1230+
void MacroAssembler::cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src) {
1231+
if (UseZicond) {
1232+
sltu(t0, cmp1, cmp2);
1233+
czero_nez(dst, dst, t0);
1234+
czero_eqz(t0, src, t0);
1235+
orr(dst, dst, t0);
1236+
return;
1237+
}
1238+
Label no_set;
1239+
bgeu(cmp1, cmp2, no_set);
1240+
mv(dst, src);
1241+
bind(no_set);
1242+
}
1243+
1244+
void MacroAssembler::cmov_gt(Register cmp1, Register cmp2, Register dst, Register src) {
1245+
if (UseZicond) {
1246+
slt(t0, cmp2, cmp1);
1247+
czero_nez(dst, dst, t0);
1248+
czero_eqz(t0, src, t0);
1249+
orr(dst, dst, t0);
1250+
return;
1251+
}
1252+
Label no_set;
1253+
ble(cmp1, cmp2, no_set);
1254+
mv(dst, src);
1255+
bind(no_set);
1256+
}
1257+
1258+
void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src) {
1259+
if (UseZicond) {
1260+
sltu(t0, cmp2, cmp1);
1261+
czero_nez(dst, dst, t0);
1262+
czero_eqz(t0, src, t0);
1263+
orr(dst, dst, t0);
1264+
return;
1265+
}
1266+
Label no_set;
1267+
bleu(cmp1, cmp2, no_set);
1268+
mv(dst, src);
1269+
bind(no_set);
1270+
}
1271+
11311272
// Float compare branch instructions
11321273

11331274
#define INSN(NAME, FLOATCMP, BRANCH) \

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

+11
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,17 @@ class MacroAssembler: public Assembler {
626626
void bltz(Register Rs, const address dest);
627627
void bgtz(Register Rs, const address dest);
628628

629+
void cmov_eq(Register cmp1, Register cmp2, Register dst, Register src);
630+
void cmov_ne(Register cmp1, Register cmp2, Register dst, Register src);
631+
void cmov_le(Register cmp1, Register cmp2, Register dst, Register src);
632+
void cmov_leu(Register cmp1, Register cmp2, Register dst, Register src);
633+
void cmov_ge(Register cmp1, Register cmp2, Register dst, Register src);
634+
void cmov_geu(Register cmp1, Register cmp2, Register dst, Register src);
635+
void cmov_lt(Register cmp1, Register cmp2, Register dst, Register src);
636+
void cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src);
637+
void cmov_gt(Register cmp1, Register cmp2, Register dst, Register src);
638+
void cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src);
639+
629640
public:
630641
// We try to follow risc-v asm menomics.
631642
// But as we don't layout a reachable GOT,

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

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class VM_Version : public Abstract_VM_Version {
116116
//
117117
// Zfh Half-Precision Floating-Point instructions
118118
//
119+
// Zicond Conditional operations
120+
//
119121
// Zicsr Control and Status Register (CSR) Instructions
120122
// Zifencei Instruction-Fetch Fence
121123
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
@@ -164,6 +166,7 @@ class VM_Version : public Abstract_VM_Version {
164166
decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvbb)) \
165167
decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvfh)) \
166168
decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvkn)) \
169+
decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
167170
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
168171
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
169172
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
@@ -223,6 +226,7 @@ class VM_Version : public Abstract_VM_Version {
223226
RV_ENABLE_EXTENSION(UseZicbom) \
224227
RV_ENABLE_EXTENSION(UseZicbop) \
225228
RV_ENABLE_EXTENSION(UseZicboz) \
229+
RV_ENABLE_EXTENSION(UseZicond) \
226230
RV_ENABLE_EXTENSION(UseZihintpause) \
227231

228232
static void useRVA23U64Profile();

‎src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ void RiscvHwprobe::add_features_from_query_result() {
181181
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) {
182182
VM_Version::ext_Zvfh.enable_feature();
183183
}
184+
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICOND)) {
185+
VM_Version::ext_Zicond.enable_feature();
186+
}
184187
if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) {
185188
VM_Version::unaligned_access.enable_feature(
186189
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);

0 commit comments

Comments
 (0)
Please sign in to comment.