@@ -1091,31 +1091,23 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
1091
1091
double constValue = tree->AsDblCon ()->DconValue ();
1092
1092
1093
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)
1096
- if (FloatingPointUtils::isPositiveZero (constValue))
1097
- {
1098
- // A faster/smaller way to generate 0.0
1099
- // We will just zero out the entire register for both float and double
1100
- emit->emitIns_R_R (size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, REG_R0);
1101
- break ;
1102
- }
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?
1094
+ int64_t bits;
1095
+ if (emitter::isSingleInstructionFpImm (constValue, size, &bits))
1110
1096
{
1111
- regNumber temp = internalRegisters. GetSingle (tree) ;
1112
- if (fitsInLui )
1097
+ regNumber temp = REG_ZERO ;
1098
+ if (bits != 0 )
1113
1099
{
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);
1100
+ temp = internalRegisters.GetSingle (tree);
1101
+ if (emitter::isValidSimm12 (bits))
1102
+ {
1103
+ emit->emitIns_R_R_I (INS_addi, size, temp, REG_ZERO, bits);
1104
+ }
1105
+ else
1106
+ {
1107
+ int64_t upperBits = bits >> 12 ;
1108
+ assert ((upperBits << 12 ) == bits);
1109
+ emit->emitIns_R_I (INS_lui, size, temp, upperBits);
1110
+ }
1119
1111
}
1120
1112
1121
1113
emit->emitIns_R_R (size == EA_4BYTE ? INS_fmv_w_x : INS_fmv_d_x, size, targetReg, temp);
@@ -2371,12 +2363,12 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
2371
2363
2372
2364
GenTree* data = treeNode->AsOp ()->gtOp2 ;
2373
2365
GenTree* addr = treeNode->AsOp ()->gtOp1 ;
2374
- regNumber dataReg = data->GetRegNum ();
2366
+ regNumber dataReg = ! data->isContained () ? data-> GetRegNum () : REG_ZERO ;
2375
2367
regNumber addrReg = addr->GetRegNum ();
2376
2368
regNumber targetReg = treeNode->GetRegNum ();
2377
2369
if (targetReg == REG_NA)
2378
2370
{
2379
- targetReg = REG_R0 ;
2371
+ targetReg = REG_ZERO ;
2380
2372
}
2381
2373
2382
2374
genConsumeAddress (addr);
@@ -2385,8 +2377,6 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
2385
2377
emitAttr dataSize = emitActualTypeSize (data);
2386
2378
bool is4 = (dataSize == EA_4BYTE);
2387
2379
2388
- assert (!data->isContainedIntOrIImmed ());
2389
-
2390
2380
instruction ins = INS_none;
2391
2381
switch (treeNode->gtOper )
2392
2382
{
@@ -2407,7 +2397,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
2407
2397
}
2408
2398
GetEmitter ()->emitIns_R_R_R (ins, dataSize, targetReg, addrReg, dataReg);
2409
2399
2410
- if (targetReg != REG_R0 )
2400
+ if (targetReg != REG_ZERO )
2411
2401
{
2412
2402
genProduceReg (treeNode);
2413
2403
}
@@ -2430,9 +2420,19 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
2430
2420
2431
2421
regNumber target = treeNode->GetRegNum ();
2432
2422
regNumber loc = locOp->GetRegNum ();
2433
- regNumber val = valOp->GetRegNum ();
2434
- regNumber comparand = comparandOp->GetRegNum ();
2435
- regNumber storeErr = internalRegisters.Extract (treeNode, RBM_ALLINT);
2423
+ regNumber val = !valOp->isContained () ? valOp->GetRegNum () : REG_ZERO;
2424
+ regNumber comparand = REG_ZERO;
2425
+ if (!comparandOp->isContained ())
2426
+ {
2427
+ comparand = comparandOp->GetRegNum ();
2428
+ if (comparandOp->TypeIs (TYP_INT, TYP_UINT))
2429
+ {
2430
+ regNumber signExtendedComparand = internalRegisters.Extract (treeNode);
2431
+ GetEmitter ()->emitIns_R_R (INS_sext_w, EA_4BYTE, signExtendedComparand, comparand);
2432
+ comparand = signExtendedComparand;
2433
+ }
2434
+ }
2435
+ regNumber storeErr = internalRegisters.GetSingle (treeNode);
2436
2436
2437
2437
// Register allocator should have extended the lifetimes of all input and internal registers
2438
2438
// They should all be different
@@ -2443,16 +2443,12 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
2443
2443
noway_assert (loc != val);
2444
2444
noway_assert (loc != comparand);
2445
2445
noway_assert (loc != storeErr);
2446
- noway_assert (val != comparand);
2446
+ noway_assert (( val != comparand) || (val == REG_ZERO) );
2447
2447
noway_assert (val != storeErr);
2448
2448
noway_assert (comparand != storeErr);
2449
2449
noway_assert (target != REG_NA);
2450
2450
noway_assert (storeErr != REG_NA);
2451
2451
2452
- assert (locOp->isUsedFromReg ());
2453
- assert (valOp->isUsedFromReg ());
2454
- assert (!comparandOp->isUsedFromMemory ());
2455
-
2456
2452
genConsumeAddress (locOp);
2457
2453
genConsumeRegs (valOp);
2458
2454
genConsumeRegs (comparandOp);
0 commit comments