Index: src/compiler/arm64/code-generator-arm64.cc |
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc |
index 46b2dbdf469600a01ce54a344f9a3e932d0c7c27..45bb5b897cff0e9c0d6ea1c0fb88a0f2255b8de7 100644 |
--- a/src/compiler/arm64/code-generator-arm64.cc |
+++ b/src/compiler/arm64/code-generator-arm64.cc |
@@ -99,7 +99,9 @@ class Arm64OperandConverter final : public InstructionOperandConverter { |
Register OutputRegister32() { return ToRegister(instr_->Output()).W(); } |
- Register TempRegister32() { return ToRegister(instr_->TempAt(0)).W(); } |
+ Register TempRegister32(size_t index) { |
+ return ToRegister(instr_->TempAt(index)).W(); |
+ } |
Operand InputOperand2_32(size_t index) { |
switch (AddressingModeField::decode(instr_->opcode())) { |
@@ -535,9 +537,26 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { |
__ bind(&exchange); \ |
__ Add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ |
__ load_instr(i.OutputRegister32(), i.TempRegister(0)); \ |
- __ store_instr(i.TempRegister32(), i.InputRegister32(2), \ |
+ __ store_instr(i.TempRegister32(0), i.InputRegister32(2), \ |
i.TempRegister(0)); \ |
- __ cbnz(i.TempRegister32(), &exchange); \ |
+ __ cbnz(i.TempRegister32(0), &exchange); \ |
+ } while (0) |
+ |
+#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(load_instr, store_instr, \ |
+ mask) \ |
+ do { \ |
+ Label compareExchange; \ |
+ Label exit; \ |
+ __ bind(&compareExchange); \ |
+ __ Add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ |
+ __ load_instr(i.OutputRegister32(), i.TempRegister(0)); \ |
+ __ eor(i.TempRegister32(1), i.OutputRegister32(), i.InputRegister32(2)); \ |
+ __ And(i.TempRegister32(1), i.TempRegister32(1), Operand(mask)); \ |
+ __ cbnz(i.TempRegister32(1), &exit); \ |
+ __ store_instr(i.TempRegister32(0), i.InputRegister32(3), \ |
+ i.TempRegister(0)); \ |
+ __ cbnz(i.TempRegister32(0), &compareExchange); \ |
+ __ bind(&exit); \ |
} while (0) |
#define ASSEMBLE_IEEE754_BINOP(name) \ |
@@ -1663,6 +1682,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
case kAtomicExchangeWord32: |
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldaxr, stlxr); |
break; |
+ case kAtomicCompareExchangeInt8: |
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldaxrb, stlxrb, 0x000000ff); |
+ __ Sxtb(i.OutputRegister(0), i.OutputRegister(0)); |
+ break; |
+ case kAtomicCompareExchangeUint8: |
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldaxrb, stlxrb, 0x000000ff); |
+ __ Uxtb(i.OutputRegister(0), i.OutputRegister(0)); |
+ break; |
+ case kAtomicCompareExchangeInt16: |
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldaxrh, stlxrh, 0x0000ffff); |
+ __ Sxth(i.OutputRegister(0), i.OutputRegister(0)); |
+ break; |
+ case kAtomicCompareExchangeUint16: |
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldaxrh, stlxrh, 0x0000ffff); |
+ __ Uxth(i.OutputRegister(0), i.OutputRegister(0)); |
+ break; |
+ case kAtomicCompareExchangeWord32: |
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldaxr, stlxr, 0xffffffff); |
+ break; |
} |
return kSuccess; |
} // NOLINT(readability/fn_size) |