Chromium Code Reviews| Index: src/compiler/arm/code-generator-arm.cc |
| diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc |
| index 7ae9ded68b5ea5a1d3ad629f8c0d81a86c2c972e..bc3356f2fe4aa33dfe97b27d567899bcec4aa1b6 100644 |
| --- a/src/compiler/arm/code-generator-arm.cc |
| +++ b/src/compiler/arm/code-generator-arm.cc |
| @@ -433,6 +433,27 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { |
| __ dmb(ISH); \ |
| } while (0) |
| +#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(load_instr, store_instr, \ |
| + mask) \ |
| + do { \ |
| + Label compareExchange; \ |
| + Label exit; \ |
| + __ dmb(ISH); \ |
|
binji
2017/02/28 23:28:53
The optimized code is a bit hard to follow, but th
|
| + __ bind(&compareExchange); \ |
| + __ add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ |
| + __ load_instr(i.OutputRegister(0), i.TempRegister(0)); \ |
| + __ eor(i.TempRegister(1), i.OutputRegister(0), \ |
| + Operand(i.InputRegister(2))); \ |
| + __ And(i.TempRegister(1), i.TempRegister(1), Operand(mask)); \ |
| + __ teq(i.TempRegister(1), Operand(0)); \ |
| + __ b(ne, &exit); \ |
| + __ store_instr(i.TempRegister(0), i.InputRegister(3), i.TempRegister(0)); \ |
| + __ teq(i.TempRegister(0), Operand(0)); \ |
| + __ b(ne, &compareExchange); \ |
| + __ bind(&exit); \ |
| + __ dmb(ISH); \ |
| + } while (0) |
| + |
| #define ASSEMBLE_IEEE754_BINOP(name) \ |
| do { \ |
| /* TODO(bmeurer): We should really get rid of this special instruction, */ \ |
| @@ -2039,6 +2060,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| case kAtomicExchangeWord32: |
| ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrex, strex); |
| break; |
| + case kAtomicCompareExchangeInt8: |
| + ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexb, strexb, 0x000000ff); |
| + __ sxtb(i.OutputRegister(0), i.OutputRegister(0)); |
| + break; |
| + case kAtomicCompareExchangeUint8: |
| + ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexb, strexb, 0x000000ff); |
| + __ uxtb(i.OutputRegister(0), i.OutputRegister(0)); |
| + break; |
| + case kAtomicCompareExchangeInt16: |
| + ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexh, strexh, 0x0000ffff); |
| + __ sxth(i.OutputRegister(0), i.OutputRegister(0)); |
| + break; |
| + case kAtomicCompareExchangeUint16: |
| + ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexh, strexh, 0x0000ffff); |
| + __ uxth(i.OutputRegister(0), i.OutputRegister(0)); |
| + break; |
| + case kAtomicCompareExchangeWord32: |
| + ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrex, strex, 0xffffffff); |
| + break; |
| } |
| return kSuccess; |
| } // NOLINT(readability/fn_size) |