OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <limits> |
| 8 |
7 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
8 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 11 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 12 #include "src/compiler/node-matchers.h" |
11 #include "src/compiler/osr.h" | 13 #include "src/compiler/osr.h" |
12 #include "src/wasm/wasm-module.h" | 14 #include "src/wasm/wasm-module.h" |
13 #include "src/x64/assembler-x64.h" | 15 #include "src/x64/assembler-x64.h" |
14 #include "src/x64/macro-assembler-x64.h" | 16 #include "src/x64/macro-assembler-x64.h" |
15 | 17 |
16 namespace v8 { | 18 namespace v8 { |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 int deopt_state_id = | 916 int deopt_state_id = |
915 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 917 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
916 Deoptimizer::BailoutType bailout_type = | 918 Deoptimizer::BailoutType bailout_type = |
917 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); | 919 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); |
918 CodeGenResult result = AssembleDeoptimizerCall( | 920 CodeGenResult result = AssembleDeoptimizerCall( |
919 deopt_state_id, bailout_type, current_source_position_); | 921 deopt_state_id, bailout_type, current_source_position_); |
920 if (result != kSuccess) return result; | 922 if (result != kSuccess) return result; |
921 break; | 923 break; |
922 } | 924 } |
923 case kArchRet: | 925 case kArchRet: |
924 AssembleReturn(); | 926 AssembleReturn(instr->InputAt(0)); |
925 break; | 927 break; |
926 case kArchStackPointer: | 928 case kArchStackPointer: |
927 __ movq(i.OutputRegister(), rsp); | 929 __ movq(i.OutputRegister(), rsp); |
928 break; | 930 break; |
929 case kArchFramePointer: | 931 case kArchFramePointer: |
930 __ movq(i.OutputRegister(), rbp); | 932 __ movq(i.OutputRegister(), rbp); |
931 break; | 933 break; |
932 case kArchParentFramePointer: | 934 case kArchParentFramePointer: |
933 if (frame_access_state()->has_frame()) { | 935 if (frame_access_state()->has_frame()) { |
934 __ movq(i.OutputRegister(), Operand(rbp, 0)); | 936 __ movq(i.OutputRegister(), Operand(rbp, 0)); |
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2443 | 2445 |
2444 const RegList saves = descriptor->CalleeSavedRegisters(); | 2446 const RegList saves = descriptor->CalleeSavedRegisters(); |
2445 if (saves != 0) { // Save callee-saved registers. | 2447 if (saves != 0) { // Save callee-saved registers. |
2446 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 2448 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
2447 if (!((1 << i) & saves)) continue; | 2449 if (!((1 << i) & saves)) continue; |
2448 __ pushq(Register::from_code(i)); | 2450 __ pushq(Register::from_code(i)); |
2449 } | 2451 } |
2450 } | 2452 } |
2451 } | 2453 } |
2452 | 2454 |
2453 | 2455 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
2454 void CodeGenerator::AssembleReturn() { | |
2455 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2456 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2456 | 2457 |
2457 // Restore registers. | 2458 // Restore registers. |
2458 const RegList saves = descriptor->CalleeSavedRegisters(); | 2459 const RegList saves = descriptor->CalleeSavedRegisters(); |
2459 if (saves != 0) { | 2460 if (saves != 0) { |
2460 for (int i = 0; i < Register::kNumRegisters; i++) { | 2461 for (int i = 0; i < Register::kNumRegisters; i++) { |
2461 if (!((1 << i) & saves)) continue; | 2462 if (!((1 << i) & saves)) continue; |
2462 __ popq(Register::from_code(i)); | 2463 __ popq(Register::from_code(i)); |
2463 } | 2464 } |
2464 } | 2465 } |
(...skipping 20 matching lines...) Expand all Loading... |
2485 } else if (frame_access_state()->has_frame()) { | 2486 } else if (frame_access_state()->has_frame()) { |
2486 // Canonicalize JSFunction return sites for now. | 2487 // Canonicalize JSFunction return sites for now. |
2487 if (return_label_.is_bound()) { | 2488 if (return_label_.is_bound()) { |
2488 __ jmp(&return_label_); | 2489 __ jmp(&return_label_); |
2489 return; | 2490 return; |
2490 } else { | 2491 } else { |
2491 __ bind(&return_label_); | 2492 __ bind(&return_label_); |
2492 AssembleDeconstructFrame(); | 2493 AssembleDeconstructFrame(); |
2493 } | 2494 } |
2494 } | 2495 } |
| 2496 // Might need rcx for scratch if pop_size is too big or if there is a variable |
| 2497 // pop count. |
| 2498 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rcx.bit()); |
2495 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; | 2499 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
2496 // Might need rcx for scratch if pop_size is too big. | 2500 X64OperandConverter g(this, nullptr); |
2497 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rcx.bit()); | 2501 if (pop->IsImmediate()) { |
2498 __ Ret(static_cast<int>(pop_size), rcx); | 2502 DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); |
| 2503 pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; |
| 2504 CHECK_LT(pop_size, std::numeric_limits<int>::max()); |
| 2505 __ Ret(static_cast<int>(pop_size), rcx); |
| 2506 } else { |
| 2507 Register reg = g.ToRegister(pop); |
| 2508 __ popq(rcx); |
| 2509 CHECK_LT(pop_size, std::numeric_limits<int>::max()); |
| 2510 __ leaq(rsp, Operand(rsp, reg, times_8, static_cast<int>(pop_size))); |
| 2511 __ jmp(rcx); |
| 2512 } |
2499 } | 2513 } |
2500 | 2514 |
2501 | 2515 |
2502 void CodeGenerator::AssembleMove(InstructionOperand* source, | 2516 void CodeGenerator::AssembleMove(InstructionOperand* source, |
2503 InstructionOperand* destination) { | 2517 InstructionOperand* destination) { |
2504 X64OperandConverter g(this, nullptr); | 2518 X64OperandConverter g(this, nullptr); |
2505 // Dispatch on the source and destination operand kinds. Not all | 2519 // Dispatch on the source and destination operand kinds. Not all |
2506 // combinations are possible. | 2520 // combinations are possible. |
2507 if (source->IsRegister()) { | 2521 if (source->IsRegister()) { |
2508 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 2522 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2770 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2757 __ Nop(padding_size); | 2771 __ Nop(padding_size); |
2758 } | 2772 } |
2759 } | 2773 } |
2760 | 2774 |
2761 #undef __ | 2775 #undef __ |
2762 | 2776 |
2763 } // namespace compiler | 2777 } // namespace compiler |
2764 } // namespace internal | 2778 } // namespace internal |
2765 } // namespace v8 | 2779 } // namespace v8 |
OLD | NEW |