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/assembler-inl.h" | 8 #include "src/assembler-inl.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 } while (0) | 415 } while (0) |
416 | 416 |
417 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ | 417 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ |
418 do { \ | 418 do { \ |
419 __ dmb(ISH); \ | 419 __ dmb(ISH); \ |
420 __ asm_instr(i.InputRegister(2), \ | 420 __ asm_instr(i.InputRegister(2), \ |
421 MemOperand(i.InputRegister(0), i.InputRegister(1))); \ | 421 MemOperand(i.InputRegister(0), i.InputRegister(1))); \ |
422 __ dmb(ISH); \ | 422 __ dmb(ISH); \ |
423 } while (0) | 423 } while (0) |
424 | 424 |
| 425 #define ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(load_instr, store_instr) \ |
| 426 do { \ |
| 427 Label exchange; \ |
| 428 __ dmb(ISH); \ |
| 429 __ bind(&exchange); \ |
| 430 __ add(i.TempRegister(0), i.InputRegister(0), i.InputRegister(1)); \ |
| 431 __ load_instr(i.OutputRegister(0), i.TempRegister(0)); \ |
| 432 __ store_instr(i.TempRegister(0), i.InputRegister(2), i.TempRegister(0)); \ |
| 433 __ teq(i.TempRegister(0), Operand(0)); \ |
| 434 __ b(ne, &exchange); \ |
| 435 __ dmb(ISH); \ |
| 436 } while (0) |
| 437 |
425 #define ASSEMBLE_IEEE754_BINOP(name) \ | 438 #define ASSEMBLE_IEEE754_BINOP(name) \ |
426 do { \ | 439 do { \ |
427 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ | 440 /* TODO(bmeurer): We should really get rid of this special instruction, */ \ |
428 /* and generate a CallAddress instruction instead. */ \ | 441 /* and generate a CallAddress instruction instead. */ \ |
429 FrameScope scope(masm(), StackFrame::MANUAL); \ | 442 FrameScope scope(masm(), StackFrame::MANUAL); \ |
430 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 443 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
431 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 444 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
432 i.InputDoubleRegister(1)); \ | 445 i.InputDoubleRegister(1)); \ |
433 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 446 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
434 0, 2); \ | 447 0, 2); \ |
(...skipping 1615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2050 | 2063 |
2051 case kAtomicStoreWord8: | 2064 case kAtomicStoreWord8: |
2052 ASSEMBLE_ATOMIC_STORE_INTEGER(strb); | 2065 ASSEMBLE_ATOMIC_STORE_INTEGER(strb); |
2053 break; | 2066 break; |
2054 case kAtomicStoreWord16: | 2067 case kAtomicStoreWord16: |
2055 ASSEMBLE_ATOMIC_STORE_INTEGER(strh); | 2068 ASSEMBLE_ATOMIC_STORE_INTEGER(strh); |
2056 break; | 2069 break; |
2057 case kAtomicStoreWord32: | 2070 case kAtomicStoreWord32: |
2058 ASSEMBLE_ATOMIC_STORE_INTEGER(str); | 2071 ASSEMBLE_ATOMIC_STORE_INTEGER(str); |
2059 break; | 2072 break; |
| 2073 case kAtomicExchangeInt8: |
| 2074 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexb, strexb); |
| 2075 __ sxtb(i.OutputRegister(0), i.OutputRegister(0)); |
| 2076 break; |
| 2077 case kAtomicExchangeUint8: |
| 2078 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexb, strexb); |
| 2079 break; |
| 2080 case kAtomicExchangeInt16: |
| 2081 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); |
| 2082 __ sxth(i.OutputRegister(0), i.OutputRegister(0)); |
| 2083 break; |
| 2084 case kAtomicExchangeUint16: |
| 2085 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrexh, strexh); |
| 2086 break; |
| 2087 case kAtomicExchangeWord32: |
| 2088 ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(ldrex, strex); |
| 2089 break; |
2060 } | 2090 } |
2061 return kSuccess; | 2091 return kSuccess; |
2062 } // NOLINT(readability/fn_size) | 2092 } // NOLINT(readability/fn_size) |
2063 | 2093 |
2064 | 2094 |
2065 // Assembles branches after an instruction. | 2095 // Assembles branches after an instruction. |
2066 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 2096 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
2067 ArmOperandConverter i(this, instr); | 2097 ArmOperandConverter i(this, instr); |
2068 Label* tlabel = branch->true_label; | 2098 Label* tlabel = branch->true_label; |
2069 Label* flabel = branch->false_label; | 2099 Label* flabel = branch->false_label; |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2654 padding_size -= v8::internal::Assembler::kInstrSize; | 2684 padding_size -= v8::internal::Assembler::kInstrSize; |
2655 } | 2685 } |
2656 } | 2686 } |
2657 } | 2687 } |
2658 | 2688 |
2659 #undef __ | 2689 #undef __ |
2660 | 2690 |
2661 } // namespace compiler | 2691 } // namespace compiler |
2662 } // namespace internal | 2692 } // namespace internal |
2663 } // namespace v8 | 2693 } // namespace v8 |
OLD | NEW |