OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 int deopt_state_id = | 985 int deopt_state_id = |
986 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 986 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
987 Deoptimizer::BailoutType bailout_type = | 987 Deoptimizer::BailoutType bailout_type = |
988 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); | 988 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); |
989 CodeGenResult result = AssembleDeoptimizerCall( | 989 CodeGenResult result = AssembleDeoptimizerCall( |
990 deopt_state_id, bailout_type, current_source_position_); | 990 deopt_state_id, bailout_type, current_source_position_); |
991 if (result != kSuccess) return result; | 991 if (result != kSuccess) return result; |
992 break; | 992 break; |
993 } | 993 } |
994 case kArchRet: | 994 case kArchRet: |
995 AssembleReturn(); | 995 AssembleReturn(instr->InputAt(0)); |
996 break; | 996 break; |
997 case kArchStackPointer: | 997 case kArchStackPointer: |
998 __ LoadRR(i.OutputRegister(), sp); | 998 __ LoadRR(i.OutputRegister(), sp); |
999 break; | 999 break; |
1000 case kArchFramePointer: | 1000 case kArchFramePointer: |
1001 __ LoadRR(i.OutputRegister(), fp); | 1001 __ LoadRR(i.OutputRegister(), fp); |
1002 break; | 1002 break; |
1003 case kArchParentFramePointer: | 1003 case kArchParentFramePointer: |
1004 if (frame_access_state()->has_frame()) { | 1004 if (frame_access_state()->has_frame()) { |
1005 __ LoadP(i.OutputRegister(), MemOperand(fp, 0)); | 1005 __ LoadP(i.OutputRegister(), MemOperand(fp, 0)); |
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 } | 2291 } |
2292 | 2292 |
2293 // Save callee-saved registers. | 2293 // Save callee-saved registers. |
2294 const RegList saves = descriptor->CalleeSavedRegisters(); | 2294 const RegList saves = descriptor->CalleeSavedRegisters(); |
2295 if (saves != 0) { | 2295 if (saves != 0) { |
2296 __ MultiPush(saves); | 2296 __ MultiPush(saves); |
2297 // register save area does not include the fp or constant pool pointer. | 2297 // register save area does not include the fp or constant pool pointer. |
2298 } | 2298 } |
2299 } | 2299 } |
2300 | 2300 |
2301 void CodeGenerator::AssembleReturn() { | 2301 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
2302 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 2302 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
2303 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 2303 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
2304 | 2304 |
2305 // Restore registers. | 2305 // Restore registers. |
2306 const RegList saves = descriptor->CalleeSavedRegisters(); | 2306 const RegList saves = descriptor->CalleeSavedRegisters(); |
2307 if (saves != 0) { | 2307 if (saves != 0) { |
2308 __ MultiPop(saves); | 2308 __ MultiPop(saves); |
2309 } | 2309 } |
2310 | 2310 |
2311 // Restore double registers. | 2311 // Restore double registers. |
2312 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | 2312 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
2313 if (double_saves != 0) { | 2313 if (double_saves != 0) { |
2314 __ MultiPopDoubles(double_saves); | 2314 __ MultiPopDoubles(double_saves); |
2315 } | 2315 } |
2316 | 2316 |
| 2317 S390OperandConverter g(this, nullptr); |
2317 if (descriptor->IsCFunctionCall()) { | 2318 if (descriptor->IsCFunctionCall()) { |
2318 AssembleDeconstructFrame(); | 2319 AssembleDeconstructFrame(); |
2319 } else if (frame_access_state()->has_frame()) { | 2320 } else if (frame_access_state()->has_frame()) { |
2320 // Canonicalize JSFunction return sites for now. | 2321 // Canonicalize JSFunction return sites for now unless they have an variable |
2321 if (return_label_.is_bound()) { | 2322 // number of stack slot pops |
2322 __ b(&return_label_); | 2323 if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) { |
2323 return; | 2324 if (return_label_.is_bound()) { |
| 2325 __ b(&return_label_); |
| 2326 return; |
| 2327 } else { |
| 2328 __ bind(&return_label_); |
| 2329 AssembleDeconstructFrame(); |
| 2330 } |
2324 } else { | 2331 } else { |
2325 __ bind(&return_label_); | |
2326 AssembleDeconstructFrame(); | 2332 AssembleDeconstructFrame(); |
2327 } | 2333 } |
2328 } | 2334 } |
2329 __ Ret(pop_count); | 2335 if (pop->IsImmediate()) { |
| 2336 DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); |
| 2337 pop_count += g.ToConstant(pop).ToInt32(); |
| 2338 } else { |
| 2339 __ Drop(g.ToRegister(pop)); |
| 2340 } |
| 2341 __ Drop(pop_count); |
| 2342 __ Ret(); |
2330 } | 2343 } |
2331 | 2344 |
2332 void CodeGenerator::AssembleMove(InstructionOperand* source, | 2345 void CodeGenerator::AssembleMove(InstructionOperand* source, |
2333 InstructionOperand* destination) { | 2346 InstructionOperand* destination) { |
2334 S390OperandConverter g(this, nullptr); | 2347 S390OperandConverter g(this, nullptr); |
2335 // Dispatch on the source and destination operand kinds. Not all | 2348 // Dispatch on the source and destination operand kinds. Not all |
2336 // combinations are possible. | 2349 // combinations are possible. |
2337 if (source->IsRegister()) { | 2350 if (source->IsRegister()) { |
2338 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 2351 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
2339 Register src = g.ToRegister(source); | 2352 Register src = g.ToRegister(source); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2560 padding_size -= 2; | 2573 padding_size -= 2; |
2561 } | 2574 } |
2562 } | 2575 } |
2563 } | 2576 } |
2564 | 2577 |
2565 #undef __ | 2578 #undef __ |
2566 | 2579 |
2567 } // namespace compiler | 2580 } // namespace compiler |
2568 } // namespace internal | 2581 } // namespace internal |
2569 } // namespace v8 | 2582 } // namespace v8 |
OLD | NEW |