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/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/mips/macro-assembler-mips.h" | 10 #include "src/mips/macro-assembler-mips.h" |
11 #include "src/scopes.h" | 11 #include "src/scopes.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 #define __ masm()-> | 17 #define __ masm()-> |
18 | 18 |
19 | 19 |
20 // TODO(plind): Possibly avoid using these lithium names. | 20 // TODO(plind): Possibly avoid using these lithium names. |
21 #define kScratchReg kLithiumScratchReg | 21 #define kScratchReg kLithiumScratchReg |
22 #define kCompareReg kLithiumScratchReg2 | 22 #define kCompareReg kLithiumScratchReg2 |
23 #define kScratchReg2 kLithiumScratchReg2 | |
23 #define kScratchDoubleReg kLithiumScratchDouble | 24 #define kScratchDoubleReg kLithiumScratchDouble |
24 | 25 |
25 | 26 |
26 // TODO(plind): consider renaming these macros. | 27 // TODO(plind): consider renaming these macros. |
27 #define TRACE_MSG(msg) \ | 28 #define TRACE_MSG(msg) \ |
28 PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \ | 29 PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \ |
29 __LINE__) | 30 __LINE__) |
30 | 31 |
31 #define TRACE_UNIMPL() \ | 32 #define TRACE_UNIMPL() \ |
32 PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \ | 33 PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \ |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 public: | 156 public: |
156 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 157 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
157 : OutOfLineCode(gen), result_(result) {} | 158 : OutOfLineCode(gen), result_(result) {} |
158 | 159 |
159 void Generate() FINAL { __ mov(result_, zero_reg); } | 160 void Generate() FINAL { __ mov(result_, zero_reg); } |
160 | 161 |
161 private: | 162 private: |
162 Register const result_; | 163 Register const result_; |
163 }; | 164 }; |
164 | 165 |
166 | |
167 class OutOfLineRound : public OutOfLineCode { | |
168 public: | |
169 OutOfLineRound(CodeGenerator* gen, DoubleRegister result) | |
170 : OutOfLineCode(gen), result_(result) {} | |
171 | |
172 void Generate() FINAL { | |
173 // Handle rounding to zero case where sign has to be preserved. | |
174 // High bits of double input already in kScratchReg. | |
175 __ srl(at, kScratchReg, 31); | |
176 __ sll(at, at, 31); | |
177 __ Mthc1(at, result_); | |
178 } | |
179 | |
180 private: | |
181 DoubleRegister const result_; | |
182 }; | |
183 | |
184 | |
185 class OutOfLineTruncate FINAL : public OutOfLineRound { | |
186 public: | |
187 OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result) | |
188 : OutOfLineRound(gen, result) {} | |
189 }; | |
190 | |
191 | |
192 class OutOfLineFloor FINAL : public OutOfLineRound { | |
193 public: | |
194 OutOfLineFloor(CodeGenerator* gen, DoubleRegister result) | |
195 : OutOfLineRound(gen, result) {} | |
196 }; | |
197 | |
198 | |
199 class OutOfLineCeil FINAL : public OutOfLineRound { | |
200 public: | |
201 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) | |
202 : OutOfLineRound(gen, result) {} | |
203 }; | |
204 | |
165 } // namespace | 205 } // namespace |
166 | 206 |
167 | 207 |
168 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | 208 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
169 do { \ | 209 do { \ |
170 auto result = i.Output##width##Register(); \ | 210 auto result = i.Output##width##Register(); \ |
171 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 211 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
172 if (instr->InputAt(0)->IsRegister()) { \ | 212 if (instr->InputAt(0)->IsRegister()) { \ |
173 auto offset = i.InputRegister(0); \ | 213 auto offset = i.InputRegister(0); \ |
174 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 214 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 } else { \ | 272 } else { \ |
233 auto offset = i.InputOperand(0).immediate(); \ | 273 auto offset = i.InputOperand(0).immediate(); \ |
234 auto value = i.InputRegister(2); \ | 274 auto value = i.InputRegister(2); \ |
235 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 275 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
236 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 276 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
237 } \ | 277 } \ |
238 __ bind(&done); \ | 278 __ bind(&done); \ |
239 } while (0) | 279 } while (0) |
240 | 280 |
241 | 281 |
282 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \ | |
283 do { \ | |
284 auto ool = \ | |
285 new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \ | |
286 Label done; \ | |
287 __ Mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ | |
288 __ Ext(at, kScratchReg, 20, 11); \ | |
289 __ Branch(USE_DELAY_SLOT, &done, hs, at, Operand(1075)); \ | |
paul.l...
2014/12/18 18:07:41
Hmmm, would prefer we don't use so many magic numb
dusmil.imgtec
2014/12/22 14:34:49
Done.
| |
290 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | |
291 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | |
292 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ | |
293 __ or_(at, at, kScratchReg2); \ | |
294 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | |
295 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | |
296 __ bind(ool->exit()); \ | |
297 __ bind(&done); \ | |
298 } while (0) | |
299 | |
300 | |
242 // Assembles an instruction after register allocation, producing machine code. | 301 // Assembles an instruction after register allocation, producing machine code. |
243 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 302 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
244 MipsOperandConverter i(this, instr); | 303 MipsOperandConverter i(this, instr); |
245 InstructionCode opcode = instr->opcode(); | 304 InstructionCode opcode = instr->opcode(); |
246 | 305 |
247 switch (ArchOpcodeField::decode(opcode)) { | 306 switch (ArchOpcodeField::decode(opcode)) { |
248 case kArchCallCodeObject: { | 307 case kArchCallCodeObject: { |
249 EnsureSpaceForLazyDeopt(); | 308 EnsureSpaceForLazyDeopt(); |
250 if (instr->InputAt(0)->IsImmediate()) { | 309 if (instr->InputAt(0)->IsImmediate()) { |
251 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 310 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 FrameScope scope(masm(), StackFrame::MANUAL); | 459 FrameScope scope(masm(), StackFrame::MANUAL); |
401 __ PrepareCallCFunction(0, 2, kScratchReg); | 460 __ PrepareCallCFunction(0, 2, kScratchReg); |
402 __ MovToFloatParameters(i.InputDoubleRegister(0), | 461 __ MovToFloatParameters(i.InputDoubleRegister(0), |
403 i.InputDoubleRegister(1)); | 462 i.InputDoubleRegister(1)); |
404 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 463 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
405 0, 2); | 464 0, 2); |
406 // Move the result in the double result register. | 465 // Move the result in the double result register. |
407 __ MovFromFloatResult(i.OutputDoubleRegister()); | 466 __ MovFromFloatResult(i.OutputDoubleRegister()); |
408 break; | 467 break; |
409 } | 468 } |
469 case kMipsFloat64Floor: { | |
470 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); | |
471 break; | |
472 } | |
473 case kMipsFloat64Ceil: { | |
474 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); | |
475 break; | |
476 } | |
477 case kMipsFloat64RoundTruncate: { | |
478 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); | |
479 break; | |
480 } | |
410 case kMipsSqrtD: { | 481 case kMipsSqrtD: { |
411 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 482 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
412 break; | 483 break; |
413 } | 484 } |
414 case kMipsCvtSD: { | 485 case kMipsCvtSD: { |
415 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); | 486 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); |
416 break; | 487 break; |
417 } | 488 } |
418 case kMipsCvtDS: { | 489 case kMipsCvtDS: { |
419 __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0)); | 490 __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0)); |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 } | 1174 } |
1104 } | 1175 } |
1105 MarkLazyDeoptSite(); | 1176 MarkLazyDeoptSite(); |
1106 } | 1177 } |
1107 | 1178 |
1108 #undef __ | 1179 #undef __ |
1109 | 1180 |
1110 } // namespace compiler | 1181 } // namespace compiler |
1111 } // namespace internal | 1182 } // namespace internal |
1112 } // namespace v8 | 1183 } // namespace v8 |
OLD | NEW |