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 #include "src/compiler/code-generator-impl.h" | 6 #include "src/compiler/code-generator-impl.h" |
7 #include "src/compiler/gap-resolver.h" | 7 #include "src/compiler/gap-resolver.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/mips/macro-assembler-mips.h" | 9 #include "src/mips/macro-assembler-mips.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 387 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
388 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ | 388 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ |
389 __ or_(at, at, kScratchReg2); \ | 389 __ or_(at, at, kScratchReg2); \ |
390 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | 390 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
391 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | 391 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
392 __ bind(ool->exit()); \ | 392 __ bind(ool->exit()); \ |
393 __ bind(&done); \ | 393 __ bind(&done); \ |
394 } while (0) | 394 } while (0) |
395 | 395 |
396 | 396 |
| 397 void CodeGenerator::AssembleDeconstructActivationRecord() { |
| 398 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 399 int stack_slots = frame()->GetSpillSlotCount(); |
| 400 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
| 401 __ mov(sp, fp); |
| 402 __ Pop(ra, fp); |
| 403 int pop_count = descriptor->IsJSFunctionCall() |
| 404 ? static_cast<int>(descriptor->JSParameterCount()) |
| 405 : 0; |
| 406 __ Drop(pop_count); |
| 407 } |
| 408 } |
| 409 |
| 410 |
397 // Assembles an instruction after register allocation, producing machine code. | 411 // Assembles an instruction after register allocation, producing machine code. |
398 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 412 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
399 MipsOperandConverter i(this, instr); | 413 MipsOperandConverter i(this, instr); |
400 InstructionCode opcode = instr->opcode(); | 414 InstructionCode opcode = instr->opcode(); |
401 | 415 |
402 switch (ArchOpcodeField::decode(opcode)) { | 416 switch (ArchOpcodeField::decode(opcode)) { |
403 case kArchCallCodeObject: { | 417 case kArchCallCodeObject: { |
404 EnsureSpaceForLazyDeopt(); | 418 EnsureSpaceForLazyDeopt(); |
405 if (instr->InputAt(0)->IsImmediate()) { | 419 if (instr->InputAt(0)->IsImmediate()) { |
406 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 420 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
407 RelocInfo::CODE_TARGET); | 421 RelocInfo::CODE_TARGET); |
408 } else { | 422 } else { |
409 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); | 423 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); |
410 __ Call(at); | 424 __ Call(at); |
411 } | 425 } |
412 RecordCallPosition(instr); | 426 RecordCallPosition(instr); |
413 break; | 427 break; |
414 } | 428 } |
| 429 case kArchTailCallCodeObject: { |
| 430 AssembleDeconstructActivationRecord(); |
| 431 if (instr->InputAt(0)->IsImmediate()) { |
| 432 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), |
| 433 RelocInfo::CODE_TARGET); |
| 434 } else { |
| 435 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); |
| 436 __ Jump(at); |
| 437 } |
| 438 break; |
| 439 } |
415 case kArchCallJSFunction: { | 440 case kArchCallJSFunction: { |
416 EnsureSpaceForLazyDeopt(); | 441 EnsureSpaceForLazyDeopt(); |
417 Register func = i.InputRegister(0); | 442 Register func = i.InputRegister(0); |
418 if (FLAG_debug_code) { | 443 if (FLAG_debug_code) { |
419 // Check the function's context matches the context argument. | 444 // Check the function's context matches the context argument. |
420 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); | 445 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); |
421 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); | 446 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); |
422 } | 447 } |
423 | 448 |
424 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 449 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
425 __ Call(at); | 450 __ Call(at); |
426 RecordCallPosition(instr); | 451 RecordCallPosition(instr); |
427 break; | 452 break; |
428 } | 453 } |
| 454 case kArchTailCallJSFunction: { |
| 455 Register func = i.InputRegister(0); |
| 456 if (FLAG_debug_code) { |
| 457 // Check the function's context matches the context argument. |
| 458 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); |
| 459 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); |
| 460 } |
| 461 |
| 462 AssembleDeconstructActivationRecord(); |
| 463 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
| 464 __ Jump(at); |
| 465 break; |
| 466 } |
429 case kArchJmp: | 467 case kArchJmp: |
430 AssembleArchJump(i.InputRpo(0)); | 468 AssembleArchJump(i.InputRpo(0)); |
431 break; | 469 break; |
432 case kArchLookupSwitch: | 470 case kArchLookupSwitch: |
433 AssembleArchLookupSwitch(instr); | 471 AssembleArchLookupSwitch(instr); |
434 break; | 472 break; |
435 case kArchTableSwitch: | 473 case kArchTableSwitch: |
436 AssembleArchTableSwitch(instr); | 474 AssembleArchTableSwitch(instr); |
437 break; | 475 break; |
438 case kArchNop: | 476 case kArchNop: |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 } | 1337 } |
1300 } | 1338 } |
1301 MarkLazyDeoptSite(); | 1339 MarkLazyDeoptSite(); |
1302 } | 1340 } |
1303 | 1341 |
1304 #undef __ | 1342 #undef __ |
1305 | 1343 |
1306 } // namespace compiler | 1344 } // namespace compiler |
1307 } // namespace internal | 1345 } // namespace internal |
1308 } // namespace v8 | 1346 } // namespace v8 |
OLD | NEW |