| 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 <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_S390 | 9 #if V8_TARGET_ARCH_S390 |
| 10 | 10 |
| (...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 | 1143 |
| 1144 // Calculate C flag value for subtractions. | 1144 // Calculate C flag value for subtractions. |
| 1145 bool Simulator::BorrowFrom(int32_t left, int32_t right) { | 1145 bool Simulator::BorrowFrom(int32_t left, int32_t right) { |
| 1146 uint32_t uleft = static_cast<uint32_t>(left); | 1146 uint32_t uleft = static_cast<uint32_t>(left); |
| 1147 uint32_t uright = static_cast<uint32_t>(right); | 1147 uint32_t uright = static_cast<uint32_t>(right); |
| 1148 | 1148 |
| 1149 return (uright > uleft); | 1149 return (uright > uleft); |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 // Calculate V flag value for additions and subtractions. | 1152 // Calculate V flag value for additions and subtractions. |
| 1153 bool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right, | 1153 template <typename T1> |
| 1154 bool addition) { | 1154 bool Simulator::OverflowFromSigned(T1 alu_out, T1 left, T1 right, |
| 1155 bool addition) { |
| 1155 bool overflow; | 1156 bool overflow; |
| 1156 if (addition) { | 1157 if (addition) { |
| 1157 // operands have the same sign | 1158 // operands have the same sign |
| 1158 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) | 1159 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) |
| 1159 // and operands and result have different sign | 1160 // and operands and result have different sign |
| 1160 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); | 1161 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
| 1161 } else { | 1162 } else { |
| 1162 // operands have different signs | 1163 // operands have different signs |
| 1163 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) | 1164 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) |
| 1164 // and first operand and result have different signs | 1165 // and first operand and result have different signs |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1633 } | 1634 } |
| 1634 } | 1635 } |
| 1635 } | 1636 } |
| 1636 | 1637 |
| 1637 // Method for checking overflow on signed addition: | 1638 // Method for checking overflow on signed addition: |
| 1638 // Test src1 and src2 have opposite sign, | 1639 // Test src1 and src2 have opposite sign, |
| 1639 // (1) No overflow if they have opposite sign | 1640 // (1) No overflow if they have opposite sign |
| 1640 // (2) Test the result and one of the operands have opposite sign | 1641 // (2) Test the result and one of the operands have opposite sign |
| 1641 // (a) No overflow if they don't have opposite sign | 1642 // (a) No overflow if they don't have opposite sign |
| 1642 // (b) Overflow if opposite | 1643 // (b) Overflow if opposite |
| 1643 #define CheckOverflowForIntAdd(src1, src2) \ | 1644 #define CheckOverflowForIntAdd(src1, src2, type) \ |
| 1644 (((src1) ^ (src2)) < 0 ? false : ((((src1) + (src2)) ^ (src1)) < 0)) | 1645 OverflowFromSigned<type>(src1 + src2, src1, src2, true); |
| 1645 | 1646 |
| 1646 // Method for checking overflow on signed subtraction: | 1647 #define CheckOverflowForIntSub(src1, src2, type) \ |
| 1647 #define CheckOverflowForIntSub(src1, src2) \ | 1648 OverflowFromSigned<type>(src1 - src2, src1, src2, false); |
| 1648 (((src1 - src2) < src1) != (src2 > 0)) | |
| 1649 | 1649 |
| 1650 // Method for checking overflow on unsigned addtion | 1650 // Method for checking overflow on unsigned addtion |
| 1651 #define CheckOverflowForUIntAdd(src1, src2) \ | 1651 #define CheckOverflowForUIntAdd(src1, src2) \ |
| 1652 ((src1) + (src2) < (src1) || (src1) + (src2) < (src2)) | 1652 ((src1) + (src2) < (src1) || (src1) + (src2) < (src2)) |
| 1653 | 1653 |
| 1654 // Method for checking overflow on unsigned subtraction | 1654 // Method for checking overflow on unsigned subtraction |
| 1655 #define CheckOverflowForUIntSub(src1, src2) ((src1) - (src2) > (src1)) | 1655 #define CheckOverflowForUIntSub(src1, src2) ((src1) - (src2) > (src1)) |
| 1656 | 1656 |
| 1657 // Method for checking overflow on multiplication | 1657 // Method for checking overflow on multiplication |
| 1658 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1)) | 1658 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1)) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1679 case NR: | 1679 case NR: |
| 1680 case XR: { | 1680 case XR: { |
| 1681 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr); | 1681 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr); |
| 1682 int r1 = rrinst->R1Value(); | 1682 int r1 = rrinst->R1Value(); |
| 1683 int r2 = rrinst->R2Value(); | 1683 int r2 = rrinst->R2Value(); |
| 1684 int32_t r1_val = get_low_register<int32_t>(r1); | 1684 int32_t r1_val = get_low_register<int32_t>(r1); |
| 1685 int32_t r2_val = get_low_register<int32_t>(r2); | 1685 int32_t r2_val = get_low_register<int32_t>(r2); |
| 1686 bool isOF = false; | 1686 bool isOF = false; |
| 1687 switch (op) { | 1687 switch (op) { |
| 1688 case AR: | 1688 case AR: |
| 1689 isOF = CheckOverflowForIntAdd(r1_val, r2_val); | 1689 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t); |
| 1690 r1_val += r2_val; | 1690 r1_val += r2_val; |
| 1691 SetS390ConditionCode<int32_t>(r1_val, 0); | 1691 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 1692 SetS390OverflowCode(isOF); | 1692 SetS390OverflowCode(isOF); |
| 1693 break; | 1693 break; |
| 1694 case SR: | 1694 case SR: |
| 1695 isOF = CheckOverflowForIntSub(r1_val, r2_val); | 1695 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t); |
| 1696 r1_val -= r2_val; | 1696 r1_val -= r2_val; |
| 1697 SetS390ConditionCode<int32_t>(r1_val, 0); | 1697 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 1698 SetS390OverflowCode(isOF); | 1698 SetS390OverflowCode(isOF); |
| 1699 break; | 1699 break; |
| 1700 case OR: | 1700 case OR: |
| 1701 r1_val |= r2_val; | 1701 r1_val |= r2_val; |
| 1702 SetS390BitWiseConditionCode<uint32_t>(r1_val); | 1702 SetS390BitWiseConditionCode<uint32_t>(r1_val); |
| 1703 break; | 1703 break; |
| 1704 case NR: | 1704 case NR: |
| 1705 r1_val &= r2_val; | 1705 r1_val &= r2_val; |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2454 case OGR: | 2454 case OGR: |
| 2455 case NGR: | 2455 case NGR: |
| 2456 case XGR: { | 2456 case XGR: { |
| 2457 int r1 = rreInst->R1Value(); | 2457 int r1 = rreInst->R1Value(); |
| 2458 int r2 = rreInst->R2Value(); | 2458 int r2 = rreInst->R2Value(); |
| 2459 int64_t r1_val = get_register(r1); | 2459 int64_t r1_val = get_register(r1); |
| 2460 int64_t r2_val = get_register(r2); | 2460 int64_t r2_val = get_register(r2); |
| 2461 bool isOF = false; | 2461 bool isOF = false; |
| 2462 switch (op) { | 2462 switch (op) { |
| 2463 case AGR: | 2463 case AGR: |
| 2464 isOF = CheckOverflowForIntAdd(r1_val, r2_val); | 2464 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t); |
| 2465 r1_val += r2_val; | 2465 r1_val += r2_val; |
| 2466 SetS390ConditionCode<int64_t>(r1_val, 0); | 2466 SetS390ConditionCode<int64_t>(r1_val, 0); |
| 2467 SetS390OverflowCode(isOF); | 2467 SetS390OverflowCode(isOF); |
| 2468 break; | 2468 break; |
| 2469 case SGR: | 2469 case SGR: |
| 2470 isOF = CheckOverflowForIntSub(r1_val, r2_val); | 2470 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); |
| 2471 r1_val -= r2_val; | 2471 r1_val -= r2_val; |
| 2472 SetS390ConditionCode<int64_t>(r1_val, 0); | 2472 SetS390ConditionCode<int64_t>(r1_val, 0); |
| 2473 SetS390OverflowCode(isOF); | 2473 SetS390OverflowCode(isOF); |
| 2474 break; | 2474 break; |
| 2475 case OGR: | 2475 case OGR: |
| 2476 r1_val |= r2_val; | 2476 r1_val |= r2_val; |
| 2477 SetS390BitWiseConditionCode<uint64_t>(r1_val); | 2477 SetS390BitWiseConditionCode<uint64_t>(r1_val); |
| 2478 break; | 2478 break; |
| 2479 case NGR: | 2479 case NGR: |
| 2480 r1_val &= r2_val; | 2480 r1_val &= r2_val; |
| 2481 SetS390BitWiseConditionCode<uint64_t>(r1_val); | 2481 SetS390BitWiseConditionCode<uint64_t>(r1_val); |
| 2482 break; | 2482 break; |
| 2483 case XGR: | 2483 case XGR: |
| 2484 r1_val ^= r2_val; | 2484 r1_val ^= r2_val; |
| 2485 SetS390BitWiseConditionCode<uint64_t>(r1_val); | 2485 SetS390BitWiseConditionCode<uint64_t>(r1_val); |
| 2486 break; | 2486 break; |
| 2487 default: | 2487 default: |
| 2488 UNREACHABLE(); | 2488 UNREACHABLE(); |
| 2489 break; | 2489 break; |
| 2490 } | 2490 } |
| 2491 set_register(r1, r1_val); | 2491 set_register(r1, r1_val); |
| 2492 break; | 2492 break; |
| 2493 } | 2493 } |
| 2494 case AGFR: { | 2494 case AGFR: { |
| 2495 // Add Register (64 <- 32) (Sign Extends 32-bit val) | 2495 // Add Register (64 <- 32) (Sign Extends 32-bit val) |
| 2496 int r1 = rreInst->R1Value(); | 2496 int r1 = rreInst->R1Value(); |
| 2497 int r2 = rreInst->R2Value(); | 2497 int r2 = rreInst->R2Value(); |
| 2498 int64_t r1_val = get_register(r1); | 2498 int64_t r1_val = get_register(r1); |
| 2499 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); | 2499 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
| 2500 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val); | 2500 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t); |
| 2501 r1_val += r2_val; | 2501 r1_val += r2_val; |
| 2502 SetS390ConditionCode<int64_t>(r1_val, 0); | 2502 SetS390ConditionCode<int64_t>(r1_val, 0); |
| 2503 SetS390OverflowCode(isOF); | 2503 SetS390OverflowCode(isOF); |
| 2504 set_register(r1, r1_val); | 2504 set_register(r1, r1_val); |
| 2505 break; | 2505 break; |
| 2506 } | 2506 } |
| 2507 case SGFR: { | 2507 case SGFR: { |
| 2508 // Sub Reg (64 <- 32) | 2508 // Sub Reg (64 <- 32) |
| 2509 int r1 = rreInst->R1Value(); | 2509 int r1 = rreInst->R1Value(); |
| 2510 int r2 = rreInst->R2Value(); | 2510 int r2 = rreInst->R2Value(); |
| 2511 int64_t r1_val = get_register(r1); | 2511 int64_t r1_val = get_register(r1); |
| 2512 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); | 2512 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
| 2513 bool isOF = false; | 2513 bool isOF = false; |
| 2514 isOF = CheckOverflowForIntSub(r1_val, r2_val); | 2514 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); |
| 2515 r1_val -= r2_val; | 2515 r1_val -= r2_val; |
| 2516 SetS390ConditionCode<int64_t>(r1_val, 0); | 2516 SetS390ConditionCode<int64_t>(r1_val, 0); |
| 2517 SetS390OverflowCode(isOF); | 2517 SetS390OverflowCode(isOF); |
| 2518 set_register(r1, r1_val); | 2518 set_register(r1, r1_val); |
| 2519 break; | 2519 break; |
| 2520 } | 2520 } |
| 2521 case ARK: | 2521 case ARK: |
| 2522 case SRK: | 2522 case SRK: |
| 2523 case NRK: | 2523 case NRK: |
| 2524 case ORK: | 2524 case ORK: |
| 2525 case XRK: { | 2525 case XRK: { |
| 2526 // 32-bit Non-clobbering arithmetics / bitwise ops | 2526 // 32-bit Non-clobbering arithmetics / bitwise ops |
| 2527 int r1 = rrfInst->R1Value(); | 2527 int r1 = rrfInst->R1Value(); |
| 2528 int r2 = rrfInst->R2Value(); | 2528 int r2 = rrfInst->R2Value(); |
| 2529 int r3 = rrfInst->R3Value(); | 2529 int r3 = rrfInst->R3Value(); |
| 2530 int32_t r2_val = get_low_register<int32_t>(r2); | 2530 int32_t r2_val = get_low_register<int32_t>(r2); |
| 2531 int32_t r3_val = get_low_register<int32_t>(r3); | 2531 int32_t r3_val = get_low_register<int32_t>(r3); |
| 2532 if (ARK == op) { | 2532 if (ARK == op) { |
| 2533 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val); | 2533 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t); |
| 2534 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0); | 2534 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0); |
| 2535 SetS390OverflowCode(isOF); | 2535 SetS390OverflowCode(isOF); |
| 2536 set_low_register(r1, r2_val + r3_val); | 2536 set_low_register(r1, r2_val + r3_val); |
| 2537 } else if (SRK == op) { | 2537 } else if (SRK == op) { |
| 2538 bool isOF = CheckOverflowForIntSub(r2_val, r3_val); | 2538 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t); |
| 2539 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0); | 2539 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0); |
| 2540 SetS390OverflowCode(isOF); | 2540 SetS390OverflowCode(isOF); |
| 2541 set_low_register(r1, r2_val - r3_val); | 2541 set_low_register(r1, r2_val - r3_val); |
| 2542 } else { | 2542 } else { |
| 2543 // Assume bitwise operation here | 2543 // Assume bitwise operation here |
| 2544 uint32_t bitwise_result = 0; | 2544 uint32_t bitwise_result = 0; |
| 2545 if (NRK == op) { | 2545 if (NRK == op) { |
| 2546 bitwise_result = r2_val & r3_val; | 2546 bitwise_result = r2_val & r3_val; |
| 2547 } else if (ORK == op) { | 2547 } else if (ORK == op) { |
| 2548 bitwise_result = r2_val | r3_val; | 2548 bitwise_result = r2_val | r3_val; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 case NGRK: | 2580 case NGRK: |
| 2581 case OGRK: | 2581 case OGRK: |
| 2582 case XGRK: { | 2582 case XGRK: { |
| 2583 // 64-bit Non-clobbering arithmetics / bitwise ops. | 2583 // 64-bit Non-clobbering arithmetics / bitwise ops. |
| 2584 int r1 = rrfInst->R1Value(); | 2584 int r1 = rrfInst->R1Value(); |
| 2585 int r2 = rrfInst->R2Value(); | 2585 int r2 = rrfInst->R2Value(); |
| 2586 int r3 = rrfInst->R3Value(); | 2586 int r3 = rrfInst->R3Value(); |
| 2587 int64_t r2_val = get_register(r2); | 2587 int64_t r2_val = get_register(r2); |
| 2588 int64_t r3_val = get_register(r3); | 2588 int64_t r3_val = get_register(r3); |
| 2589 if (AGRK == op) { | 2589 if (AGRK == op) { |
| 2590 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val); | 2590 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t); |
| 2591 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0); | 2591 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0); |
| 2592 SetS390OverflowCode(isOF); | 2592 SetS390OverflowCode(isOF); |
| 2593 set_register(r1, r2_val + r3_val); | 2593 set_register(r1, r2_val + r3_val); |
| 2594 } else if (SGRK == op) { | 2594 } else if (SGRK == op) { |
| 2595 bool isOF = CheckOverflowForIntSub(r2_val, r3_val); | 2595 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t); |
| 2596 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0); | 2596 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0); |
| 2597 SetS390OverflowCode(isOF); | 2597 SetS390OverflowCode(isOF); |
| 2598 set_register(r1, r2_val - r3_val); | 2598 set_register(r1, r2_val - r3_val); |
| 2599 } else { | 2599 } else { |
| 2600 // Assume bitwise operation here | 2600 // Assume bitwise operation here |
| 2601 uint64_t bitwise_result = 0; | 2601 uint64_t bitwise_result = 0; |
| 2602 if (NGRK == op) { | 2602 if (NGRK == op) { |
| 2603 bitwise_result = r2_val & r3_val; | 2603 bitwise_result = r2_val & r3_val; |
| 2604 } else if (OGRK == op) { | 2604 } else if (OGRK == op) { |
| 2605 bitwise_result = r2_val | r3_val; | 2605 bitwise_result = r2_val | r3_val; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2628 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); | 2628 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); |
| 2629 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0); | 2629 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0); |
| 2630 SetS390OverflowCode(isOF); | 2630 SetS390OverflowCode(isOF); |
| 2631 set_register(r1, r2_val - r3_val); | 2631 set_register(r1, r2_val - r3_val); |
| 2632 } | 2632 } |
| 2633 break; | 2633 break; |
| 2634 } | 2634 } |
| 2635 case AHI: | 2635 case AHI: |
| 2636 case MHI: { | 2636 case MHI: { |
| 2637 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); | 2637 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); |
| 2638 int r1 = riinst->R1Value(); | 2638 int32_t r1 = riinst->R1Value(); |
| 2639 int i = riinst->I2Value(); | 2639 int32_t i = riinst->I2Value(); |
| 2640 int32_t r1_val = get_low_register<int32_t>(r1); | 2640 int32_t r1_val = get_low_register<int32_t>(r1); |
| 2641 bool isOF = false; | 2641 bool isOF = false; |
| 2642 switch (op) { | 2642 switch (op) { |
| 2643 case AHI: | 2643 case AHI: |
| 2644 isOF = CheckOverflowForIntAdd(r1_val, i); | 2644 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t); |
| 2645 r1_val += i; | 2645 r1_val += i; |
| 2646 break; | 2646 break; |
| 2647 case MHI: | 2647 case MHI: |
| 2648 isOF = CheckOverflowForMul(r1_val, i); | 2648 isOF = CheckOverflowForMul(r1_val, i); |
| 2649 r1_val *= i; | 2649 r1_val *= i; |
| 2650 break; // no overflow indication is given | 2650 break; // no overflow indication is given |
| 2651 default: | 2651 default: |
| 2652 break; | 2652 break; |
| 2653 } | 2653 } |
| 2654 set_low_register(r1, r1_val); | 2654 set_low_register(r1, r1_val); |
| 2655 SetS390ConditionCode<int32_t>(r1_val, 0); | 2655 SetS390ConditionCode<int32_t>(r1_val, 0); |
| 2656 SetS390OverflowCode(isOF); | 2656 SetS390OverflowCode(isOF); |
| 2657 break; | 2657 break; |
| 2658 } | 2658 } |
| 2659 case AGHI: | 2659 case AGHI: |
| 2660 case MGHI: { | 2660 case MGHI: { |
| 2661 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); | 2661 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); |
| 2662 int r1 = riinst->R1Value(); | 2662 int32_t r1 = riinst->R1Value(); |
| 2663 int64_t i = static_cast<int64_t>(riinst->I2Value()); | 2663 int64_t i = static_cast<int64_t>(riinst->I2Value()); |
| 2664 int64_t r1_val = get_register(r1); | 2664 int64_t r1_val = get_register(r1); |
| 2665 bool isOF = false; | 2665 bool isOF = false; |
| 2666 switch (op) { | 2666 switch (op) { |
| 2667 case AGHI: | 2667 case AGHI: |
| 2668 isOF = CheckOverflowForIntAdd(r1_val, i); | 2668 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t); |
| 2669 r1_val += i; | 2669 r1_val += i; |
| 2670 break; | 2670 break; |
| 2671 case MGHI: | 2671 case MGHI: |
| 2672 isOF = CheckOverflowForMul(r1_val, i); | 2672 isOF = CheckOverflowForMul(r1_val, i); |
| 2673 r1_val *= i; | 2673 r1_val *= i; |
| 2674 break; // no overflow indication is given | 2674 break; // no overflow indication is given |
| 2675 default: | 2675 default: |
| 2676 break; | 2676 break; |
| 2677 } | 2677 } |
| 2678 set_register(r1, r1_val); | 2678 set_register(r1, r1_val); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2745 int x2 = rxinst->X2Value(); | 2745 int x2 = rxinst->X2Value(); |
| 2746 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value()); | 2746 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value()); |
| 2747 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 2747 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 2748 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 2748 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 2749 intptr_t d2_val = rxinst->D2Value(); | 2749 intptr_t d2_val = rxinst->D2Value(); |
| 2750 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); | 2750 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr); |
| 2751 int32_t alu_out = 0; | 2751 int32_t alu_out = 0; |
| 2752 bool isOF = false; | 2752 bool isOF = false; |
| 2753 switch (op) { | 2753 switch (op) { |
| 2754 case A: | 2754 case A: |
| 2755 isOF = CheckOverflowForIntAdd(r1_val, mem_val); | 2755 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
| 2756 alu_out = r1_val + mem_val; | 2756 alu_out = r1_val + mem_val; |
| 2757 SetS390ConditionCode<int32_t>(alu_out, 0); | 2757 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 2758 SetS390OverflowCode(isOF); | 2758 SetS390OverflowCode(isOF); |
| 2759 break; | 2759 break; |
| 2760 case S: | 2760 case S: |
| 2761 isOF = CheckOverflowForIntSub(r1_val, mem_val); | 2761 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); |
| 2762 alu_out = r1_val - mem_val; | 2762 alu_out = r1_val - mem_val; |
| 2763 SetS390ConditionCode<int32_t>(alu_out, 0); | 2763 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 2764 SetS390OverflowCode(isOF); | 2764 SetS390OverflowCode(isOF); |
| 2765 break; | 2765 break; |
| 2766 case M: | 2766 case M: |
| 2767 case D: | 2767 case D: |
| 2768 UNIMPLEMENTED(); | 2768 UNIMPLEMENTED(); |
| 2769 break; | 2769 break; |
| 2770 case O: | 2770 case O: |
| 2771 alu_out = r1_val | mem_val; | 2771 alu_out = r1_val | mem_val; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2829 case SH: | 2829 case SH: |
| 2830 case MH: { | 2830 case MH: { |
| 2831 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr); | 2831 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr); |
| 2832 int b2 = rxinst->B2Value(); | 2832 int b2 = rxinst->B2Value(); |
| 2833 int x2 = rxinst->X2Value(); | 2833 int x2 = rxinst->X2Value(); |
| 2834 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value()); | 2834 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value()); |
| 2835 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 2835 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 2836 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 2836 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 2837 intptr_t d2_val = rxinst->D2Value(); | 2837 intptr_t d2_val = rxinst->D2Value(); |
| 2838 intptr_t addr = b2_val + x2_val + d2_val; | 2838 intptr_t addr = b2_val + x2_val + d2_val; |
| 2839 int16_t mem_val = ReadH(addr, instr); | 2839 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr)); |
| 2840 int32_t alu_out = 0; | 2840 int32_t alu_out = 0; |
| 2841 bool isOF = false; | 2841 bool isOF = false; |
| 2842 if (AH == op) { | 2842 if (AH == op) { |
| 2843 isOF = CheckOverflowForIntAdd(r1_val, mem_val); | 2843 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
| 2844 alu_out = r1_val + mem_val; | 2844 alu_out = r1_val + mem_val; |
| 2845 } else if (SH == op) { | 2845 } else if (SH == op) { |
| 2846 isOF = CheckOverflowForIntSub(r1_val, mem_val); | 2846 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t); |
| 2847 alu_out = r1_val - mem_val; | 2847 alu_out = r1_val - mem_val; |
| 2848 } else if (MH == op) { | 2848 } else if (MH == op) { |
| 2849 alu_out = r1_val * mem_val; | 2849 alu_out = r1_val * mem_val; |
| 2850 } else { | 2850 } else { |
| 2851 UNREACHABLE(); | 2851 UNREACHABLE(); |
| 2852 } | 2852 } |
| 2853 set_low_register(r1, alu_out); | 2853 set_low_register(r1, alu_out); |
| 2854 if (MH != op) { // MH does not change condition code | 2854 if (MH != op) { // MH does not change condition code |
| 2855 SetS390ConditionCode<int32_t>(alu_out, 0); | 2855 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 2856 SetS390OverflowCode(isOF); | 2856 SetS390OverflowCode(isOF); |
| (...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4315 case AGHIK: { | 4315 case AGHIK: { |
| 4316 // Non-clobbering Add Halfword Immediate | 4316 // Non-clobbering Add Halfword Immediate |
| 4317 RIEInstruction* rieInst = reinterpret_cast<RIEInstruction*>(instr); | 4317 RIEInstruction* rieInst = reinterpret_cast<RIEInstruction*>(instr); |
| 4318 int r1 = rieInst->R1Value(); | 4318 int r1 = rieInst->R1Value(); |
| 4319 int r2 = rieInst->R2Value(); | 4319 int r2 = rieInst->R2Value(); |
| 4320 bool isOF = false; | 4320 bool isOF = false; |
| 4321 if (AHIK == op) { | 4321 if (AHIK == op) { |
| 4322 // 32-bit Add | 4322 // 32-bit Add |
| 4323 int32_t r2_val = get_low_register<int32_t>(r2); | 4323 int32_t r2_val = get_low_register<int32_t>(r2); |
| 4324 int32_t imm = rieInst->I6Value(); | 4324 int32_t imm = rieInst->I6Value(); |
| 4325 isOF = CheckOverflowForIntAdd(r2_val, imm); | 4325 isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t); |
| 4326 set_low_register(r1, r2_val + imm); | 4326 set_low_register(r1, r2_val + imm); |
| 4327 SetS390ConditionCode<int32_t>(r2_val + imm, 0); | 4327 SetS390ConditionCode<int32_t>(r2_val + imm, 0); |
| 4328 } else if (AGHIK == op) { | 4328 } else if (AGHIK == op) { |
| 4329 // 64-bit Add | 4329 // 64-bit Add |
| 4330 int64_t r2_val = get_register(r2); | 4330 int64_t r2_val = get_register(r2); |
| 4331 int64_t imm = static_cast<int64_t>(rieInst->I6Value()); | 4331 int64_t imm = static_cast<int64_t>(rieInst->I6Value()); |
| 4332 isOF = CheckOverflowForIntAdd(r2_val, imm); | 4332 isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t); |
| 4333 set_register(r1, r2_val + imm); | 4333 set_register(r1, r2_val + imm); |
| 4334 SetS390ConditionCode<int64_t>(r2_val + imm, 0); | 4334 SetS390ConditionCode<int64_t>(r2_val + imm, 0); |
| 4335 } | 4335 } |
| 4336 SetS390OverflowCode(isOF); | 4336 SetS390OverflowCode(isOF); |
| 4337 break; | 4337 break; |
| 4338 } | 4338 } |
| 4339 case ALFI: | 4339 case ALFI: |
| 4340 case SLFI: { | 4340 case SLFI: { |
| 4341 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); | 4341 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); |
| 4342 int r1 = rilInstr->R1Value(); | 4342 int r1 = rilInstr->R1Value(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4365 int r1 = rxyInstr->R1Value(); | 4365 int r1 = rxyInstr->R1Value(); |
| 4366 int x2 = rxyInstr->X2Value(); | 4366 int x2 = rxyInstr->X2Value(); |
| 4367 int b2 = rxyInstr->B2Value(); | 4367 int b2 = rxyInstr->B2Value(); |
| 4368 int d2 = rxyInstr->D2Value(); | 4368 int d2 = rxyInstr->D2Value(); |
| 4369 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 4369 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 4370 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 4370 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 4371 int32_t alu_out = get_low_register<int32_t>(r1); | 4371 int32_t alu_out = get_low_register<int32_t>(r1); |
| 4372 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); | 4372 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
| 4373 bool isOF = false; | 4373 bool isOF = false; |
| 4374 if (op == AY) { | 4374 if (op == AY) { |
| 4375 isOF = CheckOverflowForIntAdd(alu_out, mem_val); | 4375 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t); |
| 4376 alu_out += mem_val; | 4376 alu_out += mem_val; |
| 4377 SetS390ConditionCode<int32_t>(alu_out, 0); | 4377 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 4378 SetS390OverflowCode(isOF); | 4378 SetS390OverflowCode(isOF); |
| 4379 } else if (op == SY) { | 4379 } else if (op == SY) { |
| 4380 isOF = CheckOverflowForIntSub(alu_out, mem_val); | 4380 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t); |
| 4381 alu_out -= mem_val; | 4381 alu_out -= mem_val; |
| 4382 SetS390ConditionCode<int32_t>(alu_out, 0); | 4382 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 4383 SetS390OverflowCode(isOF); | 4383 SetS390OverflowCode(isOF); |
| 4384 } else if (op == NY) { | 4384 } else if (op == NY) { |
| 4385 alu_out &= mem_val; | 4385 alu_out &= mem_val; |
| 4386 SetS390BitWiseConditionCode<uint32_t>(alu_out); | 4386 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 4387 } else if (op == OY) { | 4387 } else if (op == OY) { |
| 4388 alu_out |= mem_val; | 4388 alu_out |= mem_val; |
| 4389 SetS390BitWiseConditionCode<uint32_t>(alu_out); | 4389 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 4390 } else if (op == XY) { | 4390 } else if (op == XY) { |
| 4391 alu_out ^= mem_val; | 4391 alu_out ^= mem_val; |
| 4392 SetS390BitWiseConditionCode<uint32_t>(alu_out); | 4392 SetS390BitWiseConditionCode<uint32_t>(alu_out); |
| 4393 } else if (op == CY) { | 4393 } else if (op == CY) { |
| 4394 SetS390ConditionCode<int32_t>(alu_out, mem_val); | 4394 SetS390ConditionCode<int32_t>(alu_out, mem_val); |
| 4395 } | 4395 } |
| 4396 if (op != CY) { | 4396 if (op != CY) { |
| 4397 set_low_register(r1, alu_out); | 4397 set_low_register(r1, alu_out); |
| 4398 } | 4398 } |
| 4399 break; | 4399 break; |
| 4400 } | 4400 } |
| 4401 case AHY: | 4401 case AHY: |
| 4402 case SHY: { | 4402 case SHY: { |
| 4403 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr); | 4403 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr); |
| 4404 int32_t r1_val = get_low_register<int32_t>(rxyInstr->R1Value()); | 4404 int32_t r1_val = get_low_register<int32_t>(rxyInstr->R1Value()); |
| 4405 int b2 = rxyInstr->B2Value(); | 4405 int b2 = rxyInstr->B2Value(); |
| 4406 int x2 = rxyInstr->X2Value(); | 4406 int x2 = rxyInstr->X2Value(); |
| 4407 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); | 4407 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
| 4408 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); | 4408 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
| 4409 intptr_t d2_val = rxyInstr->D2Value(); | 4409 intptr_t d2_val = rxyInstr->D2Value(); |
| 4410 int16_t mem_val = ReadH(b2_val + d2_val + x2_val, instr); | 4410 int32_t mem_val = |
| 4411 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr)); |
| 4411 int32_t alu_out = 0; | 4412 int32_t alu_out = 0; |
| 4412 bool isOF = false; | 4413 bool isOF = false; |
| 4413 switch (op) { | 4414 switch (op) { |
| 4414 case AHY: | 4415 case AHY: |
| 4415 alu_out = r1_val + mem_val; | 4416 alu_out = r1_val + mem_val; |
| 4416 isOF = CheckOverflowForIntAdd(r1_val, mem_val); | 4417 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
| 4417 break; | 4418 break; |
| 4418 case SHY: | 4419 case SHY: |
| 4419 alu_out = r1_val - mem_val; | 4420 alu_out = r1_val - mem_val; |
| 4420 isOF = CheckOverflowForIntSub(r1_val, mem_val); | 4421 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t); |
| 4421 break; | 4422 break; |
| 4422 default: | 4423 default: |
| 4423 UNREACHABLE(); | 4424 UNREACHABLE(); |
| 4424 break; | 4425 break; |
| 4425 } | 4426 } |
| 4426 set_low_register(r1, alu_out); | 4427 set_low_register(r1, alu_out); |
| 4427 SetS390ConditionCode<int32_t>(alu_out, 0); | 4428 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 4428 SetS390OverflowCode(isOF); | 4429 SetS390OverflowCode(isOF); |
| 4429 break; | 4430 break; |
| 4430 } | 4431 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4513 SetS390ConditionCode<uint32_t>(alu_out, 0); | 4514 SetS390ConditionCode<uint32_t>(alu_out, 0); |
| 4514 } else if (op == CLY) { | 4515 } else if (op == CLY) { |
| 4515 SetS390ConditionCode<uint32_t>(alu_out, mem_val); | 4516 SetS390ConditionCode<uint32_t>(alu_out, mem_val); |
| 4516 } | 4517 } |
| 4517 break; | 4518 break; |
| 4518 } | 4519 } |
| 4519 case AGFI: | 4520 case AGFI: |
| 4520 case AFI: { | 4521 case AFI: { |
| 4521 // Clobbering Add Word Immediate | 4522 // Clobbering Add Word Immediate |
| 4522 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); | 4523 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr); |
| 4523 int r1 = rilInstr->R1Value(); | 4524 int32_t r1 = rilInstr->R1Value(); |
| 4524 int i2 = rilInstr->I2Value(); | |
| 4525 bool isOF = false; | 4525 bool isOF = false; |
| 4526 if (AFI == op) { | 4526 if (AFI == op) { |
| 4527 // 32-bit Add (Register + 32-bit Immediate) | 4527 // 32-bit Add (Register + 32-bit Immediate) |
| 4528 int32_t r1_val = get_low_register<int32_t>(r1); | 4528 int32_t r1_val = get_low_register<int32_t>(r1); |
| 4529 isOF = CheckOverflowForIntAdd(r1_val, i2); | 4529 int32_t i2 = rilInstr->I2Value(); |
| 4530 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t); |
| 4530 int32_t alu_out = r1_val + i2; | 4531 int32_t alu_out = r1_val + i2; |
| 4531 set_low_register(r1, alu_out); | 4532 set_low_register(r1, alu_out); |
| 4532 SetS390ConditionCode<int32_t>(alu_out, 0); | 4533 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 4533 } else if (AGFI == op) { | 4534 } else if (AGFI == op) { |
| 4534 // 64-bit Add (Register + 32-bit Imm) | 4535 // 64-bit Add (Register + 32-bit Imm) |
| 4535 int64_t r1_val = get_register(r1); | 4536 int64_t r1_val = get_register(r1); |
| 4536 isOF = CheckOverflowForIntAdd(r1_val, i2); | 4537 int64_t i2 = static_cast<int64_t>(rilInstr->I2Value()); |
| 4538 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t); |
| 4537 int64_t alu_out = r1_val + i2; | 4539 int64_t alu_out = r1_val + i2; |
| 4538 set_register(r1, alu_out); | 4540 set_register(r1, alu_out); |
| 4539 SetS390ConditionCode<int64_t>(alu_out, 0); | 4541 SetS390ConditionCode<int64_t>(alu_out, 0); |
| 4540 } | 4542 } |
| 4541 SetS390OverflowCode(isOF); | 4543 SetS390OverflowCode(isOF); |
| 4542 break; | 4544 break; |
| 4543 } | 4545 } |
| 4544 case ASI: { | 4546 case ASI: { |
| 4545 int8_t i2 = static_cast<int8_t>(siyInstr->I2Value()); | 4547 // TODO(bcleung): Change all fooInstr->I2Value() to template functions. |
| 4548 // The below static cast to 8 bit and then to 32 bit is necessary |
| 4549 // because siyInstr->I2Value() returns a uint8_t, which a direct |
| 4550 // cast to int32_t could incorrectly interpret. |
| 4551 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value()); |
| 4552 int32_t i2 = static_cast<int32_t>(i2_8bit); |
| 4546 int b1 = siyInstr->B1Value(); | 4553 int b1 = siyInstr->B1Value(); |
| 4547 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); | 4554 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
| 4548 | 4555 |
| 4549 int d1_val = siyInstr->D1Value(); | 4556 int d1_val = siyInstr->D1Value(); |
| 4550 intptr_t addr = b1_val + d1_val; | 4557 intptr_t addr = b1_val + d1_val; |
| 4551 | 4558 |
| 4552 int32_t mem_val = ReadW(addr, instr); | 4559 int32_t mem_val = ReadW(addr, instr); |
| 4553 bool isOF = CheckOverflowForIntAdd(mem_val, i2); | 4560 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t); |
| 4554 int32_t alu_out = mem_val + i2; | 4561 int32_t alu_out = mem_val + i2; |
| 4555 SetS390ConditionCode<int32_t>(alu_out, 0); | 4562 SetS390ConditionCode<int32_t>(alu_out, 0); |
| 4556 SetS390OverflowCode(isOF); | 4563 SetS390OverflowCode(isOF); |
| 4557 WriteW(addr, alu_out, instr); | 4564 WriteW(addr, alu_out, instr); |
| 4558 break; | 4565 break; |
| 4559 } | 4566 } |
| 4560 case AGSI: { | 4567 case AGSI: { |
| 4561 int8_t i2 = static_cast<int8_t>(siyInstr->I2Value()); | 4568 // TODO(bcleung): Change all fooInstr->I2Value() to template functions. |
| 4569 // The below static cast to 8 bit and then to 32 bit is necessary |
| 4570 // because siyInstr->I2Value() returns a uint8_t, which a direct |
| 4571 // cast to int32_t could incorrectly interpret. |
| 4572 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value()); |
| 4573 int64_t i2 = static_cast<int64_t>(i2_8bit); |
| 4562 int b1 = siyInstr->B1Value(); | 4574 int b1 = siyInstr->B1Value(); |
| 4563 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); | 4575 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
| 4564 | 4576 |
| 4565 int d1_val = siyInstr->D1Value(); | 4577 int d1_val = siyInstr->D1Value(); |
| 4566 intptr_t addr = b1_val + d1_val; | 4578 intptr_t addr = b1_val + d1_val; |
| 4567 | 4579 |
| 4568 int64_t mem_val = ReadDW(addr); | 4580 int64_t mem_val = ReadDW(addr); |
| 4569 int isOF = CheckOverflowForIntAdd(mem_val, i2); | 4581 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t); |
| 4570 int64_t alu_out = mem_val + i2; | 4582 int64_t alu_out = mem_val + i2; |
| 4571 SetS390ConditionCode<uint64_t>(alu_out, 0); | 4583 SetS390ConditionCode<uint64_t>(alu_out, 0); |
| 4572 SetS390OverflowCode(isOF); | 4584 SetS390OverflowCode(isOF); |
| 4573 WriteDW(addr, alu_out); | 4585 WriteDW(addr, alu_out); |
| 4574 break; | 4586 break; |
| 4575 } | 4587 } |
| 4576 case AGF: | 4588 case AGF: |
| 4577 case SGF: | 4589 case SGF: |
| 4578 case ALG: | 4590 case ALG: |
| 4579 case SLG: { | 4591 case SLG: { |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5008 uintptr_t address = *stack_slot; | 5020 uintptr_t address = *stack_slot; |
| 5009 set_register(sp, current_sp + sizeof(uintptr_t)); | 5021 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 5010 return address; | 5022 return address; |
| 5011 } | 5023 } |
| 5012 | 5024 |
| 5013 } // namespace internal | 5025 } // namespace internal |
| 5014 } // namespace v8 | 5026 } // namespace v8 |
| 5015 | 5027 |
| 5016 #endif // USE_SIMULATOR | 5028 #endif // USE_SIMULATOR |
| 5017 #endif // V8_TARGET_ARCH_S390 | 5029 #endif // V8_TARGET_ARCH_S390 |
| OLD | NEW |