OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/compilation-info.h" | 8 #include "src/compilation-info.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 __ dmb(ISH); \ | 426 __ dmb(ISH); \ |
427 __ bind(&exchange); \ | 427 __ bind(&exchange); \ |
428 __ add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ | 428 __ add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ |
429 __ load_instr(i.OutputRegister(0), i.TempRegister(0)); \ | 429 __ load_instr(i.OutputRegister(0), i.TempRegister(0)); \ |
430 __ store_instr(i.TempRegister(0), i.InputRegister(2), i.TempRegister(0)); \ | 430 __ store_instr(i.TempRegister(0), i.InputRegister(2), i.TempRegister(0)); \ |
431 __ teq(i.TempRegister(0), Operand(0)); \ | 431 __ teq(i.TempRegister(0), Operand(0)); \ |
432 __ b(ne, &exchange); \ | 432 __ b(ne, &exchange); \ |
433 __ dmb(ISH); \ | 433 __ dmb(ISH); \ |
434 } while (0) | 434 } while (0) |
435 | 435 |
436 #define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(load_instr, store_instr, \ | |
437 mask) \ | |
438 do { \ | |
439 Label compareExchange; \ | |
440 Label exit; \ | |
441 __ dmb(ISH); \ | |
binji
2017/02/28 23:28:53
The optimized code is a bit hard to follow, but th
| |
442 __ bind(&compareExchange); \ | |
443 __ add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ | |
444 __ load_instr(i.OutputRegister(0), i.TempRegister(0)); \ | |
445 __ eor(i.TempRegister(1), i.OutputRegister(0), \ | |
446 Operand(i.InputRegister(2))); \ | |
447 __ And(i.TempRegister(1), i.TempRegister(1), Operand(mask)); \ | |
448 __ teq(i.TempRegister(1), Operand(0)); \ | |
449 __ b(ne, &exit); \ | |
450 __ store_instr(i.TempRegister(0), i.InputRegister(3), i.TempRegister(0)); \ | |
451 __ teq(i.TempRegister(0), Operand(0)); \ | |
452 __ b(ne, &compareExchange); \ | |
453 __ bind(&exit); \ | |
454 __ dmb(ISH); \ | |
455 } while (0) | |
456 | |
436 #define ASSEMBLE_IEEE754_BINOP(name) \ | 457 #define ASSEMBLE_IEEE754_BINOP(name) \ |
437 do { \ | 458 do { \ |
438 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ | 459 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ |
439 /* and generate a CallAddress instruction instead. */ \ | 460 /* and generate a CallAddress instruction instead. */ \ |
440 FrameScope scope(masm(), StackFrame::MANUAL); \ | 461 FrameScope scope(masm(), StackFrame::MANUAL); \ |
441 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 462 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
442 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 463 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
443 i.InputDoubleRegister(1)); \ | 464 i.InputDoubleRegister(1)); \ |
444 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 465 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
445 0, 2); \ | 466 0, 2); \ |
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2032 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); | 2053 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); |
2033 __ sxth(i.OutputRegister(0), i.OutputRegister(0)); | 2054 __ sxth(i.OutputRegister(0), i.OutputRegister(0)); |
2034 break; | 2055 break; |
2035 case kAtomicExchangeUint16: | 2056 case kAtomicExchangeUint16: |
2036 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); | 2057 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); |
2037 __ uxth(i.OutputRegister(0), i.OutputRegister(0)); | 2058 __ uxth(i.OutputRegister(0), i.OutputRegister(0)); |
2038 break; | 2059 break; |
2039 case kAtomicExchangeWord32: | 2060 case kAtomicExchangeWord32: |
2040 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrex, strex); | 2061 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrex, strex); |
2041 break; | 2062 break; |
2063 case kAtomicCompareExchangeInt8: | |
2064 ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexb, strexb, 0x000000ff); | |
2065 __ sxtb(i.OutputRegister(0), i.OutputRegister(0)); | |
2066 break; | |
2067 case kAtomicCompareExchangeUint8: | |
2068 ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexb, strexb, 0x000000ff); | |
2069 __ uxtb(i.OutputRegister(0), i.OutputRegister(0)); | |
2070 break; | |
2071 case kAtomicCompareExchangeInt16: | |
2072 ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexh, strexh, 0x0000ffff); | |
2073 __ sxth(i.OutputRegister(0), i.OutputRegister(0)); | |
2074 break; | |
2075 case kAtomicCompareExchangeUint16: | |
2076 ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrexh, strexh, 0x0000ffff); | |
2077 __ uxth(i.OutputRegister(0), i.OutputRegister(0)); | |
2078 break; | |
2079 case kAtomicCompareExchangeWord32: | |
2080 ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(ldrex, strex, 0xffffffff); | |
2081 break; | |
2042 } | 2082 } |
2043 return kSuccess; | 2083 return kSuccess; |
2044 } // NOLINT(readability/fn_size) | 2084 } // NOLINT(readability/fn_size) |
2045 | 2085 |
2046 | 2086 |
2047 // Assembles branches after an instruction. | 2087 // Assembles branches after an instruction. |
2048 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 2088 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
2049 ArmOperandConverter i(this, instr); | 2089 ArmOperandConverter i(this, instr); |
2050 Label* tlabel = branch->true_label; | 2090 Label* tlabel = branch->true_label; |
2051 Label* flabel = branch->false_label; | 2091 Label* flabel = branch->false_label; |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2636 padding_size -= v8::internal::Assembler::kInstrSize; | 2676 padding_size -= v8::internal::Assembler::kInstrSize; |
2637 } | 2677 } |
2638 } | 2678 } |
2639 } | 2679 } |
2640 | 2680 |
2641 #undef __ | 2681 #undef __ |
2642 | 2682 |
2643 } // namespace compiler | 2683 } // namespace compiler |
2644 } // namespace internal | 2684 } // namespace internal |
2645 } // namespace v8 | 2685 } // namespace v8 |
OLD | NEW |