@@ -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
0 commit comments