@@ -703,8 +703,8 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
703
703
emitAttr dataSize = emitActualTypeSize (data);
704
704
705
705
regNumber tempReg = treeNode->ExtractTempReg (RBM_ALLINT);
706
- regNumber loadReg = (targetReg != REG_NA ) ? targetReg : treeNode->ExtractTempReg (RBM_ALLINT);
707
- regNumber storeReg = dataReg ;
706
+ regNumber storeReg = (treeNode-> OperGet () == GT_XCHG ) ? dataReg : treeNode->ExtractTempReg (RBM_ALLINT);
707
+ regNumber loadReg = (targetReg != REG_NA) ? targetReg : storeReg ;
708
708
709
709
// Check allocator assumptions
710
710
//
@@ -743,9 +743,6 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
743
743
// bne retry
744
744
// dmb ish
745
745
746
- BasicBlock* labelRetry = genCreateTempLabel ();
747
- genDefineTempLabel (labelRetry);
748
-
749
746
instruction insLd = INS_ldrex;
750
747
instruction insSt = INS_strex;
751
748
if (varTypeIsByte (treeNode->TypeGet ()))
@@ -759,12 +756,16 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
759
756
insSt = INS_strexh;
760
757
}
761
758
759
+ instGen_MemoryBarrier ();
760
+
761
+ BasicBlock* labelRetry = genCreateTempLabel ();
762
+ genDefineTempLabel (labelRetry);
763
+
762
764
// The following instruction includes a acquire half barrier
763
765
GetEmitter ()->emitIns_R_R (insLd, dataSize, loadReg, addrReg);
764
766
765
767
if (treeNode->OperGet () == GT_XADD)
766
768
{
767
- storeReg = loadReg;
768
769
if (data->isContainedIntOrIImmed ())
769
770
{
770
771
genInstrWithConstant (INS_add, dataSize, storeReg, loadReg, data->AsIntConCommon ()->IconValue (),
@@ -864,10 +865,6 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
864
865
// compareFail:
865
866
// dmb ish
866
867
867
- BasicBlock* labelRetry = genCreateTempLabel ();
868
- BasicBlock* labelCompareFail = genCreateTempLabel ();
869
- genDefineTempLabel (labelRetry);
870
-
871
868
instruction insLd = INS_ldrex;
872
869
instruction insSt = INS_strex;
873
870
if (varTypeIsByte (treeNode->TypeGet ()))
@@ -881,20 +878,34 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
881
878
insSt = INS_strexh;
882
879
}
883
880
881
+ instGen_MemoryBarrier ();
882
+
883
+ BasicBlock* labelRetry = genCreateTempLabel ();
884
+ BasicBlock* labelCompareFail = genCreateTempLabel ();
885
+ genDefineTempLabel (labelRetry);
886
+
884
887
// The following instruction includes a acquire half barrier
885
888
GetEmitter ()->emitIns_R_R (insLd, dataSize, targetReg, addrReg);
886
889
887
890
if (comparand->isContainedIntOrIImmed ())
888
891
{
889
- assert (comparand->AsIntConCommon ()->IconValue () <= INT32_MAX);
890
- GetEmitter ()->emitIns_R_I (INS_cmp, EA_4BYTE, targetReg,
891
- (target_ssize_t )comparand->AsIntConCommon ()->IconValue ());
892
+ if (comparand->IsIntegralConst (0 ))
893
+ {
894
+ GetEmitter ()->emitIns_J_R (INS_cbnz, EA_4BYTE, labelCompareFail, targetReg);
895
+ }
896
+ else
897
+ {
898
+ assert (comparand->AsIntConCommon ()->IconValue () <= INT32_MAX);
899
+ GetEmitter ()->emitIns_R_I (INS_cmp, EA_4BYTE, targetReg,
900
+ (target_ssize_t )comparand->AsIntConCommon ()->IconValue ());
901
+ GetEmitter ()->emitIns_J (INS_bne, labelCompareFail);
902
+ }
892
903
}
893
904
else
894
905
{
895
906
GetEmitter ()->emitIns_R_R (INS_cmp, EA_4BYTE, targetReg, comparandReg);
907
+ GetEmitter ()->emitIns_J (INS_bne, labelCompareFail);
896
908
}
897
- GetEmitter ()->emitIns_J (INS_bne, labelCompareFail);
898
909
899
910
// The following instruction includes a release half barrier
900
911
GetEmitter ()->emitIns_R_R_R (insSt, dataSize, exResultReg, dataReg, addrReg);
0 commit comments