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