| 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, 20, 11); \ |
| 290 __ Branch(USE_DELAY_SLOT, &done, hs, at, Operand(1075)); \ |
| 291 __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 292 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
| 293 __ dmfc1(at, i.OutputDoubleRegister()); \ |
| 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 |
| 243 // Assembles an instruction after register allocation, producing machine code. | 301 // Assembles an instruction after register allocation, producing machine code. |
| 244 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 302 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 245 MipsOperandConverter i(this, instr); | 303 MipsOperandConverter i(this, instr); |
| 246 InstructionCode opcode = instr->opcode(); | 304 InstructionCode opcode = instr->opcode(); |
| 247 | 305 |
| 248 switch (ArchOpcodeField::decode(opcode)) { | 306 switch (ArchOpcodeField::decode(opcode)) { |
| 249 case kArchCallCodeObject: { | 307 case kArchCallCodeObject: { |
| 250 EnsureSpaceForLazyDeopt(); | 308 EnsureSpaceForLazyDeopt(); |
| 251 if (instr->InputAt(0)->IsImmediate()) { | 309 if (instr->InputAt(0)->IsImmediate()) { |
| 252 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 310 __ 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); | 523 FrameScope scope(masm(), StackFrame::MANUAL); |
| 466 __ PrepareCallCFunction(0, 2, kScratchReg); | 524 __ PrepareCallCFunction(0, 2, kScratchReg); |
| 467 __ MovToFloatParameters(i.InputDoubleRegister(0), | 525 __ MovToFloatParameters(i.InputDoubleRegister(0), |
| 468 i.InputDoubleRegister(1)); | 526 i.InputDoubleRegister(1)); |
| 469 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), | 527 __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), |
| 470 0, 2); | 528 0, 2); |
| 471 // Move the result in the double result register. | 529 // Move the result in the double result register. |
| 472 __ MovFromFloatResult(i.OutputDoubleRegister()); | 530 __ MovFromFloatResult(i.OutputDoubleRegister()); |
| 473 break; | 531 break; |
| 474 } | 532 } |
| 475 case kMips64FloorD: { | 533 case kMips64Float64Floor: { |
| 476 __ floor_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 534 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor); |
| 477 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
| 478 break; | 535 break; |
| 479 } | 536 } |
| 480 case kMips64CeilD: { | 537 case kMips64Float64Ceil: { |
| 481 __ ceil_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 538 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); |
| 482 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
| 483 break; | 539 break; |
| 484 } | 540 } |
| 485 case kMips64RoundTruncateD: { | 541 case kMips64Float64RoundTruncate: { |
| 486 __ trunc_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 542 ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate); |
| 487 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); | |
| 488 break; | 543 break; |
| 489 } | 544 } |
| 490 case kMips64SqrtD: { | 545 case kMips64SqrtD: { |
| 491 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 546 __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 492 break; | 547 break; |
| 493 } | 548 } |
| 494 case kMips64CvtSD: { | 549 case kMips64CvtSD: { |
| 495 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); | 550 __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); |
| 496 break; | 551 break; |
| 497 } | 552 } |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1378 } | 1433 } |
| 1379 } | 1434 } |
| 1380 MarkLazyDeoptSite(); | 1435 MarkLazyDeoptSite(); |
| 1381 } | 1436 } |
| 1382 | 1437 |
| 1383 #undef __ | 1438 #undef __ |
| 1384 | 1439 |
| 1385 } // namespace compiler | 1440 } // namespace compiler |
| 1386 } // namespace internal | 1441 } // namespace internal |
| 1387 } // namespace v8 | 1442 } // namespace v8 |
| OLD | NEW |