Skip to content

Commit 04eac0c

Browse files
author
Hamlin Li
committed
8352159: RISC-V: add more zfa support
Reviewed-by: fyang, luhenry, rehn
1 parent ac760dd commit 04eac0c

File tree

4 files changed

+114
-30
lines changed

4 files changed

+114
-30
lines changed

src/hotspot/cpu/riscv/assembler_riscv.hpp

+54-3
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ class Assembler : public AbstractAssembler {
371371
return -1;
372372
}
373373

374-
375374
static int zfa_zli_lookup_float(uint32_t value) {
376375
switch(value) {
377376
case 0xbf800000 : return 0;
@@ -411,8 +410,55 @@ class Assembler : public AbstractAssembler {
411410
return -1;
412411
}
413412

413+
static int zfa_zli_lookup_half_float(uint16_t value) {
414+
switch(value) {
415+
case 0xbc00 : return 0;
416+
case 0x0400 : return 1;
417+
case 0x0100 : return 2;
418+
case 0x0200 : return 3;
419+
case 0x1c00 : return 4;
420+
case 0x2000 : return 5;
421+
case 0x2c00 : return 6;
422+
case 0x3000 : return 7;
423+
case 0x3400 : return 8;
424+
case 0x3500 : return 9;
425+
case 0x3600 : return 10;
426+
case 0x3700 : return 11;
427+
case 0x3800 : return 12;
428+
case 0x3900 : return 13;
429+
case 0x3a00 : return 14;
430+
case 0x3b00 : return 15;
431+
case 0x3c00 : return 16;
432+
case 0x3d00 : return 17;
433+
case 0x3e00 : return 18;
434+
case 0x3f00 : return 19;
435+
case 0x4000 : return 20;
436+
case 0x4100 : return 21;
437+
case 0x4200 : return 22;
438+
case 0x4400 : return 23;
439+
case 0x4800 : return 24;
440+
case 0x4c00 : return 25;
441+
case 0x5800 : return 26;
442+
case 0x5c00 : return 27;
443+
case 0x7800 : return 28;
444+
case 0x7c00 : return 29;
445+
// case 0x7c00 : return 30; // redundant with 29
446+
case 0x7e00 : return 31;
447+
default: break;
448+
}
449+
return -1;
450+
}
451+
414452
public:
415453

454+
static bool can_zfa_zli_half_float(jshort hf) {
455+
if (!UseZfa || !UseZfh) {
456+
return false;
457+
}
458+
uint16_t hf_bits = (uint16_t)hf;
459+
return zfa_zli_lookup_half_float(hf_bits) != -1;
460+
}
461+
416462
static bool can_zfa_zli_float(jfloat f) {
417463
if (!UseZfa) {
418464
return false;
@@ -1440,6 +1486,11 @@ enum operand_size { int8, int16, int32, uint32, int64 };
14401486

14411487
// -------------- ZFA Instruction Definitions --------------
14421488
// Zfa Extension for Additional Floating-Point Instructions
1489+
void _fli_h(FloatRegister Rd, uint8_t Rs1) {
1490+
assert_cond(UseZfa && UseZfh);
1491+
fp_base<H_16_hp, 0b11110>(Rd, Rs1, 0b00001, 0b000);
1492+
}
1493+
14431494
void _fli_s(FloatRegister Rd, uint8_t Rs1) {
14441495
assert_cond(UseZfa);
14451496
fp_base<S_32_sp, 0b11110>(Rd, Rs1, 0b00001, 0b000);
@@ -1451,12 +1502,12 @@ enum operand_size { int8, int16, int32, uint32, int64 };
14511502
}
14521503

14531504
void fminm_h(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
1454-
assert_cond(UseZfa);
1505+
assert_cond(UseZfa && UseZfh);
14551506
fp_base<H_16_hp, 0b00101>(Rd, Rs1, Rs2, 0b010);
14561507
}
14571508

14581509
void fmaxm_h(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) {
1459-
assert_cond(UseZfa);
1510+
assert_cond(UseZfa && UseZfh);
14601511
fp_base<H_16_hp, 0b00101>(Rd, Rs1, Rs2, 0b011);
14611512
}
14621513

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -2594,6 +2594,14 @@ void MacroAssembler::movptr2(Register Rd, uint64_t addr, int32_t &offset, Regist
25942594
}
25952595

25962596
// floating point imm move
2597+
bool MacroAssembler::can_hf_imm_load(short imm) {
2598+
jshort h_bits = (jshort)imm;
2599+
if (h_bits == 0) {
2600+
return true;
2601+
}
2602+
return can_zfa_zli_half_float(imm);
2603+
}
2604+
25972605
bool MacroAssembler::can_fp_imm_load(float imm) {
25982606
jint f_bits = jint_cast(imm);
25992607
if (f_bits == 0) {
@@ -2610,6 +2618,17 @@ bool MacroAssembler::can_dp_imm_load(double imm) {
26102618
return can_zfa_zli_double(imm);
26112619
}
26122620

2621+
void MacroAssembler::fli_h(FloatRegister Rd, short imm) {
2622+
jshort h_bits = (jshort)imm;
2623+
if (h_bits == 0) {
2624+
fmv_h_x(Rd, zr);
2625+
return;
2626+
}
2627+
int Rs = zfa_zli_lookup_half_float(h_bits);
2628+
assert(Rs != -1, "Must be");
2629+
_fli_h(Rd, Rs);
2630+
}
2631+
26132632
void MacroAssembler::fli_s(FloatRegister Rd, float imm) {
26142633
jint f_bits = jint_cast(imm);
26152634
if (f_bits == 0) {

src/hotspot/cpu/riscv/macroAssembler_riscv.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -915,8 +915,10 @@ class MacroAssembler: public Assembler {
915915
void movptr2(Register Rd, uintptr_t addr, int32_t &offset, Register tmp);
916916
public:
917917
// float imm move
918+
static bool can_hf_imm_load(short imm);
918919
static bool can_fp_imm_load(float imm);
919920
static bool can_dp_imm_load(double imm);
921+
void fli_h(FloatRegister Rd, short imm);
920922
void fli_s(FloatRegister Rd, float imm);
921923
void fli_d(FloatRegister Rd, double imm);
922924

src/hotspot/cpu/riscv/riscv.ad

+39-27
Original file line numberDiff line numberDiff line change
@@ -4897,8 +4897,11 @@ instruct loadConH(fRegF dst, immH con) %{
48974897

48984898
ins_encode %{
48994899
assert(UseZfh || UseZfhmin, "must");
4900-
__ flh(as_FloatRegister($dst$$reg), $constantaddress($con));
4901-
// TODO: add zfa instructions for half float, and optimize here.
4900+
if (MacroAssembler::can_hf_imm_load($con$$constant)) {
4901+
__ fli_h(as_FloatRegister($dst$$reg), $con$$constant);
4902+
} else {
4903+
__ flh(as_FloatRegister($dst$$reg), $constantaddress($con));
4904+
}
49024905
%}
49034906

49044907
ins_pipe(fp_load_constant_s);
@@ -4929,11 +4932,11 @@ instruct loadConF(fRegF dst, immF con) %{
49294932
%}
49304933

49314934
ins_encode %{
4932-
if (MacroAssembler::can_fp_imm_load($con$$constant)) {
4933-
__ fli_s(as_FloatRegister($dst$$reg), $con$$constant);
4934-
} else {
4935-
__ flw(as_FloatRegister($dst$$reg), $constantaddress($con));
4936-
}
4935+
if (MacroAssembler::can_fp_imm_load($con$$constant)) {
4936+
__ fli_s(as_FloatRegister($dst$$reg), $con$$constant);
4937+
} else {
4938+
__ flw(as_FloatRegister($dst$$reg), $constantaddress($con));
4939+
}
49374940
%}
49384941

49394942
ins_pipe(fp_load_constant_s);
@@ -4963,11 +4966,11 @@ instruct loadConD(fRegD dst, immD con) %{
49634966
%}
49644967

49654968
ins_encode %{
4966-
if (MacroAssembler::can_dp_imm_load($con$$constant)) {
4967-
__ fli_d(as_FloatRegister($dst$$reg), $con$$constant);
4968-
} else {
4969-
__ fld(as_FloatRegister($dst$$reg), $constantaddress($con));
4970-
}
4969+
if (MacroAssembler::can_dp_imm_load($con$$constant)) {
4970+
__ fli_d(as_FloatRegister($dst$$reg), $con$$constant);
4971+
} else {
4972+
__ fld(as_FloatRegister($dst$$reg), $constantaddress($con));
4973+
}
49714974
%}
49724975

49734976
ins_pipe(fp_load_constant_d);
@@ -8342,28 +8345,22 @@ instruct binOps_HF_reg(fRegF dst, fRegF src1, fRegF src2)
83428345
ins_pipe(fp_dop_reg_reg_s);
83438346
%}
83448347

8345-
instruct min_max_HF_reg(fRegF dst, fRegF src1, fRegF src2)
8348+
instruct min_HF_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr)
83468349
%{
83478350
predicate(!UseZfa);
83488351
match(Set dst (MinHF src1 src2));
8349-
match(Set dst (MaxHF src1 src2));
8350-
format %{ "min_max_hf $dst, $src1, $src2" %}
8352+
effect(KILL cr);
8353+
8354+
format %{ "min_hf $dst, $src1, $src2" %}
8355+
83518356
ins_encode %{
8352-
int opcode = this->ideal_Opcode();
8353-
switch(opcode) {
8354-
case Op_MinHF: __ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
8355-
__ FLOAT_TYPE::half_precision, true);
8356-
break;
8357-
case Op_MaxHF: __ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
8358-
__ FLOAT_TYPE::half_precision, false);
8359-
break;
8360-
default: assert(false, "%s is not supported here", NodeClassNames[opcode]); break;
8361-
}
8357+
__ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
8358+
__ FLOAT_TYPE::half_precision, true /* is_min */);
83628359
%}
83638360
ins_pipe(pipe_class_default);
83648361
%}
83658362

8366-
instruct minHF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
8363+
instruct min_HF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
83678364
%{
83688365
predicate(UseZfa);
83698366
match(Set dst (MinHF src1 src2));
@@ -8378,7 +8375,22 @@ instruct minHF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
83788375
ins_pipe(pipe_class_default);
83798376
%}
83808377

8381-
instruct maxHF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
8378+
instruct max_HF_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr)
8379+
%{
8380+
predicate(!UseZfa);
8381+
match(Set dst (MaxHF src1 src2));
8382+
effect(KILL cr);
8383+
8384+
format %{ "max_hf $dst, $src1, $src2" %}
8385+
8386+
ins_encode %{
8387+
__ minmax_fp($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
8388+
__ FLOAT_TYPE::half_precision, false /* is_min */);
8389+
%}
8390+
ins_pipe(pipe_class_default);
8391+
%}
8392+
8393+
instruct max_HF_reg_zfa(fRegF dst, fRegF src1, fRegF src2)
83828394
%{
83838395
predicate(UseZfa);
83848396
match(Set dst (MaxHF src1 src2));

0 commit comments

Comments
 (0)