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 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1815 if (ALR == op) { | 1815 if (ALR == op) { |
1816 alu_out = r1_val + r2_val; | 1816 alu_out = r1_val + r2_val; |
1817 isOF = CheckOverflowForUIntAdd(r1_val, r2_val); | 1817 isOF = CheckOverflowForUIntAdd(r1_val, r2_val); |
1818 } else if (SLR == op) { | 1818 } else if (SLR == op) { |
1819 alu_out = r1_val - r2_val; | 1819 alu_out = r1_val - r2_val; |
1820 isOF = CheckOverflowForUIntSub(r1_val, r2_val); | 1820 isOF = CheckOverflowForUIntSub(r1_val, r2_val); |
1821 } else { | 1821 } else { |
1822 UNREACHABLE(); | 1822 UNREACHABLE(); |
1823 } | 1823 } |
1824 set_low_register(r1, alu_out); | 1824 set_low_register(r1, alu_out); |
1825 SetS390ConditionCode<uint32_t>(alu_out, 0); | 1825 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); |
1826 SetS390OverflowCode(isOF); | 1826 SetS390OverflowCode(isOF); |
john.yan
2016/03/30 20:48:52
ALR/SLR would not set Overflow condition as stated
bcleung
2016/03/30 22:23:26
This is a leftover from ALR, which originally had
| |
1827 break; | 1827 break; |
1828 } | 1828 } |
1829 case LNR: { | 1829 case LNR: { |
1830 // Load Negative (32) | 1830 // Load Negative (32) |
1831 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr); | 1831 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr); |
1832 int r1 = rrinst->R1Value(); | 1832 int r1 = rrinst->R1Value(); |
1833 int r2 = rrinst->R2Value(); | 1833 int r2 = rrinst->R2Value(); |
1834 int32_t r2_val = get_low_register<int32_t>(r2); | 1834 int32_t r2_val = get_low_register<int32_t>(r2); |
1835 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it. | 1835 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it. |
1836 set_low_register(r1, r2_val); | 1836 set_low_register(r1, r2_val); |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2450 set_low_register(r1, alu_out >> 32); | 2450 set_low_register(r1, alu_out >> 32); |
2451 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); | 2451 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF); |
2452 SetS390ConditionCode<int32_t>(alu_out, 0); | 2452 SetS390ConditionCode<int32_t>(alu_out, 0); |
2453 break; | 2453 break; |
2454 } | 2454 } |
2455 default: { return DecodeFourByteArithmetic(instr); } | 2455 default: { return DecodeFourByteArithmetic(instr); } |
2456 } | 2456 } |
2457 return true; | 2457 return true; |
2458 } | 2458 } |
2459 | 2459 |
2460 /** | 2460 bool Simulator::DecodeFourByteArithmetic64Bit(Instruction* instr) { |
2461 * Decodes and simulates four byte arithmetic instructions | |
2462 */ | |
2463 bool Simulator::DecodeFourByteArithmetic(Instruction* instr) { | |
2464 Opcode op = instr->S390OpcodeValue(); | 2461 Opcode op = instr->S390OpcodeValue(); |
2465 | 2462 |
2466 // Pre-cast instruction to various types | |
2467 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr); | 2463 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr); |
2468 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr); | 2464 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr); |
2469 | 2465 |
2470 switch (op) { | 2466 switch (op) { |
2471 case AGR: | 2467 case AGR: |
2472 case SGR: | 2468 case SGR: |
2473 case OGR: | 2469 case OGR: |
2474 case NGR: | 2470 case NGR: |
2475 case XGR: { | 2471 case XGR: { |
2476 int r1 = rreInst->R1Value(); | 2472 int r1 = rreInst->R1Value(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2530 int64_t r1_val = get_register(r1); | 2526 int64_t r1_val = get_register(r1); |
2531 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); | 2527 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
2532 bool isOF = false; | 2528 bool isOF = false; |
2533 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); | 2529 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t); |
2534 r1_val -= r2_val; | 2530 r1_val -= r2_val; |
2535 SetS390ConditionCode<int64_t>(r1_val, 0); | 2531 SetS390ConditionCode<int64_t>(r1_val, 0); |
2536 SetS390OverflowCode(isOF); | 2532 SetS390OverflowCode(isOF); |
2537 set_register(r1, r1_val); | 2533 set_register(r1, r1_val); |
2538 break; | 2534 break; |
2539 } | 2535 } |
2536 case AGRK: | |
2537 case SGRK: | |
2538 case NGRK: | |
2539 case OGRK: | |
2540 case XGRK: { | |
2541 // 64-bit Non-clobbering arithmetics / bitwise ops. | |
2542 int r1 = rrfInst->R1Value(); | |
2543 int r2 = rrfInst->R2Value(); | |
2544 int r3 = rrfInst->R3Value(); | |
2545 int64_t r2_val = get_register(r2); | |
2546 int64_t r3_val = get_register(r3); | |
2547 if (AGRK == op) { | |
2548 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t); | |
2549 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0); | |
2550 SetS390OverflowCode(isOF); | |
2551 set_register(r1, r2_val + r3_val); | |
2552 } else if (SGRK == op) { | |
2553 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t); | |
2554 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0); | |
2555 SetS390OverflowCode(isOF); | |
2556 set_register(r1, r2_val - r3_val); | |
2557 } else { | |
2558 // Assume bitwise operation here | |
2559 uint64_t bitwise_result = 0; | |
2560 if (NGRK == op) { | |
2561 bitwise_result = r2_val & r3_val; | |
2562 } else if (OGRK == op) { | |
2563 bitwise_result = r2_val | r3_val; | |
2564 } else if (XGRK == op) { | |
2565 bitwise_result = r2_val ^ r3_val; | |
2566 } | |
2567 SetS390BitWiseConditionCode<uint64_t>(bitwise_result); | |
2568 set_register(r1, bitwise_result); | |
2569 } | |
2570 break; | |
2571 } | |
2572 case ALGRK: | |
2573 case SLGRK: { | |
2574 // 64-bit Non-clobbering unsigned arithmetics | |
2575 int r1 = rrfInst->R1Value(); | |
2576 int r2 = rrfInst->R2Value(); | |
2577 int r3 = rrfInst->R3Value(); | |
2578 uint64_t r2_val = get_register(r2); | |
2579 uint64_t r3_val = get_register(r3); | |
2580 if (ALGRK == op) { | |
2581 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val); | |
2582 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0); | |
2583 SetS390OverflowCode(isOF); | |
2584 set_register(r1, r2_val + r3_val); | |
2585 } else if (SLGRK == op) { | |
2586 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); | |
2587 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0); | |
2588 SetS390OverflowCode(isOF); | |
2589 set_register(r1, r2_val - r3_val); | |
2590 } | |
2591 } | |
2592 case AGHI: | |
2593 case MGHI: { | |
2594 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); | |
2595 int32_t r1 = riinst->R1Value(); | |
2596 int64_t i = static_cast<int64_t>(riinst->I2Value()); | |
2597 int64_t r1_val = get_register(r1); | |
2598 bool isOF = false; | |
2599 switch (op) { | |
2600 case AGHI: | |
2601 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t); | |
2602 r1_val += i; | |
2603 break; | |
2604 case MGHI: | |
2605 isOF = CheckOverflowForMul(r1_val, i); | |
2606 r1_val *= i; | |
2607 break; // no overflow indication is given | |
2608 default: | |
2609 break; | |
2610 } | |
2611 set_register(r1, r1_val); | |
2612 SetS390ConditionCode<int32_t>(r1_val, 0); | |
2613 SetS390OverflowCode(isOF); | |
2614 break; | |
2615 } | |
2616 default: | |
2617 UNREACHABLE(); | |
2618 } | |
2619 return true; | |
2620 } | |
2621 | |
2622 /** | |
2623 * Decodes and simulates four byte arithmetic instructions | |
2624 */ | |
2625 bool Simulator::DecodeFourByteArithmetic(Instruction* instr) { | |
2626 Opcode op = instr->S390OpcodeValue(); | |
2627 | |
2628 // Pre-cast instruction to various types | |
2629 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr); | |
2630 | |
2631 switch (op) { | |
2632 case AGR: | |
2633 case SGR: | |
2634 case OGR: | |
2635 case NGR: | |
2636 case XGR: | |
2637 case AGFR: | |
2638 case SGFR: { | |
2639 DecodeFourByteArithmetic64Bit(instr); | |
2640 break; | |
2641 } | |
2540 case ARK: | 2642 case ARK: |
2541 case SRK: | 2643 case SRK: |
2542 case NRK: | 2644 case NRK: |
2543 case ORK: | 2645 case ORK: |
2544 case XRK: { | 2646 case XRK: { |
2545 // 32-bit Non-clobbering arithmetics / bitwise ops | 2647 // 32-bit Non-clobbering arithmetics / bitwise ops |
2546 int r1 = rrfInst->R1Value(); | 2648 int r1 = rrfInst->R1Value(); |
2547 int r2 = rrfInst->R2Value(); | 2649 int r2 = rrfInst->R2Value(); |
2548 int r3 = rrfInst->R3Value(); | 2650 int r3 = rrfInst->R3Value(); |
2549 int32_t r2_val = get_low_register<int32_t>(r2); | 2651 int32_t r2_val = get_low_register<int32_t>(r2); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2592 SetS390OverflowCode(isOF); | 2694 SetS390OverflowCode(isOF); |
2593 set_low_register(r1, r2_val - r3_val); | 2695 set_low_register(r1, r2_val - r3_val); |
2594 } | 2696 } |
2595 break; | 2697 break; |
2596 } | 2698 } |
2597 case AGRK: | 2699 case AGRK: |
2598 case SGRK: | 2700 case SGRK: |
2599 case NGRK: | 2701 case NGRK: |
2600 case OGRK: | 2702 case OGRK: |
2601 case XGRK: { | 2703 case XGRK: { |
2602 // 64-bit Non-clobbering arithmetics / bitwise ops. | 2704 DecodeFourByteArithmetic64Bit(instr); |
2603 int r1 = rrfInst->R1Value(); | |
2604 int r2 = rrfInst->R2Value(); | |
2605 int r3 = rrfInst->R3Value(); | |
2606 int64_t r2_val = get_register(r2); | |
2607 int64_t r3_val = get_register(r3); | |
2608 if (AGRK == op) { | |
2609 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t); | |
2610 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0); | |
2611 SetS390OverflowCode(isOF); | |
2612 set_register(r1, r2_val + r3_val); | |
2613 } else if (SGRK == op) { | |
2614 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t); | |
2615 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0); | |
2616 SetS390OverflowCode(isOF); | |
2617 set_register(r1, r2_val - r3_val); | |
2618 } else { | |
2619 // Assume bitwise operation here | |
2620 uint64_t bitwise_result = 0; | |
2621 if (NGRK == op) { | |
2622 bitwise_result = r2_val & r3_val; | |
2623 } else if (OGRK == op) { | |
2624 bitwise_result = r2_val | r3_val; | |
2625 } else if (XGRK == op) { | |
2626 bitwise_result = r2_val ^ r3_val; | |
2627 } | |
2628 SetS390BitWiseConditionCode<uint64_t>(bitwise_result); | |
2629 set_register(r1, bitwise_result); | |
2630 } | |
2631 break; | 2705 break; |
2632 } | 2706 } |
2633 case ALGRK: | 2707 case ALGRK: |
2634 case SLGRK: { | 2708 case SLGRK: { |
2635 // 64-bit Non-clobbering unsigned arithmetics | 2709 DecodeFourByteArithmetic64Bit(instr); |
2636 int r1 = rrfInst->R1Value(); | |
2637 int r2 = rrfInst->R2Value(); | |
2638 int r3 = rrfInst->R3Value(); | |
2639 uint64_t r2_val = get_register(r2); | |
2640 uint64_t r3_val = get_register(r3); | |
2641 if (ALGRK == op) { | |
2642 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val); | |
2643 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0); | |
2644 SetS390OverflowCode(isOF); | |
2645 set_register(r1, r2_val + r3_val); | |
2646 } else if (SLGRK == op) { | |
2647 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val); | |
2648 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0); | |
2649 SetS390OverflowCode(isOF); | |
2650 set_register(r1, r2_val - r3_val); | |
2651 } | |
2652 break; | 2710 break; |
2653 } | 2711 } |
2654 case AHI: | 2712 case AHI: |
2655 case MHI: { | 2713 case MHI: { |
2656 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); | 2714 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); |
2657 int32_t r1 = riinst->R1Value(); | 2715 int32_t r1 = riinst->R1Value(); |
2658 int32_t i = riinst->I2Value(); | 2716 int32_t i = riinst->I2Value(); |
2659 int32_t r1_val = get_low_register<int32_t>(r1); | 2717 int32_t r1_val = get_low_register<int32_t>(r1); |
2660 bool isOF = false; | 2718 bool isOF = false; |
2661 switch (op) { | 2719 switch (op) { |
2662 case AHI: | 2720 case AHI: |
2663 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t); | 2721 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t); |
2664 r1_val += i; | 2722 r1_val += i; |
2665 break; | 2723 break; |
2666 case MHI: | 2724 case MHI: |
2667 isOF = CheckOverflowForMul(r1_val, i); | 2725 isOF = CheckOverflowForMul(r1_val, i); |
2668 r1_val *= i; | 2726 r1_val *= i; |
2669 break; // no overflow indication is given | 2727 break; // no overflow indication is given |
2670 default: | 2728 default: |
2671 break; | 2729 break; |
2672 } | 2730 } |
2673 set_low_register(r1, r1_val); | 2731 set_low_register(r1, r1_val); |
2674 SetS390ConditionCode<int32_t>(r1_val, 0); | 2732 SetS390ConditionCode<int32_t>(r1_val, 0); |
2675 SetS390OverflowCode(isOF); | 2733 SetS390OverflowCode(isOF); |
2676 break; | 2734 break; |
2677 } | 2735 } |
2678 case AGHI: | 2736 case AGHI: |
2679 case MGHI: { | 2737 case MGHI: { |
2680 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr); | 2738 DecodeFourByteArithmetic64Bit(instr); |
2681 int32_t r1 = riinst->R1Value(); | |
2682 int64_t i = static_cast<int64_t>(riinst->I2Value()); | |
2683 int64_t r1_val = get_register(r1); | |
2684 bool isOF = false; | |
2685 switch (op) { | |
2686 case AGHI: | |
2687 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t); | |
2688 r1_val += i; | |
2689 break; | |
2690 case MGHI: | |
2691 isOF = CheckOverflowForMul(r1_val, i); | |
2692 r1_val *= i; | |
2693 break; // no overflow indication is given | |
2694 default: | |
2695 break; | |
2696 } | |
2697 set_register(r1, r1_val); | |
2698 SetS390ConditionCode<int32_t>(r1_val, 0); | |
2699 SetS390OverflowCode(isOF); | |
2700 break; | 2739 break; |
2701 } | 2740 } |
2702 case MLR: { | 2741 case MLR: { |
2703 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr); | 2742 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr); |
2704 int r1 = rreinst->R1Value(); | 2743 int r1 = rreinst->R1Value(); |
2705 int r2 = rreinst->R2Value(); | 2744 int r2 = rreinst->R2Value(); |
2706 DCHECK(r1 % 2 == 0); | 2745 DCHECK(r1 % 2 == 0); |
2707 | 2746 |
2708 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); | 2747 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); |
2709 uint32_t r2_val = get_low_register<uint32_t>(r2); | 2748 uint32_t r2_val = get_low_register<uint32_t>(r2); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2973 r2_val >>= 48; | 3012 r2_val >>= 48; |
2974 set_register(r1, r2_val); | 3013 set_register(r1, r2_val); |
2975 #else | 3014 #else |
2976 int32_t r2_val = get_low_register<int32_t>(r2); | 3015 int32_t r2_val = get_low_register<int32_t>(r2); |
2977 r2_val <<= 16; | 3016 r2_val <<= 16; |
2978 r2_val >>= 16; | 3017 r2_val >>= 16; |
2979 set_low_register(r1, r2_val); | 3018 set_low_register(r1, r2_val); |
2980 #endif | 3019 #endif |
2981 break; | 3020 break; |
2982 } | 3021 } |
3022 case ALCR: { | |
3023 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr); | |
3024 int r1 = rrinst->R1Value(); | |
3025 int r2 = rrinst->R2Value(); | |
3026 uint32_t r1_val = get_low_register<uint32_t>(r1); | |
3027 uint32_t r2_val = get_low_register<uint32_t>(r2); | |
3028 uint32_t alu_out = 0; | |
3029 bool isOF = false; | |
3030 | |
3031 alu_out = r1_val + r2_val; | |
3032 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val); | |
3033 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) { | |
3034 alu_out = alu_out + 1; | |
3035 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1); | |
3036 } else { | |
3037 isOF = isOF_original; | |
3038 } | |
3039 set_low_register(r1, alu_out); | |
3040 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF); | |
3041 SetS390OverflowCode(isOF); | |
john.yan
2016/03/30 20:48:52
same comment as above.
JoranSiu
2016/03/30 21:39:31
If isOF is true, won't this override the CC set ab
bcleung
2016/03/30 22:23:26
Code for ALCR was copied from AR, which had the Se
| |
3042 break; | |
3043 } | |
2983 default: { return DecodeFourByteFloatingPoint(instr); } | 3044 default: { return DecodeFourByteFloatingPoint(instr); } |
2984 } | 3045 } |
2985 return true; | 3046 return true; |
2986 } | 3047 } |
2987 | 3048 |
2988 void Simulator::DecodeFourByteFloatingPointIntConversion(Instruction* instr) { | 3049 void Simulator::DecodeFourByteFloatingPointIntConversion(Instruction* instr) { |
2989 Opcode op = instr->S390OpcodeValue(); | 3050 Opcode op = instr->S390OpcodeValue(); |
2990 switch (op) { | 3051 switch (op) { |
2991 case CDLFBR: | 3052 case CDLFBR: |
2992 case CDLGBR: | 3053 case CDLGBR: |
(...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5039 uintptr_t address = *stack_slot; | 5100 uintptr_t address = *stack_slot; |
5040 set_register(sp, current_sp + sizeof(uintptr_t)); | 5101 set_register(sp, current_sp + sizeof(uintptr_t)); |
5041 return address; | 5102 return address; |
5042 } | 5103 } |
5043 | 5104 |
5044 } // namespace internal | 5105 } // namespace internal |
5045 } // namespace v8 | 5106 } // namespace v8 |
5046 | 5107 |
5047 #endif // USE_SIMULATOR | 5108 #endif // USE_SIMULATOR |
5048 #endif // V8_TARGET_ARCH_S390 | 5109 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |