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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 } | 421 } |
422 | 422 |
423 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 423 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
424 __ Call(at); | 424 __ Call(at); |
425 AddSafepointAndDeopt(instr); | 425 AddSafepointAndDeopt(instr); |
426 break; | 426 break; |
427 } | 427 } |
428 case kArchJmp: | 428 case kArchJmp: |
429 AssembleArchJump(i.InputRpo(0)); | 429 AssembleArchJump(i.InputRpo(0)); |
430 break; | 430 break; |
431 case kArchSwitch: | 431 case kArchLookupSwitch: |
432 AssembleArchSwitch(instr); | 432 AssembleArchLookupSwitch(instr); |
433 break; | |
434 case kArchTableSwitch: | |
435 AssembleArchTableSwitch(instr); | |
433 break; | 436 break; |
434 case kArchNop: | 437 case kArchNop: |
435 // don't emit code for nops. | 438 // don't emit code for nops. |
436 break; | 439 break; |
437 case kArchRet: | 440 case kArchRet: |
438 AssembleReturn(); | 441 AssembleReturn(); |
439 break; | 442 break; |
440 case kArchStackPointer: | 443 case kArchStackPointer: |
441 __ mov(i.OutputRegister(), sp); | 444 __ mov(i.OutputRegister(), sp); |
442 break; | 445 break; |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
912 UNIMPLEMENTED(); | 915 UNIMPLEMENTED(); |
913 } | 916 } |
914 } | 917 } |
915 | 918 |
916 | 919 |
917 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 920 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
918 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); | 921 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); |
919 } | 922 } |
920 | 923 |
921 | 924 |
922 void CodeGenerator::AssembleArchSwitch(Instruction* instr) { | |
923 MipsOperandConverter i(this, instr); | |
924 int const kNumLabels = static_cast<int>(instr->InputCount() - 1); | |
925 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( | |
926 masm()); | |
927 Label here; | |
928 | |
929 // Ensure that dd-ed labels goes to 8 byte aligned addresses. | |
930 if ((masm()->pc_offset() & 7) == 0) { | |
931 __ nop(); | |
932 } | |
933 __ bal(&here); | |
934 __ nop(); // Branch delay slot nop. | |
935 __ bind(&here); | |
936 __ dsll(at, i.InputRegister(0), 3); | |
937 __ daddu(at, at, ra); | |
938 __ ld(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize)); | |
939 __ jr(at); | |
940 __ nop(); // Branch delay slot nop. | |
941 | |
942 for (int index = 0; index < kNumLabels; ++index) { | |
943 __ dd(GetLabel(i.InputRpo(index + 1))); | |
944 } | |
945 } | |
946 | |
947 | |
948 // Assembles boolean materializations after an instruction. | 925 // Assembles boolean materializations after an instruction. |
949 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 926 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
950 FlagsCondition condition) { | 927 FlagsCondition condition) { |
951 MipsOperandConverter i(this, instr); | 928 MipsOperandConverter i(this, instr); |
952 Label done; | 929 Label done; |
953 | 930 |
954 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 931 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
955 // last output of the instruction. | 932 // last output of the instruction. |
956 Label false_value; | 933 Label false_value; |
957 DCHECK_NE(0u, instr->OutputCount()); | 934 DCHECK_NE(0u, instr->OutputCount()); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 TRACE_UNIMPL(); | 1033 TRACE_UNIMPL(); |
1057 UNIMPLEMENTED(); | 1034 UNIMPLEMENTED(); |
1058 } | 1035 } |
1059 // Fallthru case is the false materialization. | 1036 // Fallthru case is the false materialization. |
1060 __ bind(&false_value); | 1037 __ bind(&false_value); |
1061 __ li(result, Operand(static_cast<int64_t>(0))); | 1038 __ li(result, Operand(static_cast<int64_t>(0))); |
1062 __ bind(&done); | 1039 __ bind(&done); |
1063 } | 1040 } |
1064 | 1041 |
1065 | 1042 |
1043 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { | |
1044 MipsOperandConverter i(this, instr); | |
1045 Register input = i.InputRegister(0); | |
1046 for (size_t index = 2; index < instr->InputCount(); index += 2) { | |
1047 __ Branch(GetLabel(i.InputRpo(index + 1)), eq, input, | |
1048 Operand(i.InputInt32(index + 0))); | |
1049 } | |
1050 AssembleArchJump(i.InputRpo(1)); | |
1051 } | |
1052 | |
1053 | |
1054 void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { | |
1055 MipsOperandConverter i(this, instr); | |
1056 Register input = i.InputRegister(0); | |
1057 size_t const case_count = instr->InputCount() - 2; | |
1058 Label here; | |
1059 | |
1060 __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count)); | |
1061 // Ensure that dd-ed labels goes to 8 byte aligned addresses. | |
paul.l...
2015/02/17 19:33:59
nit: "goes to ... " should probably be "use 8 byte
| |
1062 if ((masm()->pc_offset() & 7) == 0) { | |
1063 __ nop(); | |
1064 } | |
1065 __ bal(&here); | |
paul.l...
2015/02/17 19:33:59
Add BlockTrampolinePoolFor() to cover table and in
| |
1066 __ nop(); // Branch delay slot nop. | |
1067 __ bind(&here); | |
1068 __ dsll(at, input, 3); | |
1069 __ daddu(at, at, ra); | |
1070 __ ld(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize)); | |
1071 __ jr(at); | |
1072 __ nop(); // Branch delay slot nop. | |
1073 for (size_t index = 0; index < case_count; ++index) { | |
1074 __ dd(GetLabel(i.InputRpo(index + 2))); | |
1075 } | |
1076 } | |
1077 | |
1078 | |
1066 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 1079 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
1067 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1080 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1068 isolate(), deoptimization_id, Deoptimizer::LAZY); | 1081 isolate(), deoptimization_id, Deoptimizer::LAZY); |
1069 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1082 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1070 } | 1083 } |
1071 | 1084 |
1072 | 1085 |
1073 void CodeGenerator::AssemblePrologue() { | 1086 void CodeGenerator::AssemblePrologue() { |
1074 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1087 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1075 int stack_slots = frame()->GetSpillSlotCount(); | 1088 int stack_slots = frame()->GetSpillSlotCount(); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1344 } | 1357 } |
1345 } | 1358 } |
1346 MarkLazyDeoptSite(); | 1359 MarkLazyDeoptSite(); |
1347 } | 1360 } |
1348 | 1361 |
1349 #undef __ | 1362 #undef __ |
1350 | 1363 |
1351 } // namespace compiler | 1364 } // namespace compiler |
1352 } // namespace internal | 1365 } // namespace internal |
1353 } // namespace v8 | 1366 } // namespace v8 |
OLD | NEW |