Skip to content

Commit 9c55e25

Browse files
committed
8347981: RISC-V: Add Zfa zli imm loads
Reviewed-by: fyang, luhenry
1 parent e20bd01 commit 9c55e25

File tree

7 files changed

+192
-9
lines changed

7 files changed

+192
-9
lines changed

src/hotspot/cpu/riscv/assembler_riscv.hpp

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,104 @@ class InternalAddress: public Address {
330330
};
331331

332332
class Assembler : public AbstractAssembler {
333-
public:
333+
protected:
334+
335+
static int zfa_zli_lookup_double(uint64_t value) {
336+
switch(value) {
337+
case 0xbff0000000000000 : return 0;
338+
case 0x0010000000000000 : return 1;
339+
case 0x3ef0000000000000 : return 2;
340+
case 0x3f00000000000000 : return 3;
341+
case 0x3f70000000000000 : return 4;
342+
case 0x3f80000000000000 : return 5;
343+
case 0x3fb0000000000000 : return 6;
344+
case 0x3fc0000000000000 : return 7;
345+
case 0x3fd0000000000000 : return 8;
346+
case 0x3fd4000000000000 : return 9;
347+
case 0x3fd8000000000000 : return 10;
348+
case 0x3fdc000000000000 : return 11;
349+
case 0x3fe0000000000000 : return 12;
350+
case 0x3fe4000000000000 : return 13;
351+
case 0x3fe8000000000000 : return 14;
352+
case 0x3fec000000000000 : return 15;
353+
case 0x3ff0000000000000 : return 16;
354+
case 0x3ff4000000000000 : return 17;
355+
case 0x3ff8000000000000 : return 18;
356+
case 0x3ffc000000000000 : return 19;
357+
case 0x4000000000000000 : return 20;
358+
case 0x4004000000000000 : return 21;
359+
case 0x4008000000000000 : return 22;
360+
case 0x4010000000000000 : return 23;
361+
case 0x4020000000000000 : return 24;
362+
case 0x4030000000000000 : return 25;
363+
case 0x4060000000000000 : return 26;
364+
case 0x4070000000000000 : return 27;
365+
case 0x40e0000000000000 : return 28;
366+
case 0x40f0000000000000 : return 29;
367+
case 0x7ff0000000000000 : return 30;
368+
case 0x7ff8000000000000 : return 31;
369+
default: break;
370+
}
371+
return -1;
372+
}
373+
374+
375+
static int zfa_zli_lookup_float(uint32_t value) {
376+
switch(value) {
377+
case 0xbf800000 : return 0;
378+
case 0x00800000 : return 1;
379+
case 0x37800000 : return 2;
380+
case 0x38000000 : return 3;
381+
case 0x3b800000 : return 4;
382+
case 0x3c000000 : return 5;
383+
case 0x3d800000 : return 6;
384+
case 0x3e000000 : return 7;
385+
case 0x3e800000 : return 8;
386+
case 0x3ea00000 : return 9;
387+
case 0x3ec00000 : return 10;
388+
case 0x3ee00000 : return 11;
389+
case 0x3f000000 : return 12;
390+
case 0x3f200000 : return 13;
391+
case 0x3f400000 : return 14;
392+
case 0x3f600000 : return 15;
393+
case 0x3f800000 : return 16;
394+
case 0x3fa00000 : return 17;
395+
case 0x3fc00000 : return 18;
396+
case 0x3fe00000 : return 19;
397+
case 0x40000000 : return 20;
398+
case 0x40200000 : return 21;
399+
case 0x40400000 : return 22;
400+
case 0x40800000 : return 23;
401+
case 0x41000000 : return 24;
402+
case 0x41800000 : return 25;
403+
case 0x43000000 : return 26;
404+
case 0x43800000 : return 27;
405+
case 0x47000000 : return 28;
406+
case 0x47800000 : return 29;
407+
case 0x7f800000 : return 30;
408+
case 0x7fc00000 : return 31;
409+
default: break;
410+
}
411+
return -1;
412+
}
413+
414+
public:
415+
416+
static bool can_zfa_zli_float(jfloat f) {
417+
if (!UseZfa) {
418+
return false;
419+
}
420+
uint32_t f_bits = (uint32_t)jint_cast(f);
421+
return zfa_zli_lookup_float(f_bits) != -1;
422+
}
423+
424+
static bool can_zfa_zli_double(jdouble d) {
425+
if (!UseZfa) {
426+
return false;
427+
}
428+
uint64_t d_bits = (uint64_t)julong_cast(d);
429+
return zfa_zli_lookup_double(d_bits) != -1;
430+
}
334431

335432
enum {
336433
instruction_size = 4,
@@ -972,6 +1069,13 @@ enum operand_size { int8, int16, int32, uint32, int64 };
9721069
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm);
9731070
}
9741071

1072+
template <FmtPrecision Fmt, uint8_t funct5>
1073+
void fp_base(FloatRegister Rd, uint8_t Rs1, uint8_t Rs2, int8_t rm) {
1074+
guarantee(is_uimm5(Rs1), "Rs1 is out of validity");
1075+
guarantee(is_uimm5(Rs2), "Rs2 is out of validity");
1076+
fp_base<Fmt, funct5>(Rd->raw_encoding(), Rs1, Rs2, (RoundingMode)rm);
1077+
}
1078+
9751079
public:
9761080

9771081
enum FClassBits {
@@ -1293,6 +1397,18 @@ enum operand_size { int8, int16, int32, uint32, int64 };
12931397
fp_base<H_16_hp, 0b11100>(Rd, Rs1, 0b00000, 0b000);
12941398
}
12951399

1400+
// -------------- ZFA Instruction Definitions --------------
1401+
// Zfa Extension for Additional Floating-Point Instructions
1402+
void _fli_s(FloatRegister Rd, uint8_t Rs1) {
1403+
assert_cond(UseZfa);
1404+
fp_base<S_32_sp, 0b11110>(Rd, Rs1, 0b00001, 0b000);
1405+
}
1406+
1407+
void _fli_d(FloatRegister Rd, uint8_t Rs1) {
1408+
assert_cond(UseZfa);
1409+
fp_base<D_64_dp, 0b11110>(Rd, Rs1, 0b00001, 0b000);
1410+
}
1411+
12961412
// ==========================
12971413
// RISC-V Vector Extension
12981414
// ==========================

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,8 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
425425
assert(dest->is_register(), "should not call otherwise");
426426
LIR_Const* c = src->as_constant_ptr();
427427
address const_addr = nullptr;
428+
jfloat fconst;
429+
jdouble dconst;
428430

429431
switch (c->type()) {
430432
case T_INT:
@@ -460,15 +462,25 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
460462
break;
461463

462464
case T_FLOAT:
463-
const_addr = float_constant(c->as_jfloat());
464-
assert(const_addr != nullptr, "must create float constant in the constant table");
465-
__ flw(dest->as_float_reg(), InternalAddress(const_addr));
465+
fconst = c->as_jfloat();
466+
if (MacroAssembler::can_fp_imm_load(fconst)) {
467+
__ fli_s(dest->as_float_reg(), fconst);
468+
} else {
469+
const_addr = float_constant(fconst);
470+
assert(const_addr != nullptr, "must create float constant in the constant table");
471+
__ flw(dest->as_float_reg(), InternalAddress(const_addr));
472+
}
466473
break;
467474

468475
case T_DOUBLE:
469-
const_addr = double_constant(c->as_jdouble());
470-
assert(const_addr != nullptr, "must create double constant in the constant table");
471-
__ fld(dest->as_double_reg(), InternalAddress(const_addr));
476+
dconst = c->as_jdouble();
477+
if (MacroAssembler::can_dp_imm_load(dconst)) {
478+
__ fli_d(dest->as_double_reg(), dconst);
479+
} else {
480+
const_addr = double_constant(c->as_jdouble());
481+
assert(const_addr != nullptr, "must create double constant in the constant table");
482+
__ fld(dest->as_double_reg(), InternalAddress(const_addr));
483+
}
472484
break;
473485

474486
default:

src/hotspot/cpu/riscv/globals_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
103103
product(bool, UseZba, false, DIAGNOSTIC, "Use Zba instructions") \
104104
product(bool, UseZbb, false, DIAGNOSTIC, "Use Zbb instructions") \
105105
product(bool, UseZbs, false, DIAGNOSTIC, "Use Zbs instructions") \
106+
product(bool, UseZfa, false, EXPERIMENTAL, "Use Zfa instructions") \
106107
product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \
107108
product(bool, UseZfhmin, false, DIAGNOSTIC, "Use Zfhmin instructions") \
108109
product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,45 @@ void MacroAssembler::movptr2(Register Rd, uint64_t addr, int32_t &offset, Regist
25932593
offset = lower12;
25942594
}
25952595

2596+
// floating point imm move
2597+
bool MacroAssembler::can_fp_imm_load(float imm) {
2598+
jint f_bits = jint_cast(imm);
2599+
if (f_bits == 0) {
2600+
return true;
2601+
}
2602+
return can_zfa_zli_float(imm);
2603+
}
2604+
2605+
bool MacroAssembler::can_dp_imm_load(double imm) {
2606+
julong d_bits = julong_cast(imm);
2607+
if (d_bits == 0) {
2608+
return true;
2609+
}
2610+
return can_zfa_zli_double(imm);
2611+
}
2612+
2613+
void MacroAssembler::fli_s(FloatRegister Rd, float imm) {
2614+
jint f_bits = jint_cast(imm);
2615+
if (f_bits == 0) {
2616+
fmv_w_x(Rd, zr);
2617+
return;
2618+
}
2619+
int Rs = zfa_zli_lookup_float(f_bits);
2620+
assert(Rs != -1, "Must be");
2621+
_fli_s(Rd, Rs);
2622+
}
2623+
2624+
void MacroAssembler::fli_d(FloatRegister Rd, double imm) {
2625+
uint64_t d_bits = (uint64_t)julong_cast(imm);
2626+
if (d_bits == 0) {
2627+
fmv_d_x(Rd, zr);
2628+
return;
2629+
}
2630+
int Rs = zfa_zli_lookup_double(d_bits);
2631+
assert(Rs != -1, "Must be");
2632+
_fli_d(Rd, Rs);
2633+
}
2634+
25962635
void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register tmp) {
25972636
if (is_simm12(increment)) {
25982637
addi(Rd, Rn, increment);

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,11 @@ class MacroAssembler: public Assembler {
920920
void movptr1(Register Rd, uintptr_t addr, int32_t &offset);
921921
void movptr2(Register Rd, uintptr_t addr, int32_t &offset, Register tmp);
922922
public:
923+
// float imm move
924+
static bool can_fp_imm_load(float imm);
925+
static bool can_dp_imm_load(double imm);
926+
void fli_s(FloatRegister Rd, float imm);
927+
void fli_d(FloatRegister Rd, double imm);
923928

924929
// arith
925930
void add (Register Rd, Register Rn, int64_t increment, Register tmp = t0);

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4920,7 +4920,11 @@ instruct loadConF(fRegF dst, immF con) %{
49204920
%}
49214921

49224922
ins_encode %{
4923-
__ flw(as_FloatRegister($dst$$reg), $constantaddress($con));
4923+
if (MacroAssembler::can_fp_imm_load($con$$constant)) {
4924+
__ fli_s(as_FloatRegister($dst$$reg), $con$$constant);
4925+
} else {
4926+
__ flw(as_FloatRegister($dst$$reg), $constantaddress($con));
4927+
}
49244928
%}
49254929

49264930
ins_pipe(fp_load_constant_s);
@@ -4950,7 +4954,11 @@ instruct loadConD(fRegD dst, immD con) %{
49504954
%}
49514955

49524956
ins_encode %{
4953-
__ fld(as_FloatRegister($dst$$reg), $constantaddress($con));
4957+
if (MacroAssembler::can_dp_imm_load($con$$constant)) {
4958+
__ fli_d(as_FloatRegister($dst$$reg), $con$$constant);
4959+
} else {
4960+
__ fld(as_FloatRegister($dst$$reg), $constantaddress($con));
4961+
}
49544962
%}
49554963

49564964
ins_pipe(fp_load_constant_d);

src/hotspot/cpu/riscv/vm_version_riscv.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class VM_Version : public Abstract_VM_Version {
157157
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
158158
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
159159
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
160+
decl(ext_Zfa , "Zfa" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
160161
decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
161162
decl(ext_Zfhmin , "Zfhmin" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
162163
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
@@ -226,6 +227,7 @@ class VM_Version : public Abstract_VM_Version {
226227
RV_ENABLE_EXTENSION(UseZbb) \
227228
RV_ENABLE_EXTENSION(UseZbs) \
228229
RV_ENABLE_EXTENSION(UseZcb) \
230+
RV_ENABLE_EXTENSION(UseZfa) \
229231
RV_ENABLE_EXTENSION(UseZfhmin) \
230232
RV_ENABLE_EXTENSION(UseZic64b) \
231233
RV_ENABLE_EXTENSION(UseZicbom) \

0 commit comments

Comments
 (0)