Skip to content

Commit 7122090

Browse files
authored
[RISC-V] Synthesize some floating constants inline (#111529)
1 parent edb2fac commit 7122090

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

src/coreclr/jit/codegenriscv64.cpp

+29-14
Original file line numberDiff line numberDiff line change
@@ -1090,29 +1090,44 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
10901090
emitAttr size = emitActualTypeSize(tree);
10911091
double constValue = tree->AsDblCon()->DconValue();
10921092

1093-
// Make sure we use "fmv.w.x reg, zero" only for positive zero (0.0)
1094-
// and not for negative zero (-0.0)
1093+
assert(emitter::isFloatReg(targetReg));
1094+
1095+
// Make sure we use "fmv.w.x reg, zero" only for positive zero (0.0) and not for negative zero (-0.0)
10951096
if (FloatingPointUtils::isPositiveZero(constValue))
10961097
{
10971098
// A faster/smaller way to generate 0.0
1098-
// We will just zero out the entire vector register for both float and double
1099+
// We will just zero out the entire register for both float and double
10991100
emit->emitIns_R_R(size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, REG_R0);
1101+
break;
11001102
}
1101-
else
1103+
1104+
int64_t bits =
1105+
(size == EA_4BYTE)
1106+
? (int32_t)BitOperations::SingleToUInt32Bits(FloatingPointUtils::convertToSingle(constValue))
1107+
: (int64_t)BitOperations::DoubleToUInt64Bits(constValue);
1108+
bool fitsInLui = ((bits & 0xfff) == 0) && emitter::isValidSimm20(bits >> 12);
1109+
if (fitsInLui || emitter::isValidSimm12(bits)) // can we synthesize bits with a single instruction?
11021110
{
1103-
// Get a temp integer register to compute long address.
1104-
// regNumber addrReg = internalRegisters.GetSingle(tree);
1111+
regNumber temp = internalRegisters.GetSingle(tree);
1112+
if (fitsInLui)
1113+
{
1114+
emit->emitIns_R_I(INS_lui, size, temp, bits >> 12);
1115+
}
1116+
else
1117+
{
1118+
emit->emitIns_R_R_I(INS_addi, size, temp, REG_ZERO, bits);
1119+
}
11051120

1106-
// We must load the FP constant from the constant pool
1107-
// Emit a data section constant for the float or double constant.
1108-
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(constValue, size);
1121+
emit->emitIns_R_R(size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, temp);
1122+
break;
1123+
}
11091124

1110-
// Load the FP constant.
1111-
assert(emit->isFloatReg(targetReg));
1125+
// We must load the FP constant from the constant pool
1126+
// Emit a data section constant for the float or double constant.
1127+
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(constValue, size);
11121128

1113-
// Compute the address of the FP constant and load the data.
1114-
emit->emitIns_R_C(size == EA_4BYTE ? INS_flw : INS_fld, size, targetReg, REG_NA, hnd, 0);
1115-
}
1129+
// Compute the address of the FP constant and load the data.
1130+
emit->emitIns_R_C(size == EA_4BYTE ? INS_flw : INS_fld, size, targetReg, REG_NA, hnd, 0);
11161131
}
11171132
break;
11181133

src/coreclr/jit/lsrariscv64.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,22 @@ int LinearScan::BuildNode(GenTree* tree)
143143

144144
case GT_CNS_DBL:
145145
{
146-
// There is no instruction for loading float/double imm directly into FPR.
147-
// Reserve int to load constant from memory (IF_LARGELDC)
148-
buildInternalIntRegisterDefForNode(tree);
149-
buildInternalRegisterUses();
146+
emitAttr size = emitActualTypeSize(tree);
147+
148+
double constValue = tree->AsDblCon()->DconValue();
149+
if (!FloatingPointUtils::isPositiveZero(constValue))
150+
{
151+
int64_t bits =
152+
(size == EA_4BYTE)
153+
? (int32_t)BitOperations::SingleToUInt32Bits(FloatingPointUtils::convertToSingle(constValue))
154+
: (int64_t)BitOperations::DoubleToUInt64Bits(constValue);
155+
bool fitsInLui = ((bits & 0xfff) == 0) && emitter::isValidSimm20(bits >> 12);
156+
if (fitsInLui || emitter::isValidSimm12(bits)) // can we synthesize bits with a single instruction?
157+
{
158+
buildInternalIntRegisterDefForNode(tree);
159+
buildInternalRegisterUses();
160+
}
161+
}
150162
}
151163
FALLTHROUGH;
152164

0 commit comments

Comments
 (0)