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 |