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/compilation-info.h" | 6 #include "src/compilation-info.h" |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 FloatRegister InputSingleRegister(size_t index) { | 47 FloatRegister InputSingleRegister(size_t index) { |
48 return ToSingleRegister(instr_->InputAt(index)); | 48 return ToSingleRegister(instr_->InputAt(index)); |
49 } | 49 } |
50 | 50 |
51 FloatRegister ToSingleRegister(InstructionOperand* op) { | 51 FloatRegister ToSingleRegister(InstructionOperand* op) { |
52 // Single (Float) and Double register namespace is same on MIPS, | 52 // Single (Float) and Double register namespace is same on MIPS, |
53 // both are typedefs of FPURegister. | 53 // both are typedefs of FPURegister. |
54 return ToDoubleRegister(op); | 54 return ToDoubleRegister(op); |
55 } | 55 } |
56 | 56 |
| 57 Register InputOrZeroRegister(size_t index) { |
| 58 if (instr_->InputAt(index)->IsImmediate()) { |
| 59 DCHECK((InputInt32(index) == 0)); |
| 60 return zero_reg; |
| 61 } |
| 62 return InputRegister(index); |
| 63 } |
| 64 |
57 DoubleRegister InputOrZeroDoubleRegister(size_t index) { | 65 DoubleRegister InputOrZeroDoubleRegister(size_t index) { |
58 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; | 66 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; |
59 | 67 |
60 return InputDoubleRegister(index); | 68 return InputDoubleRegister(index); |
61 } | 69 } |
62 | 70 |
63 DoubleRegister InputOrZeroSingleRegister(size_t index) { | 71 DoubleRegister InputOrZeroSingleRegister(size_t index) { |
64 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; | 72 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; |
65 | 73 |
66 return InputSingleRegister(index); | 74 return InputSingleRegister(index); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 __ addu(kScratchReg, i.InputRegister(2), offset); \ | 382 __ addu(kScratchReg, i.InputRegister(2), offset); \ |
375 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ | 383 __ asm_instr(result, MemOperand(kScratchReg, 0)); \ |
376 } else { \ | 384 } else { \ |
377 auto offset = i.InputOperand(0).immediate(); \ | 385 auto offset = i.InputOperand(0).immediate(); \ |
378 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ | 386 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ |
379 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | 387 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
380 } \ | 388 } \ |
381 __ bind(ool->exit()); \ | 389 __ bind(ool->exit()); \ |
382 } while (0) | 390 } while (0) |
383 | 391 |
384 | |
385 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ | 392 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ |
386 do { \ | 393 do { \ |
387 Label done; \ | 394 Label done; \ |
388 if (instr->InputAt(0)->IsRegister()) { \ | 395 if (instr->InputAt(0)->IsRegister()) { \ |
389 auto offset = i.InputRegister(0); \ | 396 auto offset = i.InputRegister(0); \ |
390 auto value = i.Input##width##Register(2); \ | 397 auto value = i.InputOrZero##width##Register(2); \ |
| 398 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 399 __ Move(kDoubleRegZero, 0.0); \ |
| 400 } \ |
391 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 401 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
392 __ addu(kScratchReg, i.InputRegister(3), offset); \ | 402 __ addu(kScratchReg, i.InputRegister(3), offset); \ |
393 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 403 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
394 } else { \ | 404 } else { \ |
395 auto offset = i.InputOperand(0).immediate(); \ | 405 auto offset = i.InputOperand(0).immediate(); \ |
396 auto value = i.Input##width##Register(2); \ | 406 auto value = i.InputOrZero##width##Register(2); \ |
| 407 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 408 __ Move(kDoubleRegZero, 0.0); \ |
| 409 } \ |
397 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 410 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
398 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 411 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
399 } \ | 412 } \ |
400 __ bind(&done); \ | 413 __ bind(&done); \ |
401 } while (0) | 414 } while (0) |
402 | 415 |
403 | |
404 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 416 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
405 do { \ | 417 do { \ |
406 Label done; \ | 418 Label done; \ |
407 if (instr->InputAt(0)->IsRegister()) { \ | 419 if (instr->InputAt(0)->IsRegister()) { \ |
408 auto offset = i.InputRegister(0); \ | 420 auto offset = i.InputRegister(0); \ |
409 auto value = i.InputRegister(2); \ | 421 auto value = i.InputOrZeroRegister(2); \ |
410 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 422 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
411 __ addu(kScratchReg, i.InputRegister(3), offset); \ | 423 __ addu(kScratchReg, i.InputRegister(3), offset); \ |
412 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 424 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
413 } else { \ | 425 } else { \ |
414 auto offset = i.InputOperand(0).immediate(); \ | 426 auto offset = i.InputOperand(0).immediate(); \ |
415 auto value = i.InputRegister(2); \ | 427 auto value = i.InputOrZeroRegister(2); \ |
416 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 428 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
417 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 429 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
418 } \ | 430 } \ |
419 __ bind(&done); \ | 431 __ bind(&done); \ |
420 } while (0) | 432 } while (0) |
421 | 433 |
422 | |
423 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ | 434 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ |
424 if (IsMipsArchVariant(kMips32r6)) { \ | 435 if (IsMipsArchVariant(kMips32r6)) { \ |
425 __ cfc1(kScratchReg, FCSR); \ | 436 __ cfc1(kScratchReg, FCSR); \ |
426 __ li(at, Operand(mode_##mode)); \ | 437 __ li(at, Operand(mode_##mode)); \ |
427 __ ctc1(at, FCSR); \ | 438 __ ctc1(at, FCSR); \ |
428 __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ | 439 __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ |
429 __ ctc1(kScratchReg, FCSR); \ | 440 __ ctc1(kScratchReg, FCSR); \ |
430 } else { \ | 441 } else { \ |
431 auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister()); \ | 442 auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister()); \ |
432 Label done; \ | 443 Label done; \ |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 __ bind(ool->exit()); \ | 482 __ bind(ool->exit()); \ |
472 __ bind(&done); \ | 483 __ bind(&done); \ |
473 } | 484 } |
474 | 485 |
475 #define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \ | 486 #define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \ |
476 do { \ | 487 do { \ |
477 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ | 488 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ |
478 __ sync(); \ | 489 __ sync(); \ |
479 } while (0) | 490 } while (0) |
480 | 491 |
481 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ | 492 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ |
482 do { \ | 493 do { \ |
483 __ sync(); \ | 494 __ sync(); \ |
484 __ asm_instr(i.InputRegister(2), i.MemoryOperand()); \ | 495 __ asm_instr(i.InputOrZeroRegister(2), i.MemoryOperand()); \ |
485 __ sync(); \ | 496 __ sync(); \ |
486 } while (0) | 497 } while (0) |
487 | 498 |
488 #define ASSEMBLE_IEEE754_BINOP(name) \ | 499 #define ASSEMBLE_IEEE754_BINOP(name) \ |
489 do { \ | 500 do { \ |
490 FrameScope scope(masm(), StackFrame::MANUAL); \ | 501 FrameScope scope(masm(), StackFrame::MANUAL); \ |
491 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 502 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
492 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 503 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
493 i.InputDoubleRegister(1)); \ | 504 i.InputDoubleRegister(1)); \ |
494 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 505 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
495 0, 2); \ | 506 0, 2); \ |
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 case kMipsSeh: | 1406 case kMipsSeh: |
1396 __ Seh(i.OutputRegister(), i.InputRegister(0)); | 1407 __ Seh(i.OutputRegister(), i.InputRegister(0)); |
1397 break; | 1408 break; |
1398 case kMipsLbu: | 1409 case kMipsLbu: |
1399 __ lbu(i.OutputRegister(), i.MemoryOperand()); | 1410 __ lbu(i.OutputRegister(), i.MemoryOperand()); |
1400 break; | 1411 break; |
1401 case kMipsLb: | 1412 case kMipsLb: |
1402 __ lb(i.OutputRegister(), i.MemoryOperand()); | 1413 __ lb(i.OutputRegister(), i.MemoryOperand()); |
1403 break; | 1414 break; |
1404 case kMipsSb: | 1415 case kMipsSb: |
1405 __ sb(i.InputRegister(2), i.MemoryOperand()); | 1416 __ sb(i.InputOrZeroRegister(2), i.MemoryOperand()); |
1406 break; | 1417 break; |
1407 case kMipsLhu: | 1418 case kMipsLhu: |
1408 __ lhu(i.OutputRegister(), i.MemoryOperand()); | 1419 __ lhu(i.OutputRegister(), i.MemoryOperand()); |
1409 break; | 1420 break; |
1410 case kMipsUlhu: | 1421 case kMipsUlhu: |
1411 __ Ulhu(i.OutputRegister(), i.MemoryOperand()); | 1422 __ Ulhu(i.OutputRegister(), i.MemoryOperand()); |
1412 break; | 1423 break; |
1413 case kMipsLh: | 1424 case kMipsLh: |
1414 __ lh(i.OutputRegister(), i.MemoryOperand()); | 1425 __ lh(i.OutputRegister(), i.MemoryOperand()); |
1415 break; | 1426 break; |
1416 case kMipsUlh: | 1427 case kMipsUlh: |
1417 __ Ulh(i.OutputRegister(), i.MemoryOperand()); | 1428 __ Ulh(i.OutputRegister(), i.MemoryOperand()); |
1418 break; | 1429 break; |
1419 case kMipsSh: | 1430 case kMipsSh: |
1420 __ sh(i.InputRegister(2), i.MemoryOperand()); | 1431 __ sh(i.InputOrZeroRegister(2), i.MemoryOperand()); |
1421 break; | 1432 break; |
1422 case kMipsUsh: | 1433 case kMipsUsh: |
1423 __ Ush(i.InputRegister(2), i.MemoryOperand(), kScratchReg); | 1434 __ Ush(i.InputOrZeroRegister(2), i.MemoryOperand(), kScratchReg); |
1424 break; | 1435 break; |
1425 case kMipsLw: | 1436 case kMipsLw: |
1426 __ lw(i.OutputRegister(), i.MemoryOperand()); | 1437 __ lw(i.OutputRegister(), i.MemoryOperand()); |
1427 break; | 1438 break; |
1428 case kMipsUlw: | 1439 case kMipsUlw: |
1429 __ Ulw(i.OutputRegister(), i.MemoryOperand()); | 1440 __ Ulw(i.OutputRegister(), i.MemoryOperand()); |
1430 break; | 1441 break; |
1431 case kMipsSw: | 1442 case kMipsSw: |
1432 __ sw(i.InputRegister(2), i.MemoryOperand()); | 1443 __ sw(i.InputOrZeroRegister(2), i.MemoryOperand()); |
1433 break; | 1444 break; |
1434 case kMipsUsw: | 1445 case kMipsUsw: |
1435 __ Usw(i.InputRegister(2), i.MemoryOperand()); | 1446 __ Usw(i.InputOrZeroRegister(2), i.MemoryOperand()); |
1436 break; | 1447 break; |
1437 case kMipsLwc1: { | 1448 case kMipsLwc1: { |
1438 __ lwc1(i.OutputSingleRegister(), i.MemoryOperand()); | 1449 __ lwc1(i.OutputSingleRegister(), i.MemoryOperand()); |
1439 break; | 1450 break; |
1440 } | 1451 } |
1441 case kMipsUlwc1: { | 1452 case kMipsUlwc1: { |
1442 __ Ulwc1(i.OutputSingleRegister(), i.MemoryOperand(), kScratchReg); | 1453 __ Ulwc1(i.OutputSingleRegister(), i.MemoryOperand(), kScratchReg); |
1443 break; | 1454 break; |
1444 } | 1455 } |
1445 case kMipsSwc1: { | 1456 case kMipsSwc1: { |
1446 size_t index = 0; | 1457 size_t index = 0; |
1447 MemOperand operand = i.MemoryOperand(&index); | 1458 MemOperand operand = i.MemoryOperand(&index); |
1448 __ swc1(i.InputSingleRegister(index), operand); | 1459 FPURegister ft = i.InputOrZeroSingleRegister(index); |
| 1460 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1461 __ Move(kDoubleRegZero, 0.0); |
| 1462 } |
| 1463 __ swc1(ft, operand); |
1449 break; | 1464 break; |
1450 } | 1465 } |
1451 case kMipsUswc1: { | 1466 case kMipsUswc1: { |
1452 size_t index = 0; | 1467 size_t index = 0; |
1453 MemOperand operand = i.MemoryOperand(&index); | 1468 MemOperand operand = i.MemoryOperand(&index); |
1454 __ Uswc1(i.InputSingleRegister(index), operand, kScratchReg); | 1469 FPURegister ft = i.InputOrZeroSingleRegister(index); |
| 1470 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1471 __ Move(kDoubleRegZero, 0.0); |
| 1472 } |
| 1473 __ Uswc1(ft, operand, kScratchReg); |
1455 break; | 1474 break; |
1456 } | 1475 } |
1457 case kMipsLdc1: | 1476 case kMipsLdc1: |
1458 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand()); | 1477 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand()); |
1459 break; | 1478 break; |
1460 case kMipsUldc1: | 1479 case kMipsUldc1: |
1461 __ Uldc1(i.OutputDoubleRegister(), i.MemoryOperand(), kScratchReg); | 1480 __ Uldc1(i.OutputDoubleRegister(), i.MemoryOperand(), kScratchReg); |
1462 break; | 1481 break; |
1463 case kMipsSdc1: | 1482 case kMipsSdc1: { |
1464 __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand()); | 1483 FPURegister ft = i.InputOrZeroDoubleRegister(2); |
| 1484 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1485 __ Move(kDoubleRegZero, 0.0); |
| 1486 } |
| 1487 __ sdc1(ft, i.MemoryOperand()); |
1465 break; | 1488 break; |
1466 case kMipsUsdc1: | 1489 } |
1467 __ Usdc1(i.InputDoubleRegister(2), i.MemoryOperand(), kScratchReg); | 1490 case kMipsUsdc1: { |
| 1491 FPURegister ft = i.InputOrZeroDoubleRegister(2); |
| 1492 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1493 __ Move(kDoubleRegZero, 0.0); |
| 1494 } |
| 1495 __ Usdc1(ft, i.MemoryOperand(), kScratchReg); |
1468 break; | 1496 break; |
| 1497 } |
1469 case kMipsPush: | 1498 case kMipsPush: |
1470 if (instr->InputAt(0)->IsFPRegister()) { | 1499 if (instr->InputAt(0)->IsFPRegister()) { |
1471 __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); | 1500 __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); |
1472 __ Subu(sp, sp, Operand(kDoubleSize)); | 1501 __ Subu(sp, sp, Operand(kDoubleSize)); |
1473 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1502 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
1474 } else { | 1503 } else { |
1475 __ Push(i.InputRegister(0)); | 1504 __ Push(i.InputRegister(0)); |
1476 frame_access_state()->IncreaseSPDelta(1); | 1505 frame_access_state()->IncreaseSPDelta(1); |
1477 } | 1506 } |
1478 break; | 1507 break; |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2267 padding_size -= v8::internal::Assembler::kInstrSize; | 2296 padding_size -= v8::internal::Assembler::kInstrSize; |
2268 } | 2297 } |
2269 } | 2298 } |
2270 } | 2299 } |
2271 | 2300 |
2272 #undef __ | 2301 #undef __ |
2273 | 2302 |
2274 } // namespace compiler | 2303 } // namespace compiler |
2275 } // namespace internal | 2304 } // namespace internal |
2276 } // namespace v8 | 2305 } // namespace v8 |
OLD | NEW |