@@ -1090,29 +1090,44 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
1090
1090
emitAttr size = emitActualTypeSize (tree);
1091
1091
double constValue = tree->AsDblCon ()->DconValue ();
1092
1092
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)
1095
1096
if (FloatingPointUtils::isPositiveZero (constValue))
1096
1097
{
1097
1098
// 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
1099
1100
emit->emitIns_R_R (size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, REG_R0);
1101
+ break ;
1100
1102
}
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?
1102
1110
{
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
+ }
1105
1120
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
+ }
1109
1124
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);
1112
1128
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 );
1116
1131
}
1117
1132
break ;
1118
1133
0 commit comments