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" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 public: | 156 public: |
157 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 157 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
158 : OutOfLineCode(gen), result_(result) {} | 158 : OutOfLineCode(gen), result_(result) {} |
159 | 159 |
160 void Generate() FINAL { __ mov(result_, zero_reg); } | 160 void Generate() FINAL { __ mov(result_, zero_reg); } |
161 | 161 |
162 private: | 162 private: |
163 Register const result_; | 163 Register const result_; |
164 }; | 164 }; |
165 | 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 __ dsrl(at, kScratchReg, 31); |
| 176 __ dsll(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 |
| 205 |
166 } // namespace | 206 } // namespace |
167 | 207 |
168 | 208 |
169 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ | 209 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
170 do { \ | 210 do { \ |
171 auto result = i.Output##width##Register(); \ | 211 auto result = i.Output##width##Register(); \ |
172 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ | 212 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
173 if (instr->InputAt(0)->IsRegister()) { \ | 213 if (instr->InputAt(0)->IsRegister()) { \ |
174 auto offset = i.InputRegister(0); \ | 214 auto offset = i.InputRegister(0); \ |
175 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ | 215 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } else { \ | 273 } else { \ |
234 auto offset = i.InputOperand(0).immediate(); \ | 274 auto offset = i.InputOperand(0).immediate(); \ |
235 auto value = i.InputRegister(2); \ | 275 auto value = i.InputRegister(2); \ |
236 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 276 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
237 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 277 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
238 } \ | 278 } \ |
239 __ bind(&done); \ | 279 __ bind(&done); \ |
240 } while (0) | 280 } while (0) |
241 | 281 |
242 | 282 |
| 283 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \ |
| 284 do { \ |
| 285 auto ool = \ |
| 286 new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \ |
| 287 Label done; \ |
| 288 __ mfhc1(kScratchReg, i.InputDoubleRegister(0)); \ |
| 289 __ Ext(at, kScratchReg, HeapNumber::kExponentShift, \ |
| 290 HeapNumber::kExponentBits); \ |
| 291 __ Branch(USE_DELAY_SLOT, &done, hs, at, \ |
| 292 Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \ |
| 293 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 294 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 295 __ dmfc1(at, i.OutputDoubleRegister()); \ |
| 296 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 297 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 298 __ bind(ool->exit()); \ |
| 299 __ bind(&done); \ |
| 300 } while (0) |
| 301 |
| 302 |
243 // Assembles an instruction after register allocation, producing machine code. | 303 // Assembles an instruction after register allocation, producing machine code. |
244 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 304 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
245 MipsOperandConverter i(this, instr); | 305 MipsOperandConverter i(this, instr); |
246 InstructionCode opcode = instr->opcode(); | 306 InstructionCode opcode = instr->opcode(); |
247 | 307 |
248 switch (ArchOpcodeField::decode(opcode)) { | 308 switch (ArchOpcodeField::decode(opcode)) { |
249 case kArchCallCodeObject: { | 309 case kArchCallCodeObject: { |
250 EnsureSpaceForLazyDeopt(); | 310 EnsureSpaceForLazyDeopt(); |
251 if (instr->InputAt(0)->IsImmediate()) { | 311 if (instr->InputAt(0)->IsImmediate()) { |
252 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 312 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 FrameScope scope(masm(), StackFrame::MANUAL); | 525 FrameScope scope(masm(), StackFrame::MANUAL); |
466 __ PrepareCallCFunction(0, 2, kScratchReg); | 526 __ PrepareCallCFunction(0, 2, kScratchReg); |
467 __ MovToFloatParameters(i.InputDoubleRegister(0), | 527 __ MovToFloatParameters(i.InputDoubleRegister(0), |
468 i.InputDoubleRegister(1)); | 528 i.InputDoubleRegister(1)); |
469 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 529 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
470 0, 2); | 530 0, 2); |
471 // Move the result in the double result register. | 531 // Move the result in the double result register. |
472 __ MovFromFloatResult(i.OutputDoubleRegister()); | 532 __ MovFromFloatResult(i.OutputDoubleRegister()); |
473 break; | 533 break; |
474 } | 534 } |
475 case kMips64FloorD: { | 535 case kMips64Float64Floor: { |
476 __ floor_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 536 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); |
477 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
478 break; | 537 break; |
479 } | 538 } |
480 case kMips64CeilD: { | 539 case kMips64Float64Ceil: { |
481 __ ceil_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 540 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); |
482 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
483 break; | 541 break; |
484 } | 542 } |
485 case kMips64RoundTruncateD: { | 543 case kMips64Float64RoundTruncate: { |
486 __ trunc_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 544 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); |
487 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
488 break; | 545 break; |
489 } | 546 } |
490 case kMips64SqrtD: { | 547 case kMips64SqrtD: { |
491 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 548 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
492 break; | 549 break; |
493 } | 550 } |
494 case kMips64CvtSD: { | 551 case kMips64CvtSD: { |
495 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); | 552 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); |
496 break; | 553 break; |
497 } | 554 } |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 } | 1435 } |
1379 } | 1436 } |
1380 MarkLazyDeoptSite(); | 1437 MarkLazyDeoptSite(); |
1381 } | 1438 } |
1382 | 1439 |
1383 #undef __ | 1440 #undef __ |
1384 | 1441 |
1385 } // namespace compiler | 1442 } // namespace compiler |
1386 } // namespace internal | 1443 } // namespace internal |
1387 } // namespace v8 | 1444 } // namespace v8 |
OLD | NEW |