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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 UNREACHABLE(); | 99 UNREACHABLE(); |
100 } | 100 } |
101 UNREACHABLE(); | 101 UNREACHABLE(); |
102 return MemOperand(no_reg); | 102 return MemOperand(no_reg); |
103 } | 103 } |
104 | 104 |
105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); } | 105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); } |
106 | 106 |
107 MemOperand ToMemOperand(InstructionOperand* op) const { | 107 MemOperand ToMemOperand(InstructionOperand* op) const { |
108 DCHECK(op != NULL); | 108 DCHECK(op != NULL); |
109 DCHECK(!op->IsRegister()); | |
110 DCHECK(!op->IsDoubleRegister()); | |
111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 109 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
112 // The linkage computes where all spill slots are located. | 110 FrameOffset offset = |
113 FrameOffset offset = linkage()->GetFrameOffset( | 111 linkage()->GetFrameOffset(AllocatedOperand::cast(op)->index(), frame()); |
114 AllocatedOperand::cast(op)->index(), frame(), 0); | |
115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 112 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
116 } | 113 } |
117 }; | 114 }; |
118 | 115 |
119 | 116 |
120 static inline bool HasRegisterInput(Instruction* instr, size_t index) { | 117 static inline bool HasRegisterInput(Instruction* instr, size_t index) { |
121 return instr->InputAt(index)->IsRegister(); | 118 return instr->InputAt(index)->IsRegister(); |
122 } | 119 } |
123 | 120 |
124 | 121 |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1148 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
1152 __ Push(ra, fp); | 1149 __ Push(ra, fp); |
1153 __ mov(fp, sp); | 1150 __ mov(fp, sp); |
1154 | 1151 |
1155 const RegList saves = descriptor->CalleeSavedRegisters(); | 1152 const RegList saves = descriptor->CalleeSavedRegisters(); |
1156 // Save callee-saved registers. | 1153 // Save callee-saved registers. |
1157 __ MultiPush(saves); | 1154 __ MultiPush(saves); |
1158 // kNumCalleeSaved includes the fp register, but the fp register | 1155 // kNumCalleeSaved includes the fp register, but the fp register |
1159 // is saved separately in TF. | 1156 // is saved separately in TF. |
1160 DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves) + 1); | 1157 DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves) + 1); |
1161 int register_save_area_size = kNumCalleeSaved * kPointerSize; | 1158 int register_save_area_size = |
| 1159 base::bits::CountPopulation32(saves) * kPointerSize; |
1162 | 1160 |
1163 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); | 1161 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); |
1164 // Save callee-saved FPU registers. | 1162 // Save callee-saved FPU registers. |
1165 __ MultiPushFPU(saves_fpu); | 1163 __ MultiPushFPU(saves_fpu); |
1166 DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu)); | 1164 DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu)); |
1167 register_save_area_size += kNumCalleeSavedFPU * kDoubleSize * kPointerSize; | 1165 register_save_area_size += kNumCalleeSavedFPU * kDoubleSize; |
1168 | 1166 |
1169 frame()->SetRegisterSaveAreaSize(register_save_area_size); | 1167 frame()->SetRegisterSaveAreaSize(register_save_area_size); |
1170 } else if (descriptor->IsJSFunctionCall()) { | 1168 } else if (descriptor->IsJSFunctionCall()) { |
1171 CompilationInfo* info = this->info(); | 1169 CompilationInfo* info = this->info(); |
1172 __ Prologue(info->IsCodePreAgingActive()); | 1170 __ Prologue(info->IsCodePreAgingActive()); |
1173 frame()->SetRegisterSaveAreaSize( | 1171 frame()->SetRegisterSaveAreaSize( |
1174 StandardFrameConstants::kFixedFrameSizeFromFp); | 1172 StandardFrameConstants::kFixedFrameSizeFromFp); |
1175 } else if (needs_frame_) { | 1173 } else if (needs_frame_) { |
1176 __ StubPrologue(); | 1174 __ StubPrologue(); |
1177 frame()->SetRegisterSaveAreaSize( | 1175 frame()->SetRegisterSaveAreaSize( |
1178 StandardFrameConstants::kFixedFrameSizeFromFp); | 1176 StandardFrameConstants::kFixedFrameSizeFromFp); |
| 1177 } else { |
| 1178 frame()->SetPCOnStack(false); |
1179 } | 1179 } |
1180 | 1180 |
1181 if (info()->is_osr()) { | 1181 if (info()->is_osr()) { |
1182 // TurboFan OSR-compiled functions cannot be entered directly. | 1182 // TurboFan OSR-compiled functions cannot be entered directly. |
1183 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1183 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
1184 | 1184 |
1185 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1185 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
1186 // frame is still on the stack. Optimized code uses OSR values directly from | 1186 // frame is still on the stack. Optimized code uses OSR values directly from |
1187 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1187 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
1188 // remaining stack slots. | 1188 // remaining stack slots. |
1189 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1189 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
1190 osr_pc_offset_ = __ pc_offset(); | 1190 osr_pc_offset_ = __ pc_offset(); |
1191 // TODO(titzer): cannot address target function == local #-1 | 1191 // TODO(titzer): cannot address target function == local #-1 |
1192 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1192 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1193 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); | 1193 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); |
1194 stack_slots -= frame()->GetOsrStackSlotCount(); | 1194 stack_slots -= frame()->GetOsrStackSlotCount(); |
1195 } | 1195 } |
1196 | 1196 |
1197 if (stack_slots > 0) { | 1197 if (stack_slots > 0) { |
1198 __ Dsubu(sp, sp, Operand(stack_slots * kPointerSize)); | 1198 __ Dsubu(sp, sp, Operand(stack_slots * kPointerSize)); |
1199 } | 1199 } |
1200 } | 1200 } |
1201 | 1201 |
1202 | 1202 |
1203 void CodeGenerator::AssembleReturn() { | 1203 void CodeGenerator::AssembleReturn() { |
1204 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1204 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1205 int stack_slots = frame()->GetSpillSlotCount(); | 1205 int stack_slots = frame()->GetSpillSlotCount(); |
| 1206 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
1206 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1207 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
1207 if (frame()->GetRegisterSaveAreaSize() > 0) { | 1208 if (frame()->GetRegisterSaveAreaSize() > 0) { |
1208 // Remove this frame's spill slots first. | 1209 // Remove this frame's spill slots first. |
1209 if (stack_slots > 0) { | 1210 if (stack_slots > 0) { |
1210 __ Daddu(sp, sp, Operand(stack_slots * kPointerSize)); | 1211 __ Daddu(sp, sp, Operand(stack_slots * kPointerSize)); |
1211 } | 1212 } |
1212 // Restore FPU registers. | 1213 // Restore FPU registers. |
1213 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); | 1214 const RegList saves_fpu = descriptor->CalleeSavedFPRegisters(); |
1214 __ MultiPopFPU(saves_fpu); | 1215 __ MultiPopFPU(saves_fpu); |
1215 | 1216 |
1216 // Restore GP registers. | 1217 // Restore GP registers. |
1217 const RegList saves = descriptor->CalleeSavedRegisters(); | 1218 const RegList saves = descriptor->CalleeSavedRegisters(); |
1218 __ MultiPop(saves); | 1219 __ MultiPop(saves); |
1219 } | 1220 } |
1220 __ mov(sp, fp); | 1221 __ mov(sp, fp); |
1221 __ Pop(ra, fp); | 1222 __ Pop(ra, fp); |
1222 __ Ret(); | |
1223 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { | 1223 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { |
1224 // Canonicalize JSFunction return sites for now. | 1224 // Canonicalize JSFunction return sites for now. |
1225 if (return_label_.is_bound()) { | 1225 if (return_label_.is_bound()) { |
1226 __ Branch(&return_label_); | 1226 __ Branch(&return_label_); |
| 1227 return; |
1227 } else { | 1228 } else { |
1228 __ bind(&return_label_); | 1229 __ bind(&return_label_); |
1229 __ mov(sp, fp); | 1230 __ mov(sp, fp); |
1230 __ Pop(ra, fp); | 1231 __ Pop(ra, fp); |
1231 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | |
1232 if (pop_count != 0) { | |
1233 __ DropAndRet(pop_count); | |
1234 } else { | |
1235 __ Ret(); | |
1236 } | |
1237 } | 1232 } |
| 1233 } |
| 1234 if (pop_count != 0) { |
| 1235 __ DropAndRet(pop_count); |
1238 } else { | 1236 } else { |
1239 __ Ret(); | 1237 __ Ret(); |
1240 } | 1238 } |
1241 } | 1239 } |
1242 | 1240 |
1243 | 1241 |
1244 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1242 void CodeGenerator::AssembleMove(InstructionOperand* source, |
1245 InstructionOperand* destination) { | 1243 InstructionOperand* destination) { |
1246 MipsOperandConverter g(this, NULL); | 1244 MipsOperandConverter g(this, NULL); |
1247 // Dispatch on the source and destination operand kinds. Not all | 1245 // Dispatch on the source and destination operand kinds. Not all |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 } | 1443 } |
1446 } | 1444 } |
1447 } | 1445 } |
1448 } | 1446 } |
1449 | 1447 |
1450 #undef __ | 1448 #undef __ |
1451 | 1449 |
1452 } // namespace compiler | 1450 } // namespace compiler |
1453 } // namespace internal | 1451 } // namespace internal |
1454 } // namespace v8 | 1452 } // namespace v8 |
OLD | NEW |