Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(877)

Side by Side Diff: src/s390/simulator-s390.cc

Issue 2741053004: s390: cleanup old instruction decode routines (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/s390/simulator-s390.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1)) 2405 #define CheckOverflowForMul(src1, src2) (((src1) * (src2)) / (src2) != (src1))
2406 2406
2407 // Method for checking overflow on shift right 2407 // Method for checking overflow on shift right
2408 #define CheckOverflowForShiftRight(src1, src2) \ 2408 #define CheckOverflowForShiftRight(src1, src2) \
2409 (((src1) >> (src2)) << (src2) != (src1)) 2409 (((src1) >> (src2)) << (src2) != (src1))
2410 2410
2411 // Method for checking overflow on shift left 2411 // Method for checking overflow on shift left
2412 #define CheckOverflowForShiftLeft(src1, src2) \ 2412 #define CheckOverflowForShiftLeft(src1, src2) \
2413 (((src1) << (src2)) >> (src2) != (src1)) 2413 (((src1) << (src2)) >> (src2) != (src1))
2414 2414
2415 // S390 Decode and simulate helpers
2416 bool Simulator::DecodeTwoByte(Instruction* instr) {
2417 Opcode op = instr->S390OpcodeValue();
2418
2419 switch (op) {
2420 // RR format instructions
2421 case AR:
2422 case SR:
2423 case MR:
2424 case DR:
2425 case OR:
2426 case NR:
2427 case XR: {
2428 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2429 int r1 = rrinst->R1Value();
2430 int r2 = rrinst->R2Value();
2431 int32_t r1_val = get_low_register<int32_t>(r1);
2432 int32_t r2_val = get_low_register<int32_t>(r2);
2433 bool isOF = false;
2434 switch (op) {
2435 case AR:
2436 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int32_t);
2437 r1_val += r2_val;
2438 SetS390ConditionCode<int32_t>(r1_val, 0);
2439 SetS390OverflowCode(isOF);
2440 break;
2441 case SR:
2442 isOF = CheckOverflowForIntSub(r1_val, r2_val, int32_t);
2443 r1_val -= r2_val;
2444 SetS390ConditionCode<int32_t>(r1_val, 0);
2445 SetS390OverflowCode(isOF);
2446 break;
2447 case OR:
2448 r1_val |= r2_val;
2449 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2450 break;
2451 case NR:
2452 r1_val &= r2_val;
2453 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2454 break;
2455 case XR:
2456 r1_val ^= r2_val;
2457 SetS390BitWiseConditionCode<uint32_t>(r1_val);
2458 break;
2459 case MR: {
2460 DCHECK(r1 % 2 == 0);
2461 r1_val = get_low_register<int32_t>(r1 + 1);
2462 int64_t product =
2463 static_cast<int64_t>(r1_val) * static_cast<int64_t>(r2_val);
2464 int32_t high_bits = product >> 32;
2465 r1_val = high_bits;
2466 int32_t low_bits = product & 0x00000000FFFFFFFF;
2467 set_low_register(r1, high_bits);
2468 set_low_register(r1 + 1, low_bits);
2469 break;
2470 }
2471 case DR: {
2472 // reg-reg pair should be even-odd pair, assert r1 is an even register
2473 DCHECK(r1 % 2 == 0);
2474 // leftmost 32 bits of the dividend are in r1
2475 // rightmost 32 bits of the dividend are in r1+1
2476 // get the signed value from r1
2477 int64_t dividend = static_cast<int64_t>(r1_val) << 32;
2478 // get unsigned value from r1+1
2479 // avoid addition with sign-extended r1+1 value
2480 dividend += get_low_register<uint32_t>(r1 + 1);
2481 int32_t remainder = dividend % r2_val;
2482 int32_t quotient = dividend / r2_val;
2483 r1_val = remainder;
2484 set_low_register(r1, remainder);
2485 set_low_register(r1 + 1, quotient);
2486 break; // reg pair
2487 }
2488 default:
2489 UNREACHABLE();
2490 break;
2491 }
2492 set_low_register(r1, r1_val);
2493 break;
2494 }
2495 case LR: {
2496 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2497 int r1 = rrinst->R1Value();
2498 int r2 = rrinst->R2Value();
2499 set_low_register(r1, get_low_register<int32_t>(r2));
2500 break;
2501 }
2502 case LDR: {
2503 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2504 int r1 = rrinst->R1Value();
2505 int r2 = rrinst->R2Value();
2506 int64_t r2_val = get_d_register(r2);
2507 set_d_register(r1, r2_val);
2508 break;
2509 }
2510 case CR: {
2511 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2512 int r1 = rrinst->R1Value();
2513 int r2 = rrinst->R2Value();
2514 int32_t r1_val = get_low_register<int32_t>(r1);
2515 int32_t r2_val = get_low_register<int32_t>(r2);
2516 SetS390ConditionCode<int32_t>(r1_val, r2_val);
2517 break;
2518 }
2519 case CLR: {
2520 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2521 int r1 = rrinst->R1Value();
2522 int r2 = rrinst->R2Value();
2523 uint32_t r1_val = get_low_register<uint32_t>(r1);
2524 uint32_t r2_val = get_low_register<uint32_t>(r2);
2525 SetS390ConditionCode<uint32_t>(r1_val, r2_val);
2526 break;
2527 }
2528 case BCR: {
2529 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2530 int r1 = rrinst->R1Value();
2531 int r2 = rrinst->R2Value();
2532 if (TestConditionCode(Condition(r1))) {
2533 intptr_t r2_val = get_register(r2);
2534 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2535 // On 31-bit, the top most bit may be 0 or 1, but is ignored by the
2536 // hardware. Cleanse the top bit before jumping to it, unless it's one
2537 // of the special PCs
2538 if (r2_val != bad_lr && r2_val != end_sim_pc) r2_val &= 0x7FFFFFFF;
2539 #endif
2540 set_pc(r2_val);
2541 }
2542 break;
2543 }
2544 case LTR: {
2545 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2546 int r1 = rrinst->R1Value();
2547 int r2 = rrinst->R2Value();
2548 int32_t r2_val = get_low_register<int32_t>(r2);
2549 SetS390ConditionCode<int32_t>(r2_val, 0);
2550 set_low_register(r1, r2_val);
2551 break;
2552 }
2553 case ALR:
2554 case SLR: {
2555 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2556 int r1 = rrinst->R1Value();
2557 int r2 = rrinst->R2Value();
2558 uint32_t r1_val = get_low_register<uint32_t>(r1);
2559 uint32_t r2_val = get_low_register<uint32_t>(r2);
2560 uint32_t alu_out = 0;
2561 bool isOF = false;
2562 if (ALR == op) {
2563 alu_out = r1_val + r2_val;
2564 isOF = CheckOverflowForUIntAdd(r1_val, r2_val);
2565 } else if (SLR == op) {
2566 alu_out = r1_val - r2_val;
2567 isOF = CheckOverflowForUIntSub(r1_val, r2_val);
2568 } else {
2569 UNREACHABLE();
2570 }
2571 set_low_register(r1, alu_out);
2572 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
2573 break;
2574 }
2575 case LNR: {
2576 // Load Negative (32)
2577 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2578 int r1 = rrinst->R1Value();
2579 int r2 = rrinst->R2Value();
2580 int32_t r2_val = get_low_register<int32_t>(r2);
2581 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
2582 set_low_register(r1, r2_val);
2583 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
2584 // CC1 - result is negative
2585 break;
2586 }
2587 case BASR: {
2588 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2589 int r1 = rrinst->R1Value();
2590 int r2 = rrinst->R2Value();
2591 intptr_t link_addr = get_pc() + 2;
2592 // If R2 is zero, the BASR does not branch.
2593 int64_t r2_val = (r2 == 0) ? link_addr : get_register(r2);
2594 #if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
2595 // On 31-bit, the top most bit may be 0 or 1, which can cause issues
2596 // for stackwalker. The top bit should either be cleanse before being
2597 // pushed onto the stack, or during stack walking when dereferenced.
2598 // For simulator, we'll take the worst case scenario and always tag
2599 // the high bit, to flush out more problems.
2600 link_addr |= 0x80000000;
2601 #endif
2602 set_register(r1, link_addr);
2603 set_pc(r2_val);
2604 break;
2605 }
2606 case LCR: {
2607 RRInstruction* rrinst = reinterpret_cast<RRInstruction*>(instr);
2608 int r1 = rrinst->R1Value();
2609 int r2 = rrinst->R2Value();
2610 int32_t r2_val = get_low_register<int32_t>(r2);
2611 int32_t original_r2_val = r2_val;
2612 r2_val = ~r2_val;
2613 r2_val = r2_val + 1;
2614 set_low_register(r1, r2_val);
2615 SetS390ConditionCode<int32_t>(r2_val, 0);
2616 // Checks for overflow where r2_val = -2147483648.
2617 // Cannot do int comparison due to GCC 4.8 bug on x86.
2618 // Detect INT_MIN alternatively, as it is the only value where both
2619 // original and result are negative due to overflow.
2620 if (r2_val < 0 && original_r2_val < 0) {
2621 SetS390OverflowCode(true);
2622 }
2623 break;
2624 }
2625 case BKPT: {
2626 set_pc(get_pc() + 2);
2627 S390Debugger dbg(this);
2628 dbg.Debug();
2629 break;
2630 }
2631 default:
2632 UNREACHABLE();
2633 return false;
2634 break;
2635 }
2636 return true;
2637 }
2638
2639 // Decode routine for four-byte instructions
2640 bool Simulator::DecodeFourByte(Instruction* instr) {
2641 Opcode op = instr->S390OpcodeValue();
2642
2643 // Pre-cast instruction to various types
2644 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
2645 SIInstruction* siInstr = reinterpret_cast<SIInstruction*>(instr);
2646
2647 switch (op) {
2648 case POPCNT_Z: {
2649 int r1 = rreInst->R1Value();
2650 int r2 = rreInst->R2Value();
2651 int64_t r2_val = get_register(r2);
2652 int64_t r1_val = 0;
2653
2654 uint8_t* r2_val_ptr = reinterpret_cast<uint8_t*>(&r2_val);
2655 uint8_t* r1_val_ptr = reinterpret_cast<uint8_t*>(&r1_val);
2656 for (int i = 0; i < 8; i++) {
2657 uint32_t x = static_cast<uint32_t>(r2_val_ptr[i]);
2658 #if defined(__GNUC__)
2659 r1_val_ptr[i] = __builtin_popcount(x);
2660 #else
2661 #error unsupport __builtin_popcount
2662 #endif
2663 }
2664
2665 set_register(r1, static_cast<uint64_t>(r1_val));
2666 break;
2667 }
2668 case LLGFR: {
2669 int r1 = rreInst->R1Value();
2670 int r2 = rreInst->R2Value();
2671 int32_t r2_val = get_low_register<int32_t>(r2);
2672 uint64_t r2_finalval =
2673 (static_cast<uint64_t>(r2_val) & 0x00000000ffffffff);
2674 set_register(r1, r2_finalval);
2675 break;
2676 }
2677 case EX: {
2678 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2679 int r1 = rxinst->R1Value();
2680 int b2 = rxinst->B2Value();
2681 int x2 = rxinst->X2Value();
2682 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2683 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2684 intptr_t d2_val = rxinst->D2Value();
2685 int32_t r1_val = get_low_register<int32_t>(r1);
2686
2687 SixByteInstr the_instr = Instruction::InstructionBits(
2688 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2689 int length = Instruction::InstructionLength(
2690 reinterpret_cast<const byte*>(b2_val + x2_val + d2_val));
2691
2692 char new_instr_buf[8];
2693 char* addr = reinterpret_cast<char*>(&new_instr_buf[0]);
2694 the_instr |= static_cast<SixByteInstr>(r1_val & 0xff)
2695 << (8 * length - 16);
2696 Instruction::SetInstructionBits<SixByteInstr>(
2697 reinterpret_cast<byte*>(addr), static_cast<SixByteInstr>(the_instr));
2698 ExecuteInstruction(reinterpret_cast<Instruction*>(addr), false);
2699 break;
2700 }
2701 case LGR: {
2702 // Load Register (64)
2703 int r1 = rreInst->R1Value();
2704 int r2 = rreInst->R2Value();
2705 set_register(r1, get_register(r2));
2706 break;
2707 }
2708 case LDGR: {
2709 // Load FPR from GPR (L <- 64)
2710 uint64_t int_val = get_register(rreInst->R2Value());
2711 // double double_val = bit_cast<double, uint64_t>(int_val);
2712 // set_d_register_from_double(rreInst->R1Value(), double_val);
2713 set_d_register(rreInst->R1Value(), int_val);
2714 break;
2715 }
2716 case LGDR: {
2717 // Load GPR from FPR (64 <- L)
2718 int64_t double_val = get_d_register(rreInst->R2Value());
2719 set_register(rreInst->R1Value(), double_val);
2720 break;
2721 }
2722 case LTGR: {
2723 // Load Register (64)
2724 int r1 = rreInst->R1Value();
2725 int r2 = rreInst->R2Value();
2726 int64_t r2_val = get_register(r2);
2727 SetS390ConditionCode<int64_t>(r2_val, 0);
2728 set_register(r1, get_register(r2));
2729 break;
2730 }
2731 case LZDR: {
2732 int r1 = rreInst->R1Value();
2733 set_d_register_from_double(r1, 0.0);
2734 break;
2735 }
2736 case LTEBR: {
2737 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2738 int r1 = rreinst->R1Value();
2739 int r2 = rreinst->R2Value();
2740 int64_t r2_val = get_d_register(r2);
2741 float fr2_val = get_float32_from_d_register(r2);
2742 SetS390ConditionCode<float>(fr2_val, 0.0);
2743 set_d_register(r1, r2_val);
2744 break;
2745 }
2746 case LTDBR: {
2747 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
2748 int r1 = rreinst->R1Value();
2749 int r2 = rreinst->R2Value();
2750 int64_t r2_val = get_d_register(r2);
2751 SetS390ConditionCode<double>(bit_cast<double, int64_t>(r2_val), 0.0);
2752 set_d_register(r1, r2_val);
2753 break;
2754 }
2755 case CGR: {
2756 // Compare (64)
2757 int64_t r1_val = get_register(rreInst->R1Value());
2758 int64_t r2_val = get_register(rreInst->R2Value());
2759 SetS390ConditionCode<int64_t>(r1_val, r2_val);
2760 break;
2761 }
2762 case CLGR: {
2763 // Compare Logical (64)
2764 uint64_t r1_val = static_cast<uint64_t>(get_register(rreInst->R1Value()));
2765 uint64_t r2_val = static_cast<uint64_t>(get_register(rreInst->R2Value()));
2766 SetS390ConditionCode<uint64_t>(r1_val, r2_val);
2767 break;
2768 }
2769 case LH: {
2770 // Load Halfword
2771 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2772 int r1 = rxinst->R1Value();
2773 int x2 = rxinst->X2Value();
2774 int b2 = rxinst->B2Value();
2775
2776 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
2777 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2778 intptr_t d2_val = rxinst->D2Value();
2779 intptr_t mem_addr = x2_val + b2_val + d2_val;
2780
2781 int32_t result = static_cast<int32_t>(ReadH(mem_addr, instr));
2782 set_low_register(r1, result);
2783 break;
2784 }
2785 case LHI: {
2786 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2787 int r1 = riinst->R1Value();
2788 int i = riinst->I2Value();
2789 set_low_register(r1, i);
2790 break;
2791 }
2792 case LGHI: {
2793 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2794 int r1 = riinst->R1Value();
2795 int64_t i = riinst->I2Value();
2796 set_register(r1, i);
2797 break;
2798 }
2799 case CHI: {
2800 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2801 int r1 = riinst->R1Value();
2802 int16_t i = riinst->I2Value();
2803 int32_t r1_val = get_low_register<int32_t>(r1);
2804 SetS390ConditionCode<int32_t>(r1_val, i);
2805 break;
2806 }
2807 case CGHI: {
2808 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2809 int r1 = riinst->R1Value();
2810 int64_t i = static_cast<int64_t>(riinst->I2Value());
2811 int64_t r1_val = get_register(r1);
2812 SetS390ConditionCode<int64_t>(r1_val, i);
2813 break;
2814 }
2815 case BRAS: {
2816 // Branch Relative and Save
2817 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
2818 int r1 = rilInstr->R1Value();
2819 intptr_t d2 = rilInstr->I2Value();
2820 intptr_t pc = get_pc();
2821 // Set PC of next instruction to register
2822 set_register(r1, pc + sizeof(FourByteInstr));
2823 // Update PC to branch target
2824 set_pc(pc + d2 * 2);
2825 break;
2826 }
2827 case BRC: {
2828 // Branch Relative on Condition
2829 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2830 int m1 = riinst->M1Value();
2831 if (TestConditionCode((Condition)m1)) {
2832 intptr_t offset = riinst->I2Value() * 2;
2833 set_pc(get_pc() + offset);
2834 }
2835 break;
2836 }
2837 case BRCT:
2838 case BRCTG: {
2839 // Branch On Count (32/64).
2840 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
2841 int r1 = riinst->R1Value();
2842 int64_t value =
2843 (op == BRCT) ? get_low_register<int32_t>(r1) : get_register(r1);
2844 if (BRCT == op)
2845 set_low_register(r1, --value);
2846 else
2847 set_register(r1, --value);
2848 // Branch if value != 0
2849 if (value != 0) {
2850 intptr_t offset = riinst->I2Value() * 2;
2851 set_pc(get_pc() + offset);
2852 }
2853 break;
2854 }
2855 case BXH: {
2856 RSInstruction* rsinst = reinterpret_cast<RSInstruction*>(instr);
2857 int r1 = rsinst->R1Value();
2858 int r3 = rsinst->R3Value();
2859 int b2 = rsinst->B2Value();
2860 int d2 = rsinst->D2Value();
2861
2862 // r1_val is the first operand, r3_val is the increment
2863 int32_t r1_val = r1 == 0 ? 0 : get_register(r1);
2864 int32_t r3_val = r2 == 0 ? 0 : get_register(r3);
2865 intptr_t b2_val = b2 == 0 ? 0 : get_register(b2);
2866 intptr_t branch_address = b2_val + d2;
2867 // increment r1_val
2868 r1_val += r3_val;
2869
2870 // if the increment is even, then it designates a pair of registers
2871 // and the contents of the even and odd registers of the pair are used as
2872 // the increment and compare value respectively. If the increment is odd,
2873 // the increment itself is used as both the increment and compare value
2874 int32_t compare_val = r3 % 2 == 0 ? get_register(r3 + 1) : r3_val;
2875 if (r1_val > compare_val) {
2876 // branch to address if r1_val is greater than compare value
2877 set_pc(branch_address);
2878 }
2879
2880 // update contents of register in r1 with the new incremented value
2881 set_register(r1, r1_val);
2882 break;
2883 }
2884 case IIHH:
2885 case IIHL:
2886 case IILH:
2887 case IILL: {
2888 UNIMPLEMENTED();
2889 break;
2890 }
2891 case STM:
2892 case LM: {
2893 // Store Multiple 32-bits.
2894 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
2895 int r1 = rsinstr->R1Value();
2896 int r3 = rsinstr->R3Value();
2897 int rb = rsinstr->B2Value();
2898 int offset = rsinstr->D2Value();
2899
2900 // Regs roll around if r3 is less than r1.
2901 // Artifically increase r3 by 16 so we can calculate
2902 // the number of regs stored properly.
2903 if (r3 < r1) r3 += 16;
2904
2905 int32_t rb_val = (rb == 0) ? 0 : get_low_register<int32_t>(rb);
2906
2907 // Store each register in ascending order.
2908 for (int i = 0; i <= r3 - r1; i++) {
2909 if (op == STM) {
2910 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
2911 WriteW(rb_val + offset + 4 * i, value, instr);
2912 } else if (op == LM) {
2913 int32_t value = ReadW(rb_val + offset + 4 * i, instr);
2914 set_low_register((r1 + i) % 16, value);
2915 }
2916 }
2917 break;
2918 }
2919 case SLL:
2920 case SRL: {
2921 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2922 int r1 = rsInstr->R1Value();
2923 int b2 = rsInstr->B2Value();
2924 intptr_t d2 = rsInstr->D2Value();
2925 // only takes rightmost 6bits
2926 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2927 int shiftBits = (b2_val + d2) & 0x3F;
2928 uint32_t r1_val = get_low_register<uint32_t>(r1);
2929 uint32_t alu_out = 0;
2930 if (SLL == op) {
2931 alu_out = r1_val << shiftBits;
2932 } else if (SRL == op) {
2933 alu_out = r1_val >> shiftBits;
2934 } else {
2935 UNREACHABLE();
2936 }
2937 set_low_register(r1, alu_out);
2938 break;
2939 }
2940 case SLDL: {
2941 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2942 int r1 = rsInstr->R1Value();
2943 int b2 = rsInstr->B2Value();
2944 intptr_t d2 = rsInstr->D2Value();
2945 // only takes rightmost 6bits
2946 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2947 int shiftBits = (b2_val + d2) & 0x3F;
2948
2949 DCHECK(r1 % 2 == 0);
2950 uint32_t r1_val = get_low_register<uint32_t>(r1);
2951 uint32_t r1_next_val = get_low_register<uint32_t>(r1 + 1);
2952 uint64_t alu_out = (static_cast<uint64_t>(r1_val) << 32) |
2953 (static_cast<uint64_t>(r1_next_val));
2954 alu_out <<= shiftBits;
2955 set_low_register(r1 + 1, static_cast<uint32_t>(alu_out));
2956 set_low_register(r1, static_cast<uint32_t>(alu_out >> 32));
2957 break;
2958 }
2959 case SLA:
2960 case SRA: {
2961 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
2962 int r1 = rsInstr->R1Value();
2963 int b2 = rsInstr->B2Value();
2964 intptr_t d2 = rsInstr->D2Value();
2965 // only takes rightmost 6bits
2966 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
2967 int shiftBits = (b2_val + d2) & 0x3F;
2968 int32_t r1_val = get_low_register<int32_t>(r1);
2969 int32_t alu_out = 0;
2970 bool isOF = false;
2971 if (op == SLA) {
2972 isOF = CheckOverflowForShiftLeft(r1_val, shiftBits);
2973 alu_out = r1_val << shiftBits;
2974 } else if (op == SRA) {
2975 alu_out = r1_val >> shiftBits;
2976 }
2977 set_low_register(r1, alu_out);
2978 SetS390ConditionCode<int32_t>(alu_out, 0);
2979 SetS390OverflowCode(isOF);
2980 break;
2981 }
2982 case LLHR: {
2983 UNIMPLEMENTED();
2984 break;
2985 }
2986 case LLGHR: {
2987 UNIMPLEMENTED();
2988 break;
2989 }
2990 case L:
2991 case LA:
2992 case LD:
2993 case LE: {
2994 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
2995 int b2 = rxinst->B2Value();
2996 int x2 = rxinst->X2Value();
2997 int32_t r1 = rxinst->R1Value();
2998 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
2999 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3000 intptr_t d2_val = rxinst->D2Value();
3001 intptr_t addr = b2_val + x2_val + d2_val;
3002 if (op == L) {
3003 int32_t mem_val = ReadW(addr, instr);
3004 set_low_register(r1, mem_val);
3005 } else if (op == LA) {
3006 set_register(r1, addr);
3007 } else if (op == LD) {
3008 int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
3009 set_d_register(r1, dbl_val);
3010 } else if (op == LE) {
3011 float float_val = *reinterpret_cast<float*>(addr);
3012 set_d_register_from_float32(r1, float_val);
3013 }
3014 break;
3015 }
3016 case C:
3017 case CL: {
3018 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3019 int b2 = rxinst->B2Value();
3020 int x2 = rxinst->X2Value();
3021 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3022 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3023 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3024 intptr_t d2_val = rxinst->D2Value();
3025 intptr_t addr = b2_val + x2_val + d2_val;
3026 int32_t mem_val = ReadW(addr, instr);
3027 if (C == op)
3028 SetS390ConditionCode<int32_t>(r1_val, mem_val);
3029 else if (CL == op)
3030 SetS390ConditionCode<uint32_t>(r1_val, mem_val);
3031 break;
3032 }
3033 case CLI: {
3034 // Compare Immediate (Mem - Imm) (8)
3035 int b1 = siInstr->B1Value();
3036 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3037 intptr_t d1_val = siInstr->D1Value();
3038 intptr_t addr = b1_val + d1_val;
3039 uint8_t mem_val = ReadB(addr);
3040 uint8_t imm_val = siInstr->I2Value();
3041 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
3042 break;
3043 }
3044 case TM: {
3045 // Test Under Mask (Mem - Imm) (8)
3046 int b1 = siInstr->B1Value();
3047 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
3048 intptr_t d1_val = siInstr->D1Value();
3049 intptr_t addr = b1_val + d1_val;
3050 uint8_t mem_val = ReadB(addr);
3051 uint8_t imm_val = siInstr->I2Value();
3052 uint8_t selected_bits = mem_val & imm_val;
3053 // CC0: Selected bits are zero
3054 // CC1: Selected bits mixed zeros and ones
3055 // CC3: Selected bits all ones
3056 if (0 == selected_bits) {
3057 condition_reg_ = CC_EQ; // CC0
3058 } else if (selected_bits == imm_val) {
3059 condition_reg_ = 0x1; // CC3
3060 } else {
3061 condition_reg_ = 0x4; // CC1
3062 }
3063 break;
3064 }
3065 case ST:
3066 case STE:
3067 case STD: {
3068 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3069 int b2 = rxinst->B2Value();
3070 int x2 = rxinst->X2Value();
3071 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3072 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3073 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3074 intptr_t d2_val = rxinst->D2Value();
3075 intptr_t addr = b2_val + x2_val + d2_val;
3076 if (op == ST) {
3077 WriteW(addr, r1_val, instr);
3078 } else if (op == STD) {
3079 int64_t frs_val = get_d_register(rxinst->R1Value());
3080 WriteDW(addr, frs_val);
3081 } else if (op == STE) {
3082 int64_t frs_val = get_d_register(rxinst->R1Value()) >> 32;
3083 WriteW(addr, static_cast<int32_t>(frs_val), instr);
3084 }
3085 break;
3086 }
3087 case LTGFR:
3088 case LGFR: {
3089 // Load and Test Register (64 <- 32) (Sign Extends 32-bit val)
3090 // Load Register (64 <- 32) (Sign Extends 32-bit val)
3091 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3092 int r1 = rreInstr->R1Value();
3093 int r2 = rreInstr->R2Value();
3094 int32_t r2_val = get_low_register<int32_t>(r2);
3095 int64_t result = static_cast<int64_t>(r2_val);
3096 set_register(r1, result);
3097
3098 if (LTGFR == op) SetS390ConditionCode<int64_t>(result, 0);
3099 break;
3100 }
3101 case LNGR: {
3102 // Load Negative (64)
3103 int r1 = rreInst->R1Value();
3104 int r2 = rreInst->R2Value();
3105 int64_t r2_val = get_register(r2);
3106 r2_val = (r2_val >= 0) ? -r2_val : r2_val; // If pos, then negate it.
3107 set_register(r1, r2_val);
3108 condition_reg_ = (r2_val == 0) ? CC_EQ : CC_LT; // CC0 - result is zero
3109 // CC1 - result is negative
3110 break;
3111 }
3112 case TRAP4: {
3113 // whack the space of the caller allocated stack
3114 int64_t sp_addr = get_register(sp);
3115 for (int i = 0; i < kCalleeRegisterSaveAreaSize / kPointerSize; ++i) {
3116 // we dont want to whack the RA (r14)
3117 if (i != 14) (reinterpret_cast<intptr_t*>(sp_addr))[i] = 0xdeadbabe;
3118 }
3119 SoftwareInterrupt(instr);
3120 break;
3121 }
3122 case STC: {
3123 // Store Character/Byte
3124 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3125 int b2 = rxinst->B2Value();
3126 int x2 = rxinst->X2Value();
3127 uint8_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3128 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3129 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3130 intptr_t d2_val = rxinst->D2Value();
3131 intptr_t mem_addr = b2_val + x2_val + d2_val;
3132 WriteB(mem_addr, r1_val);
3133 break;
3134 }
3135 case STH: {
3136 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3137 int b2 = rxinst->B2Value();
3138 int x2 = rxinst->X2Value();
3139 int16_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3140 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3141 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3142 intptr_t d2_val = rxinst->D2Value();
3143 intptr_t mem_addr = b2_val + x2_val + d2_val;
3144 WriteH(mem_addr, r1_val, instr);
3145 break;
3146 }
3147 #if V8_TARGET_ARCH_S390X
3148 case LCGR: {
3149 int r1 = rreInst->R1Value();
3150 int r2 = rreInst->R2Value();
3151 int64_t r2_val = get_register(r2);
3152 r2_val = ~r2_val;
3153 r2_val = r2_val + 1;
3154 set_register(r1, r2_val);
3155 SetS390ConditionCode<int64_t>(r2_val, 0);
3156 // if the input is INT_MIN, loading its compliment would be overflowing
3157 if (r2_val < 0 && (r2_val + 1) > 0) {
3158 SetS390OverflowCode(true);
3159 }
3160 break;
3161 }
3162 #endif
3163 case SRDA: {
3164 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3165 int r1 = rsInstr->R1Value();
3166 DCHECK(r1 % 2 == 0); // must be a reg pair
3167 int b2 = rsInstr->B2Value();
3168 intptr_t d2 = rsInstr->D2Value();
3169 // only takes rightmost 6bits
3170 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3171 int shiftBits = (b2_val + d2) & 0x3F;
3172 int64_t opnd1 = static_cast<int64_t>(get_low_register<int32_t>(r1)) << 32;
3173 int64_t opnd2 = static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3174 int64_t r1_val = opnd1 + opnd2;
3175 int64_t alu_out = r1_val >> shiftBits;
3176 set_low_register(r1, alu_out >> 32);
3177 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3178 SetS390ConditionCode<int32_t>(alu_out, 0);
3179 break;
3180 }
3181 case SRDL: {
3182 RSInstruction* rsInstr = reinterpret_cast<RSInstruction*>(instr);
3183 int r1 = rsInstr->R1Value();
3184 DCHECK(r1 % 2 == 0); // must be a reg pair
3185 int b2 = rsInstr->B2Value();
3186 intptr_t d2 = rsInstr->D2Value();
3187 // only takes rightmost 6bits
3188 int64_t b2_val = b2 == 0 ? 0 : get_register(b2);
3189 int shiftBits = (b2_val + d2) & 0x3F;
3190 uint64_t opnd1 = static_cast<uint64_t>(get_low_register<uint32_t>(r1))
3191 << 32;
3192 uint64_t opnd2 =
3193 static_cast<uint64_t>(get_low_register<uint32_t>(r1 + 1));
3194 uint64_t r1_val = opnd1 | opnd2;
3195 uint64_t alu_out = r1_val >> shiftBits;
3196 set_low_register(r1, alu_out >> 32);
3197 set_low_register(r1 + 1, alu_out & 0x00000000FFFFFFFF);
3198 SetS390ConditionCode<int32_t>(alu_out, 0);
3199 break;
3200 }
3201 default: { return DecodeFourByteArithmetic(instr); }
3202 }
3203 return true;
3204 }
3205
3206 bool Simulator::DecodeFourByteArithmetic64Bit(Instruction* instr) {
3207 Opcode op = instr->S390OpcodeValue();
3208
3209 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3210 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3211
3212 switch (op) {
3213 case AGR:
3214 case SGR:
3215 case OGR:
3216 case NGR:
3217 case XGR: {
3218 int r1 = rreInst->R1Value();
3219 int r2 = rreInst->R2Value();
3220 int64_t r1_val = get_register(r1);
3221 int64_t r2_val = get_register(r2);
3222 bool isOF = false;
3223 switch (op) {
3224 case AGR:
3225 isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3226 r1_val += r2_val;
3227 SetS390ConditionCode<int64_t>(r1_val, 0);
3228 SetS390OverflowCode(isOF);
3229 break;
3230 case SGR:
3231 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3232 r1_val -= r2_val;
3233 SetS390ConditionCode<int64_t>(r1_val, 0);
3234 SetS390OverflowCode(isOF);
3235 break;
3236 case OGR:
3237 r1_val |= r2_val;
3238 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3239 break;
3240 case NGR:
3241 r1_val &= r2_val;
3242 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3243 break;
3244 case XGR:
3245 r1_val ^= r2_val;
3246 SetS390BitWiseConditionCode<uint64_t>(r1_val);
3247 break;
3248 default:
3249 UNREACHABLE();
3250 break;
3251 }
3252 set_register(r1, r1_val);
3253 break;
3254 }
3255 case AGFR: {
3256 // Add Register (64 <- 32) (Sign Extends 32-bit val)
3257 int r1 = rreInst->R1Value();
3258 int r2 = rreInst->R2Value();
3259 int64_t r1_val = get_register(r1);
3260 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3261 bool isOF = CheckOverflowForIntAdd(r1_val, r2_val, int64_t);
3262 r1_val += r2_val;
3263 SetS390ConditionCode<int64_t>(r1_val, 0);
3264 SetS390OverflowCode(isOF);
3265 set_register(r1, r1_val);
3266 break;
3267 }
3268 case SGFR: {
3269 // Sub Reg (64 <- 32)
3270 int r1 = rreInst->R1Value();
3271 int r2 = rreInst->R2Value();
3272 int64_t r1_val = get_register(r1);
3273 int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2));
3274 bool isOF = false;
3275 isOF = CheckOverflowForIntSub(r1_val, r2_val, int64_t);
3276 r1_val -= r2_val;
3277 SetS390ConditionCode<int64_t>(r1_val, 0);
3278 SetS390OverflowCode(isOF);
3279 set_register(r1, r1_val);
3280 break;
3281 }
3282 case AGRK:
3283 case SGRK:
3284 case NGRK:
3285 case OGRK:
3286 case XGRK: {
3287 // 64-bit Non-clobbering arithmetics / bitwise ops.
3288 int r1 = rrfInst->R1Value();
3289 int r2 = rrfInst->R2Value();
3290 int r3 = rrfInst->R3Value();
3291 int64_t r2_val = get_register(r2);
3292 int64_t r3_val = get_register(r3);
3293 if (AGRK == op) {
3294 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int64_t);
3295 SetS390ConditionCode<int64_t>(r2_val + r3_val, 0);
3296 SetS390OverflowCode(isOF);
3297 set_register(r1, r2_val + r3_val);
3298 } else if (SGRK == op) {
3299 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int64_t);
3300 SetS390ConditionCode<int64_t>(r2_val - r3_val, 0);
3301 SetS390OverflowCode(isOF);
3302 set_register(r1, r2_val - r3_val);
3303 } else {
3304 // Assume bitwise operation here
3305 uint64_t bitwise_result = 0;
3306 if (NGRK == op) {
3307 bitwise_result = r2_val & r3_val;
3308 } else if (OGRK == op) {
3309 bitwise_result = r2_val | r3_val;
3310 } else if (XGRK == op) {
3311 bitwise_result = r2_val ^ r3_val;
3312 }
3313 SetS390BitWiseConditionCode<uint64_t>(bitwise_result);
3314 set_register(r1, bitwise_result);
3315 }
3316 break;
3317 }
3318 case ALGRK:
3319 case SLGRK: {
3320 // 64-bit Non-clobbering unsigned arithmetics
3321 int r1 = rrfInst->R1Value();
3322 int r2 = rrfInst->R2Value();
3323 int r3 = rrfInst->R3Value();
3324 uint64_t r2_val = get_register(r2);
3325 uint64_t r3_val = get_register(r3);
3326 if (ALGRK == op) {
3327 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3328 SetS390ConditionCode<uint64_t>(r2_val + r3_val, 0);
3329 SetS390OverflowCode(isOF);
3330 set_register(r1, r2_val + r3_val);
3331 } else if (SLGRK == op) {
3332 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3333 SetS390ConditionCode<uint64_t>(r2_val - r3_val, 0);
3334 SetS390OverflowCode(isOF);
3335 set_register(r1, r2_val - r3_val);
3336 }
3337 break;
3338 }
3339 case AGHI:
3340 case MGHI: {
3341 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3342 int32_t r1 = riinst->R1Value();
3343 int64_t i = static_cast<int64_t>(riinst->I2Value());
3344 int64_t r1_val = get_register(r1);
3345 bool isOF = false;
3346 switch (op) {
3347 case AGHI:
3348 isOF = CheckOverflowForIntAdd(r1_val, i, int64_t);
3349 r1_val += i;
3350 break;
3351 case MGHI:
3352 isOF = CheckOverflowForMul(r1_val, i);
3353 r1_val *= i;
3354 break; // no overflow indication is given
3355 default:
3356 break;
3357 }
3358 set_register(r1, r1_val);
3359 SetS390ConditionCode<int32_t>(r1_val, 0);
3360 SetS390OverflowCode(isOF);
3361 break;
3362 }
3363 default:
3364 UNREACHABLE();
3365 }
3366 return true;
3367 }
3368
3369 /**
3370 * Decodes and simulates four byte arithmetic instructions
3371 */
3372 bool Simulator::DecodeFourByteArithmetic(Instruction* instr) {
3373 Opcode op = instr->S390OpcodeValue();
3374
3375 // Pre-cast instruction to various types
3376 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
3377
3378 switch (op) {
3379 case AGR:
3380 case SGR:
3381 case OGR:
3382 case NGR:
3383 case XGR:
3384 case AGFR:
3385 case SGFR: {
3386 DecodeFourByteArithmetic64Bit(instr);
3387 break;
3388 }
3389 case ARK:
3390 case SRK:
3391 case NRK:
3392 case ORK:
3393 case XRK: {
3394 // 32-bit Non-clobbering arithmetics / bitwise ops
3395 int r1 = rrfInst->R1Value();
3396 int r2 = rrfInst->R2Value();
3397 int r3 = rrfInst->R3Value();
3398 int32_t r2_val = get_low_register<int32_t>(r2);
3399 int32_t r3_val = get_low_register<int32_t>(r3);
3400 if (ARK == op) {
3401 bool isOF = CheckOverflowForIntAdd(r2_val, r3_val, int32_t);
3402 SetS390ConditionCode<int32_t>(r2_val + r3_val, 0);
3403 SetS390OverflowCode(isOF);
3404 set_low_register(r1, r2_val + r3_val);
3405 } else if (SRK == op) {
3406 bool isOF = CheckOverflowForIntSub(r2_val, r3_val, int32_t);
3407 SetS390ConditionCode<int32_t>(r2_val - r3_val, 0);
3408 SetS390OverflowCode(isOF);
3409 set_low_register(r1, r2_val - r3_val);
3410 } else {
3411 // Assume bitwise operation here
3412 uint32_t bitwise_result = 0;
3413 if (NRK == op) {
3414 bitwise_result = r2_val & r3_val;
3415 } else if (ORK == op) {
3416 bitwise_result = r2_val | r3_val;
3417 } else if (XRK == op) {
3418 bitwise_result = r2_val ^ r3_val;
3419 }
3420 SetS390BitWiseConditionCode<uint32_t>(bitwise_result);
3421 set_low_register(r1, bitwise_result);
3422 }
3423 break;
3424 }
3425 case ALRK:
3426 case SLRK: {
3427 // 32-bit Non-clobbering unsigned arithmetics
3428 int r1 = rrfInst->R1Value();
3429 int r2 = rrfInst->R2Value();
3430 int r3 = rrfInst->R3Value();
3431 uint32_t r2_val = get_low_register<uint32_t>(r2);
3432 uint32_t r3_val = get_low_register<uint32_t>(r3);
3433 if (ALRK == op) {
3434 bool isOF = CheckOverflowForUIntAdd(r2_val, r3_val);
3435 SetS390ConditionCode<uint32_t>(r2_val + r3_val, 0);
3436 SetS390OverflowCode(isOF);
3437 set_low_register(r1, r2_val + r3_val);
3438 } else if (SLRK == op) {
3439 bool isOF = CheckOverflowForUIntSub(r2_val, r3_val);
3440 SetS390ConditionCode<uint32_t>(r2_val - r3_val, 0);
3441 SetS390OverflowCode(isOF);
3442 set_low_register(r1, r2_val - r3_val);
3443 }
3444 break;
3445 }
3446 case AGRK:
3447 case SGRK:
3448 case NGRK:
3449 case OGRK:
3450 case XGRK: {
3451 DecodeFourByteArithmetic64Bit(instr);
3452 break;
3453 }
3454 case ALGRK:
3455 case SLGRK: {
3456 DecodeFourByteArithmetic64Bit(instr);
3457 break;
3458 }
3459 case AHI:
3460 case MHI: {
3461 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
3462 int32_t r1 = riinst->R1Value();
3463 int32_t i = riinst->I2Value();
3464 int32_t r1_val = get_low_register<int32_t>(r1);
3465 bool isOF = false;
3466 switch (op) {
3467 case AHI:
3468 isOF = CheckOverflowForIntAdd(r1_val, i, int32_t);
3469 r1_val += i;
3470 break;
3471 case MHI:
3472 isOF = CheckOverflowForMul(r1_val, i);
3473 r1_val *= i;
3474 break; // no overflow indication is given
3475 default:
3476 break;
3477 }
3478 set_low_register(r1, r1_val);
3479 SetS390ConditionCode<int32_t>(r1_val, 0);
3480 SetS390OverflowCode(isOF);
3481 break;
3482 }
3483 case AGHI:
3484 case MGHI: {
3485 DecodeFourByteArithmetic64Bit(instr);
3486 break;
3487 }
3488 case MLR: {
3489 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3490 int r1 = rreinst->R1Value();
3491 int r2 = rreinst->R2Value();
3492 DCHECK(r1 % 2 == 0);
3493
3494 uint32_t r1_val = get_low_register<uint32_t>(r1 + 1);
3495 uint32_t r2_val = get_low_register<uint32_t>(r2);
3496 uint64_t product =
3497 static_cast<uint64_t>(r1_val) * static_cast<uint64_t>(r2_val);
3498 int32_t high_bits = product >> 32;
3499 int32_t low_bits = product & 0x00000000FFFFFFFF;
3500 set_low_register(r1, high_bits);
3501 set_low_register(r1 + 1, low_bits);
3502 break;
3503 }
3504 case DLGR: {
3505 #ifdef V8_TARGET_ARCH_S390X
3506 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3507 int r1 = rreinst->R1Value();
3508 int r2 = rreinst->R2Value();
3509 uint64_t r1_val = get_register(r1);
3510 uint64_t r2_val = get_register(r2);
3511 DCHECK(r1 % 2 == 0);
3512 unsigned __int128 dividend = static_cast<unsigned __int128>(r1_val) << 64;
3513 dividend += get_register(r1 + 1);
3514 uint64_t remainder = dividend % r2_val;
3515 uint64_t quotient = dividend / r2_val;
3516 r1_val = remainder;
3517 set_register(r1, remainder);
3518 set_register(r1 + 1, quotient);
3519 #else
3520 UNREACHABLE();
3521 #endif
3522 break;
3523 }
3524 case DLR: {
3525 RREInstruction* rreinst = reinterpret_cast<RREInstruction*>(instr);
3526 int r1 = rreinst->R1Value();
3527 int r2 = rreinst->R2Value();
3528 uint32_t r1_val = get_low_register<uint32_t>(r1);
3529 uint32_t r2_val = get_low_register<uint32_t>(r2);
3530 DCHECK(r1 % 2 == 0);
3531 uint64_t dividend = static_cast<uint64_t>(r1_val) << 32;
3532 dividend += get_low_register<uint32_t>(r1 + 1);
3533 uint32_t remainder = dividend % r2_val;
3534 uint32_t quotient = dividend / r2_val;
3535 r1_val = remainder;
3536 set_low_register(r1, remainder);
3537 set_low_register(r1 + 1, quotient);
3538 break;
3539 }
3540 case A:
3541 case S:
3542 case M:
3543 case D:
3544 case O:
3545 case N:
3546 case X: {
3547 // 32-bit Reg-Mem instructions
3548 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3549 int b2 = rxinst->B2Value();
3550 int x2 = rxinst->X2Value();
3551 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3552 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3553 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3554 intptr_t d2_val = rxinst->D2Value();
3555 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3556 int32_t alu_out = 0;
3557 bool isOF = false;
3558 switch (op) {
3559 case A:
3560 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3561 alu_out = r1_val + mem_val;
3562 SetS390ConditionCode<int32_t>(alu_out, 0);
3563 SetS390OverflowCode(isOF);
3564 break;
3565 case S:
3566 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3567 alu_out = r1_val - mem_val;
3568 SetS390ConditionCode<int32_t>(alu_out, 0);
3569 SetS390OverflowCode(isOF);
3570 break;
3571 case M:
3572 case D:
3573 UNIMPLEMENTED();
3574 break;
3575 case O:
3576 alu_out = r1_val | mem_val;
3577 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3578 break;
3579 case N:
3580 alu_out = r1_val & mem_val;
3581 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3582 break;
3583 case X:
3584 alu_out = r1_val ^ mem_val;
3585 SetS390BitWiseConditionCode<uint32_t>(alu_out);
3586 break;
3587 default:
3588 UNREACHABLE();
3589 break;
3590 }
3591 set_low_register(r1, alu_out);
3592 break;
3593 }
3594 case OILL:
3595 case OIHL: {
3596 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3597 int r1 = riInst->R1Value();
3598 int i = riInst->I2Value();
3599 int32_t r1_val = get_low_register<int32_t>(r1);
3600 if (OILL == op) {
3601 // CC is set based on the 16 bits that are AND'd
3602 SetS390BitWiseConditionCode<uint16_t>(r1_val | i);
3603 } else if (OILH == op) {
3604 // CC is set based on the 16 bits that are AND'd
3605 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) | i);
3606 i = i << 16;
3607 } else {
3608 UNIMPLEMENTED();
3609 }
3610 set_low_register(r1, r1_val | i);
3611 break;
3612 }
3613 case NILL:
3614 case NILH: {
3615 RIInstruction* riInst = reinterpret_cast<RIInstruction*>(instr);
3616 int r1 = riInst->R1Value();
3617 int i = riInst->I2Value();
3618 int32_t r1_val = get_low_register<int32_t>(r1);
3619 if (NILL == op) {
3620 // CC is set based on the 16 bits that are AND'd
3621 SetS390BitWiseConditionCode<uint16_t>(r1_val & i);
3622 i |= 0xFFFF0000;
3623 } else if (NILH == op) {
3624 // CC is set based on the 16 bits that are AND'd
3625 SetS390BitWiseConditionCode<uint16_t>((r1_val >> 16) & i);
3626 i = (i << 16) | 0x0000FFFF;
3627 } else {
3628 UNIMPLEMENTED();
3629 }
3630 set_low_register(r1, r1_val & i);
3631 break;
3632 }
3633 case AH:
3634 case SH:
3635 case MH: {
3636 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3637 int b2 = rxinst->B2Value();
3638 int x2 = rxinst->X2Value();
3639 int32_t r1_val = get_low_register<int32_t>(rxinst->R1Value());
3640 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3641 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3642 intptr_t d2_val = rxinst->D2Value();
3643 intptr_t addr = b2_val + x2_val + d2_val;
3644 int32_t mem_val = static_cast<int32_t>(ReadH(addr, instr));
3645 int32_t alu_out = 0;
3646 bool isOF = false;
3647 if (AH == op) {
3648 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
3649 alu_out = r1_val + mem_val;
3650 } else if (SH == op) {
3651 isOF = CheckOverflowForIntSub(r1_val, mem_val, int32_t);
3652 alu_out = r1_val - mem_val;
3653 } else if (MH == op) {
3654 alu_out = r1_val * mem_val;
3655 } else {
3656 UNREACHABLE();
3657 }
3658 set_low_register(r1, alu_out);
3659 if (MH != op) { // MH does not change condition code
3660 SetS390ConditionCode<int32_t>(alu_out, 0);
3661 SetS390OverflowCode(isOF);
3662 }
3663 break;
3664 }
3665 case DSGR: {
3666 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3667 int r1 = rreInst->R1Value();
3668 int r2 = rreInst->R2Value();
3669
3670 DCHECK(r1 % 2 == 0);
3671
3672 int64_t dividend = get_register(r1 + 1);
3673 int64_t divisor = get_register(r2);
3674 set_register(r1, dividend % divisor);
3675 set_register(r1 + 1, dividend / divisor);
3676
3677 break;
3678 }
3679 case FLOGR: {
3680 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3681 int r1 = rreInst->R1Value();
3682 int r2 = rreInst->R2Value();
3683
3684 DCHECK(r1 % 2 == 0);
3685
3686 int64_t r2_val = get_register(r2);
3687
3688 int i = 0;
3689 for (; i < 64; i++) {
3690 if (r2_val < 0) break;
3691 r2_val <<= 1;
3692 }
3693
3694 r2_val = get_register(r2);
3695
3696 int64_t mask = ~(1 << (63 - i));
3697 set_register(r1, i);
3698 set_register(r1 + 1, r2_val & mask);
3699
3700 break;
3701 }
3702 case MSR:
3703 case MSGR: { // they do not set overflow code
3704 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
3705 int r1 = rreInst->R1Value();
3706 int r2 = rreInst->R2Value();
3707 if (op == MSR) {
3708 int32_t r1_val = get_low_register<int32_t>(r1);
3709 int32_t r2_val = get_low_register<int32_t>(r2);
3710 set_low_register(r1, r1_val * r2_val);
3711 } else if (op == MSGR) {
3712 int64_t r1_val = get_register(r1);
3713 int64_t r2_val = get_register(r2);
3714 set_register(r1, r1_val * r2_val);
3715 } else {
3716 UNREACHABLE();
3717 }
3718 break;
3719 }
3720 case MS: {
3721 RXInstruction* rxinst = reinterpret_cast<RXInstruction*>(instr);
3722 int r1 = rxinst->R1Value();
3723 int b2 = rxinst->B2Value();
3724 int x2 = rxinst->X2Value();
3725 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
3726 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
3727 intptr_t d2_val = rxinst->D2Value();
3728 int32_t mem_val = ReadW(b2_val + x2_val + d2_val, instr);
3729 int32_t r1_val = get_low_register<int32_t>(r1);
3730 set_low_register(r1, r1_val * mem_val);
3731 break;
3732 }
3733 case LGBR:
3734 case LBR: {
3735 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3736 int r1 = rrinst->R1Value();
3737 int r2 = rrinst->R2Value();
3738 if (op == LGBR) {
3739 int64_t r2_val = get_low_register<int64_t>(r2);
3740 r2_val <<= 56;
3741 r2_val >>= 56;
3742 set_register(r1, r2_val);
3743 } else if (op == LBR) {
3744 int32_t r2_val = get_low_register<int32_t>(r2);
3745 r2_val <<= 24;
3746 r2_val >>= 24;
3747 set_low_register(r1, r2_val);
3748 } else {
3749 UNREACHABLE();
3750 }
3751 break;
3752 }
3753 case LGHR:
3754 case LHR: {
3755 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3756 int r1 = rrinst->R1Value();
3757 int r2 = rrinst->R2Value();
3758 if (op == LGHR) {
3759 int64_t r2_val = get_low_register<int64_t>(r2);
3760 r2_val <<= 48;
3761 r2_val >>= 48;
3762 set_register(r1, r2_val);
3763 } else if (op == LHR) {
3764 int32_t r2_val = get_low_register<int32_t>(r2);
3765 r2_val <<= 16;
3766 r2_val >>= 16;
3767 set_low_register(r1, r2_val);
3768 } else {
3769 UNREACHABLE();
3770 }
3771 break;
3772 }
3773 case ALCR: {
3774 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3775 int r1 = rrinst->R1Value();
3776 int r2 = rrinst->R2Value();
3777 uint32_t r1_val = get_low_register<uint32_t>(r1);
3778 uint32_t r2_val = get_low_register<uint32_t>(r2);
3779 uint32_t alu_out = 0;
3780 bool isOF = false;
3781
3782 alu_out = r1_val + r2_val;
3783 bool isOF_original = CheckOverflowForUIntAdd(r1_val, r2_val);
3784 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3785 alu_out = alu_out + 1;
3786 isOF = isOF_original || CheckOverflowForUIntAdd(alu_out, 1);
3787 } else {
3788 isOF = isOF_original;
3789 }
3790 set_low_register(r1, alu_out);
3791 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3792 break;
3793 }
3794 case SLBR: {
3795 RREInstruction* rrinst = reinterpret_cast<RREInstruction*>(instr);
3796 int r1 = rrinst->R1Value();
3797 int r2 = rrinst->R2Value();
3798 uint32_t r1_val = get_low_register<uint32_t>(r1);
3799 uint32_t r2_val = get_low_register<uint32_t>(r2);
3800 uint32_t alu_out = 0;
3801 bool isOF = false;
3802
3803 alu_out = r1_val - r2_val;
3804 bool isOF_original = CheckOverflowForUIntSub(r1_val, r2_val);
3805 if (TestConditionCode((Condition)2) || TestConditionCode((Condition)3)) {
3806 alu_out = alu_out - 1;
3807 isOF = isOF_original || CheckOverflowForUIntSub(alu_out, 1);
3808 } else {
3809 isOF = isOF_original;
3810 }
3811 set_low_register(r1, alu_out);
3812 SetS390ConditionCodeCarry<uint32_t>(alu_out, isOF);
3813 break;
3814 }
3815 default: { return DecodeFourByteFloatingPoint(instr); }
3816 }
3817 return true;
3818 }
3819
3820 void Simulator::DecodeFourByteFloatingPointIntConversion(Instruction* instr) {
3821 Opcode op = instr->S390OpcodeValue();
3822 switch (op) {
3823 case CDLFBR:
3824 case CDLGBR:
3825 case CELGBR:
3826 case CLFDBR:
3827 case CLGDBR:
3828 case CELFBR:
3829 case CLGEBR:
3830 case CLFEBR: {
3831 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3832 int r1 = rreInstr->R1Value();
3833 int r2 = rreInstr->R2Value();
3834 if (op == CDLFBR) {
3835 uint32_t r2_val = get_low_register<uint32_t>(r2);
3836 double r1_val = static_cast<double>(r2_val);
3837 set_d_register_from_double(r1, r1_val);
3838 } else if (op == CELFBR) {
3839 uint32_t r2_val = get_low_register<uint32_t>(r2);
3840 float r1_val = static_cast<float>(r2_val);
3841 set_d_register_from_float32(r1, r1_val);
3842 } else if (op == CDLGBR) {
3843 uint64_t r2_val = get_register(r2);
3844 double r1_val = static_cast<double>(r2_val);
3845 set_d_register_from_double(r1, r1_val);
3846 } else if (op == CELGBR) {
3847 uint64_t r2_val = get_register(r2);
3848 float r1_val = static_cast<float>(r2_val);
3849 set_d_register_from_float32(r1, r1_val);
3850 } else if (op == CLFDBR) {
3851 double r2_val = get_double_from_d_register(r2);
3852 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3853 set_low_register(r1, r1_val);
3854 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3855 } else if (op == CLFEBR) {
3856 float r2_val = get_float32_from_d_register(r2);
3857 uint32_t r1_val = static_cast<uint32_t>(r2_val);
3858 set_low_register(r1, r1_val);
3859 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX);
3860 } else if (op == CLGDBR) {
3861 double r2_val = get_double_from_d_register(r2);
3862 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3863 set_register(r1, r1_val);
3864 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3865 } else if (op == CLGEBR) {
3866 float r2_val = get_float32_from_d_register(r2);
3867 uint64_t r1_val = static_cast<uint64_t>(r2_val);
3868 set_register(r1, r1_val);
3869 SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT64_MAX);
3870 }
3871 break;
3872 }
3873 default:
3874 UNREACHABLE();
3875 }
3876 }
3877
3878 void Simulator::DecodeFourByteFloatingPointRound(Instruction* instr) {
3879 Opcode op = instr->S390OpcodeValue();
3880 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
3881 int r1 = rreInstr->R1Value();
3882 int r2 = rreInstr->R2Value();
3883 double r2_val = get_double_from_d_register(r2);
3884 float r2_fval = get_float32_from_d_register(r2);
3885
3886 switch (op) {
3887 case CFDBR: {
3888 int mask_val = rreInstr->M3Value();
3889 int32_t r1_val = 0;
3890
3891 SetS390RoundConditionCode(r2_val, INT32_MAX, INT32_MIN);
3892
3893 switch (mask_val) {
3894 case CURRENT_ROUNDING_MODE:
3895 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3896 r1_val = static_cast<int32_t>(r2_val);
3897 break;
3898 }
3899 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
3900 double ceil_val = std::ceil(r2_val);
3901 double floor_val = std::floor(r2_val);
3902 double sub_val1 = std::fabs(r2_val - floor_val);
3903 double sub_val2 = std::fabs(r2_val - ceil_val);
3904 if (sub_val1 > sub_val2) {
3905 r1_val = static_cast<int32_t>(ceil_val);
3906 } else if (sub_val1 < sub_val2) {
3907 r1_val = static_cast<int32_t>(floor_val);
3908 } else { // round away from zero:
3909 if (r2_val > 0.0) {
3910 r1_val = static_cast<int32_t>(ceil_val);
3911 } else {
3912 r1_val = static_cast<int32_t>(floor_val);
3913 }
3914 }
3915 break;
3916 }
3917 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3918 double ceil_val = std::ceil(r2_val);
3919 double floor_val = std::floor(r2_val);
3920 double sub_val1 = std::fabs(r2_val - floor_val);
3921 double sub_val2 = std::fabs(r2_val - ceil_val);
3922 if (sub_val1 > sub_val2) {
3923 r1_val = static_cast<int32_t>(ceil_val);
3924 } else if (sub_val1 < sub_val2) {
3925 r1_val = static_cast<int32_t>(floor_val);
3926 } else { // check which one is even:
3927 int32_t c_v = static_cast<int32_t>(ceil_val);
3928 int32_t f_v = static_cast<int32_t>(floor_val);
3929 if (f_v % 2 == 0)
3930 r1_val = f_v;
3931 else
3932 r1_val = c_v;
3933 }
3934 break;
3935 }
3936 case ROUND_TOWARD_0: {
3937 // check for overflow, cast r2_val to 64bit integer
3938 // then check value within the range of INT_MIN and INT_MAX
3939 // and set condition code accordingly
3940 int64_t temp = static_cast<int64_t>(r2_val);
3941 if (temp < INT_MIN || temp > INT_MAX) {
3942 condition_reg_ = CC_OF;
3943 }
3944 r1_val = static_cast<int32_t>(r2_val);
3945 break;
3946 }
3947 case ROUND_TOWARD_PLUS_INFINITE: {
3948 r1_val = static_cast<int32_t>(std::ceil(r2_val));
3949 break;
3950 }
3951 case ROUND_TOWARD_MINUS_INFINITE: {
3952 // check for overflow, cast r2_val to 64bit integer
3953 // then check value within the range of INT_MIN and INT_MAX
3954 // and set condition code accordingly
3955 int64_t temp = static_cast<int64_t>(std::floor(r2_val));
3956 if (temp < INT_MIN || temp > INT_MAX) {
3957 condition_reg_ = CC_OF;
3958 }
3959 r1_val = static_cast<int32_t>(std::floor(r2_val));
3960 break;
3961 }
3962 default:
3963 UNREACHABLE();
3964 }
3965 set_low_register(r1, r1_val);
3966 break;
3967 }
3968 case CGDBR: {
3969 int mask_val = rreInstr->M3Value();
3970 int64_t r1_val = 0;
3971
3972 SetS390RoundConditionCode(r2_val, INT64_MAX, INT64_MIN);
3973
3974 switch (mask_val) {
3975 case CURRENT_ROUNDING_MODE:
3976 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
3977 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
3978 UNIMPLEMENTED();
3979 break;
3980 }
3981 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
3982 double ceil_val = std::ceil(r2_val);
3983 double floor_val = std::floor(r2_val);
3984 if (std::abs(r2_val - floor_val) > std::abs(r2_val - ceil_val)) {
3985 r1_val = static_cast<int64_t>(ceil_val);
3986 } else if (std::abs(r2_val - floor_val) <
3987 std::abs(r2_val - ceil_val)) {
3988 r1_val = static_cast<int64_t>(floor_val);
3989 } else { // check which one is even:
3990 int64_t c_v = static_cast<int64_t>(ceil_val);
3991 int64_t f_v = static_cast<int64_t>(floor_val);
3992 if (f_v % 2 == 0)
3993 r1_val = f_v;
3994 else
3995 r1_val = c_v;
3996 }
3997 break;
3998 }
3999 case ROUND_TOWARD_0: {
4000 r1_val = static_cast<int64_t>(r2_val);
4001 break;
4002 }
4003 case ROUND_TOWARD_PLUS_INFINITE: {
4004 r1_val = static_cast<int64_t>(std::ceil(r2_val));
4005 break;
4006 }
4007 case ROUND_TOWARD_MINUS_INFINITE: {
4008 r1_val = static_cast<int64_t>(std::floor(r2_val));
4009 break;
4010 }
4011 default:
4012 UNREACHABLE();
4013 }
4014 set_register(r1, r1_val);
4015 break;
4016 }
4017 case CGEBR: {
4018 int mask_val = rreInstr->M3Value();
4019 int64_t r1_val = 0;
4020
4021 SetS390RoundConditionCode(r2_fval, INT64_MAX, INT64_MIN);
4022
4023 switch (mask_val) {
4024 case CURRENT_ROUNDING_MODE:
4025 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0:
4026 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4027 UNIMPLEMENTED();
4028 break;
4029 }
4030 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4031 float ceil_val = std::ceil(r2_fval);
4032 float floor_val = std::floor(r2_fval);
4033 if (std::abs(r2_fval - floor_val) > std::abs(r2_fval - ceil_val)) {
4034 r1_val = static_cast<int64_t>(ceil_val);
4035 } else if (std::abs(r2_fval - floor_val) <
4036 std::abs(r2_fval - ceil_val)) {
4037 r1_val = static_cast<int64_t>(floor_val);
4038 } else { // check which one is even:
4039 int64_t c_v = static_cast<int64_t>(ceil_val);
4040 int64_t f_v = static_cast<int64_t>(floor_val);
4041 if (f_v % 2 == 0)
4042 r1_val = f_v;
4043 else
4044 r1_val = c_v;
4045 }
4046 break;
4047 }
4048 case ROUND_TOWARD_0: {
4049 r1_val = static_cast<int64_t>(r2_fval);
4050 break;
4051 }
4052 case ROUND_TOWARD_PLUS_INFINITE: {
4053 r1_val = static_cast<int64_t>(std::ceil(r2_fval));
4054 break;
4055 }
4056 case ROUND_TOWARD_MINUS_INFINITE: {
4057 r1_val = static_cast<int64_t>(std::floor(r2_fval));
4058 break;
4059 }
4060 default:
4061 UNREACHABLE();
4062 }
4063 set_register(r1, r1_val);
4064 break;
4065 }
4066 case CFEBR: {
4067 int mask_val = rreInstr->M3Value();
4068 int32_t r1_val = 0;
4069
4070 SetS390RoundConditionCode(r2_fval, INT32_MAX, INT32_MIN);
4071
4072 switch (mask_val) {
4073 case CURRENT_ROUNDING_MODE:
4074 case ROUND_TO_PREPARE_FOR_SHORTER_PRECISION: {
4075 r1_val = static_cast<int32_t>(r2_fval);
4076 break;
4077 }
4078 case ROUND_TO_NEAREST_WITH_TIES_AWAY_FROM_0: {
4079 float ceil_val = std::ceil(r2_fval);
4080 float floor_val = std::floor(r2_fval);
4081 float sub_val1 = std::fabs(r2_fval - floor_val);
4082 float sub_val2 = std::fabs(r2_fval - ceil_val);
4083 if (sub_val1 > sub_val2) {
4084 r1_val = static_cast<int32_t>(ceil_val);
4085 } else if (sub_val1 < sub_val2) {
4086 r1_val = static_cast<int32_t>(floor_val);
4087 } else { // round away from zero:
4088 if (r2_fval > 0.0) {
4089 r1_val = static_cast<int32_t>(ceil_val);
4090 } else {
4091 r1_val = static_cast<int32_t>(floor_val);
4092 }
4093 }
4094 break;
4095 }
4096 case ROUND_TO_NEAREST_WITH_TIES_TO_EVEN: {
4097 float ceil_val = std::ceil(r2_fval);
4098 float floor_val = std::floor(r2_fval);
4099 float sub_val1 = std::fabs(r2_fval - floor_val);
4100 float sub_val2 = std::fabs(r2_fval - ceil_val);
4101 if (sub_val1 > sub_val2) {
4102 r1_val = static_cast<int32_t>(ceil_val);
4103 } else if (sub_val1 < sub_val2) {
4104 r1_val = static_cast<int32_t>(floor_val);
4105 } else { // check which one is even:
4106 int32_t c_v = static_cast<int32_t>(ceil_val);
4107 int32_t f_v = static_cast<int32_t>(floor_val);
4108 if (f_v % 2 == 0)
4109 r1_val = f_v;
4110 else
4111 r1_val = c_v;
4112 }
4113 break;
4114 }
4115 case ROUND_TOWARD_0: {
4116 // check for overflow, cast r2_fval to 64bit integer
4117 // then check value within the range of INT_MIN and INT_MAX
4118 // and set condition code accordingly
4119 int64_t temp = static_cast<int64_t>(r2_fval);
4120 if (temp < INT_MIN || temp > INT_MAX) {
4121 condition_reg_ = CC_OF;
4122 }
4123 r1_val = static_cast<int32_t>(r2_fval);
4124 break;
4125 }
4126 case ROUND_TOWARD_PLUS_INFINITE: {
4127 r1_val = static_cast<int32_t>(std::ceil(r2_fval));
4128 break;
4129 }
4130 case ROUND_TOWARD_MINUS_INFINITE: {
4131 // check for overflow, cast r2_fval to 64bit integer
4132 // then check value within the range of INT_MIN and INT_MAX
4133 // and set condition code accordingly
4134 int64_t temp = static_cast<int64_t>(std::floor(r2_fval));
4135 if (temp < INT_MIN || temp > INT_MAX) {
4136 condition_reg_ = CC_OF;
4137 }
4138 r1_val = static_cast<int32_t>(std::floor(r2_fval));
4139 break;
4140 }
4141 default:
4142 UNREACHABLE();
4143 }
4144 set_low_register(r1, r1_val);
4145
4146 break;
4147 }
4148 default:
4149 UNREACHABLE();
4150 }
4151 }
4152
4153 /**
4154 * Decodes and simulates four byte floating point instructions
4155 */
4156 bool Simulator::DecodeFourByteFloatingPoint(Instruction* instr) {
4157 Opcode op = instr->S390OpcodeValue();
4158
4159 switch (op) {
4160 case ADBR:
4161 case AEBR:
4162 case SDBR:
4163 case SEBR:
4164 case MDBR:
4165 case MEEBR:
4166 case MADBR:
4167 case DDBR:
4168 case DEBR:
4169 case CDBR:
4170 case CEBR:
4171 case CDFBR:
4172 case CDGBR:
4173 case CEGBR:
4174 case CGEBR:
4175 case CFDBR:
4176 case CGDBR:
4177 case SQDBR:
4178 case SQEBR:
4179 case CFEBR:
4180 case CEFBR:
4181 case LCDBR:
4182 case LCEBR:
4183 case LPDBR:
4184 case LPEBR: {
4185 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4186 int r1 = rreInstr->R1Value();
4187 int r2 = rreInstr->R2Value();
4188 double r1_val = get_double_from_d_register(r1);
4189 double r2_val = get_double_from_d_register(r2);
4190 float fr1_val = get_float32_from_d_register(r1);
4191 float fr2_val = get_float32_from_d_register(r2);
4192 if (op == ADBR) {
4193 r1_val += r2_val;
4194 set_d_register_from_double(r1, r1_val);
4195 SetS390ConditionCode<double>(r1_val, 0);
4196 } else if (op == AEBR) {
4197 fr1_val += fr2_val;
4198 set_d_register_from_float32(r1, fr1_val);
4199 SetS390ConditionCode<float>(fr1_val, 0);
4200 } else if (op == SDBR) {
4201 r1_val -= r2_val;
4202 set_d_register_from_double(r1, r1_val);
4203 SetS390ConditionCode<double>(r1_val, 0);
4204 } else if (op == SEBR) {
4205 fr1_val -= fr2_val;
4206 set_d_register_from_float32(r1, fr1_val);
4207 SetS390ConditionCode<float>(fr1_val, 0);
4208 } else if (op == MDBR) {
4209 r1_val *= r2_val;
4210 set_d_register_from_double(r1, r1_val);
4211 SetS390ConditionCode<double>(r1_val, 0);
4212 } else if (op == MEEBR) {
4213 fr1_val *= fr2_val;
4214 set_d_register_from_float32(r1, fr1_val);
4215 SetS390ConditionCode<float>(fr1_val, 0);
4216 } else if (op == MADBR) {
4217 RRDInstruction* rrdInstr = reinterpret_cast<RRDInstruction*>(instr);
4218 int r1 = rrdInstr->R1Value();
4219 int r2 = rrdInstr->R2Value();
4220 int r3 = rrdInstr->R3Value();
4221 double r1_val = get_double_from_d_register(r1);
4222 double r2_val = get_double_from_d_register(r2);
4223 double r3_val = get_double_from_d_register(r3);
4224 r1_val += r2_val * r3_val;
4225 set_d_register_from_double(r1, r1_val);
4226 SetS390ConditionCode<double>(r1_val, 0);
4227 } else if (op == DDBR) {
4228 r1_val /= r2_val;
4229 set_d_register_from_double(r1, r1_val);
4230 SetS390ConditionCode<double>(r1_val, 0);
4231 } else if (op == DEBR) {
4232 fr1_val /= fr2_val;
4233 set_d_register_from_float32(r1, fr1_val);
4234 SetS390ConditionCode<float>(fr1_val, 0);
4235 } else if (op == CDBR) {
4236 if (isNaN(r1_val) || isNaN(r2_val)) {
4237 condition_reg_ = CC_OF;
4238 } else {
4239 SetS390ConditionCode<double>(r1_val, r2_val);
4240 }
4241 } else if (op == CEBR) {
4242 if (isNaN(fr1_val) || isNaN(fr2_val)) {
4243 condition_reg_ = CC_OF;
4244 } else {
4245 SetS390ConditionCode<float>(fr1_val, fr2_val);
4246 }
4247 } else if (op == CDGBR) {
4248 int64_t r2_val = get_register(r2);
4249 double r1_val = static_cast<double>(r2_val);
4250 set_d_register_from_double(r1, r1_val);
4251 } else if (op == CEGBR) {
4252 int64_t fr2_val = get_register(r2);
4253 float fr1_val = static_cast<float>(fr2_val);
4254 set_d_register_from_float32(r1, fr1_val);
4255 } else if (op == CDFBR) {
4256 int32_t r2_val = get_low_register<int32_t>(r2);
4257 double r1_val = static_cast<double>(r2_val);
4258 set_d_register_from_double(r1, r1_val);
4259 } else if (op == CEFBR) {
4260 int32_t fr2_val = get_low_register<int32_t>(r2);
4261 float fr1_val = static_cast<float>(fr2_val);
4262 set_d_register_from_float32(r1, fr1_val);
4263 } else if (op == CFDBR) {
4264 DecodeFourByteFloatingPointRound(instr);
4265 } else if (op == CGDBR) {
4266 DecodeFourByteFloatingPointRound(instr);
4267 } else if (op == CGEBR) {
4268 DecodeFourByteFloatingPointRound(instr);
4269 } else if (op == SQDBR) {
4270 r1_val = std::sqrt(r2_val);
4271 set_d_register_from_double(r1, r1_val);
4272 } else if (op == SQEBR) {
4273 fr1_val = std::sqrt(fr2_val);
4274 set_d_register_from_float32(r1, fr1_val);
4275 } else if (op == CFEBR) {
4276 DecodeFourByteFloatingPointRound(instr);
4277 } else if (op == LCDBR) {
4278 r1_val = -r2_val;
4279 set_d_register_from_double(r1, r1_val);
4280 if (r2_val != r2_val) { // input is NaN
4281 condition_reg_ = CC_OF;
4282 } else if (r2_val == 0) {
4283 condition_reg_ = CC_EQ;
4284 } else if (r2_val < 0) {
4285 condition_reg_ = CC_LT;
4286 } else if (r2_val > 0) {
4287 condition_reg_ = CC_GT;
4288 }
4289 } else if (op == LCEBR) {
4290 fr1_val = -fr2_val;
4291 set_d_register_from_float32(r1, fr1_val);
4292 if (fr2_val != fr2_val) { // input is NaN
4293 condition_reg_ = CC_OF;
4294 } else if (fr2_val == 0) {
4295 condition_reg_ = CC_EQ;
4296 } else if (fr2_val < 0) {
4297 condition_reg_ = CC_LT;
4298 } else if (fr2_val > 0) {
4299 condition_reg_ = CC_GT;
4300 }
4301 } else if (op == LPDBR) {
4302 r1_val = std::fabs(r2_val);
4303 set_d_register_from_double(r1, r1_val);
4304 if (r2_val != r2_val) { // input is NaN
4305 condition_reg_ = CC_OF;
4306 } else if (r2_val == 0) {
4307 condition_reg_ = CC_EQ;
4308 } else {
4309 condition_reg_ = CC_GT;
4310 }
4311 } else if (op == LPEBR) {
4312 fr1_val = std::fabs(fr2_val);
4313 set_d_register_from_float32(r1, fr1_val);
4314 if (fr2_val != fr2_val) { // input is NaN
4315 condition_reg_ = CC_OF;
4316 } else if (fr2_val == 0) {
4317 condition_reg_ = CC_EQ;
4318 } else {
4319 condition_reg_ = CC_GT;
4320 }
4321 } else {
4322 UNREACHABLE();
4323 }
4324 break;
4325 }
4326 case CDLFBR:
4327 case CDLGBR:
4328 case CELGBR:
4329 case CLFDBR:
4330 case CELFBR:
4331 case CLGDBR:
4332 case CLGEBR:
4333 case CLFEBR: {
4334 DecodeFourByteFloatingPointIntConversion(instr);
4335 break;
4336 }
4337 case TMLL: {
4338 RIInstruction* riinst = reinterpret_cast<RIInstruction*>(instr);
4339 int r1 = riinst->R1Value();
4340 int mask = riinst->I2Value() & 0x0000FFFF;
4341 if (mask == 0) {
4342 condition_reg_ = 0x0;
4343 break;
4344 }
4345 uint32_t r1_val = get_low_register<uint32_t>(r1);
4346 r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
4347
4348 // Test if all selected bits are Zero
4349 bool allSelectedBitsAreZeros = true;
4350 for (int i = 0; i < 15; i++) {
4351 if (mask & (1 << i)) {
4352 if (r1_val & (1 << i)) {
4353 allSelectedBitsAreZeros = false;
4354 break;
4355 }
4356 }
4357 }
4358 if (allSelectedBitsAreZeros) {
4359 condition_reg_ = 0x8;
4360 break; // Done!
4361 }
4362
4363 // Test if all selected bits are one
4364 bool allSelectedBitsAreOnes = true;
4365 for (int i = 0; i < 15; i++) {
4366 if (mask & (1 << i)) {
4367 if (!(r1_val & (1 << i))) {
4368 allSelectedBitsAreOnes = false;
4369 break;
4370 }
4371 }
4372 }
4373 if (allSelectedBitsAreOnes) {
4374 condition_reg_ = 0x1;
4375 break; // Done!
4376 }
4377
4378 // Now we know selected bits mixed zeros and ones
4379 // Test if the leftmost bit is zero or one
4380 for (int i = 14; i >= 0; i--) {
4381 if (mask & (1 << i)) {
4382 if (r1_val & (1 << i)) {
4383 // leftmost bit is one
4384 condition_reg_ = 0x2;
4385 } else {
4386 // leftmost bit is zero
4387 condition_reg_ = 0x4;
4388 }
4389 break; // Done!
4390 }
4391 }
4392 break;
4393 }
4394 case LEDBR: {
4395 RREInstruction* rreInst = reinterpret_cast<RREInstruction*>(instr);
4396 int r1 = rreInst->R1Value();
4397 int r2 = rreInst->R2Value();
4398 double r2_val = get_double_from_d_register(r2);
4399 set_d_register_from_float32(r1, static_cast<float>(r2_val));
4400 break;
4401 }
4402 case FIDBRA: {
4403 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4404 int r1 = rrfInst->R1Value();
4405 int r2 = rrfInst->R2Value();
4406 int m3 = rrfInst->M3Value();
4407 double r2_val = get_double_from_d_register(r2);
4408 DCHECK(rrfInst->M4Value() == 0);
4409 switch (m3) {
4410 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4411 set_d_register_from_double(r1, round(r2_val));
4412 break;
4413 case Assembler::FIDBRA_ROUND_TOWARD_0:
4414 set_d_register_from_double(r1, trunc(r2_val));
4415 break;
4416 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4417 set_d_register_from_double(r1, std::ceil(r2_val));
4418 break;
4419 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4420 set_d_register_from_double(r1, std::floor(r2_val));
4421 break;
4422 default:
4423 UNIMPLEMENTED();
4424 break;
4425 }
4426 break;
4427 }
4428 case FIEBRA: {
4429 RRFInstruction* rrfInst = reinterpret_cast<RRFInstruction*>(instr);
4430 int r1 = rrfInst->R1Value();
4431 int r2 = rrfInst->R2Value();
4432 int m3 = rrfInst->M3Value();
4433 float r2_val = get_float32_from_d_register(r2);
4434 DCHECK(rrfInst->M4Value() == 0);
4435 switch (m3) {
4436 case Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0:
4437 set_d_register_from_float32(r1, round(r2_val));
4438 break;
4439 case Assembler::FIDBRA_ROUND_TOWARD_0:
4440 set_d_register_from_float32(r1, trunc(r2_val));
4441 break;
4442 case Assembler::FIDBRA_ROUND_TOWARD_POS_INF:
4443 set_d_register_from_float32(r1, std::ceil(r2_val));
4444 break;
4445 case Assembler::FIDBRA_ROUND_TOWARD_NEG_INF:
4446 set_d_register_from_float32(r1, std::floor(r2_val));
4447 break;
4448 default:
4449 UNIMPLEMENTED();
4450 break;
4451 }
4452 break;
4453 }
4454 case MSDBR: {
4455 UNIMPLEMENTED();
4456 break;
4457 }
4458 case LDEBR: {
4459 RREInstruction* rreInstr = reinterpret_cast<RREInstruction*>(instr);
4460 int r1 = rreInstr->R1Value();
4461 int r2 = rreInstr->R2Value();
4462 float fp_val = get_float32_from_d_register(r2);
4463 double db_val = static_cast<double>(fp_val);
4464 set_d_register_from_double(r1, db_val);
4465 break;
4466 }
4467 default: {
4468 UNREACHABLE();
4469 return false;
4470 }
4471 }
4472 return true;
4473 }
4474
4475 // Decode routine for six-byte instructions
4476 bool Simulator::DecodeSixByte(Instruction* instr) {
4477 Opcode op = instr->S390OpcodeValue();
4478
4479 // Pre-cast instruction to various types
4480 RIEInstruction* rieInstr = reinterpret_cast<RIEInstruction*>(instr);
4481 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
4482 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4483 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
4484 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
4485 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
4486 SILInstruction* silInstr = reinterpret_cast<SILInstruction*>(instr);
4487 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
4488
4489 switch (op) {
4490 case CLIY: {
4491 // Compare Immediate (Mem - Imm) (8)
4492 int b1 = siyInstr->B1Value();
4493 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4494 intptr_t d1_val = siyInstr->D1Value();
4495 intptr_t addr = b1_val + d1_val;
4496 uint8_t mem_val = ReadB(addr);
4497 uint8_t imm_val = siyInstr->I2Value();
4498 SetS390ConditionCode<uint8_t>(mem_val, imm_val);
4499 break;
4500 }
4501 case TMY: {
4502 // Test Under Mask (Mem - Imm) (8)
4503 int b1 = siyInstr->B1Value();
4504 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4505 intptr_t d1_val = siyInstr->D1Value();
4506 intptr_t addr = b1_val + d1_val;
4507 uint8_t mem_val = ReadB(addr);
4508 uint8_t imm_val = siyInstr->I2Value();
4509 uint8_t selected_bits = mem_val & imm_val;
4510 // CC0: Selected bits are zero
4511 // CC1: Selected bits mixed zeros and ones
4512 // CC3: Selected bits all ones
4513 if (0 == selected_bits) {
4514 condition_reg_ = CC_EQ; // CC0
4515 } else if (selected_bits == imm_val) {
4516 condition_reg_ = 0x1; // CC3
4517 } else {
4518 condition_reg_ = 0x4; // CC1
4519 }
4520 break;
4521 }
4522 case LDEB: {
4523 // Load Float
4524 int r1 = rxeInstr->R1Value();
4525 int rb = rxeInstr->B2Value();
4526 int rx = rxeInstr->X2Value();
4527 int offset = rxeInstr->D2Value();
4528 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4529 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4530 double ret = static_cast<double>(
4531 *reinterpret_cast<float*>(rx_val + rb_val + offset));
4532 set_d_register_from_double(r1, ret);
4533 break;
4534 }
4535 case LAY: {
4536 // Load Address
4537 int r1 = rxyInstr->R1Value();
4538 int rb = rxyInstr->B2Value();
4539 int rx = rxyInstr->X2Value();
4540 int offset = rxyInstr->D2Value();
4541 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4542 int64_t rx_val = (rx == 0) ? 0 : get_register(rx);
4543 set_register(r1, rx_val + rb_val + offset);
4544 break;
4545 }
4546 case LARL: {
4547 // Load Addresss Relative Long
4548 int r1 = rilInstr->R1Value();
4549 intptr_t offset = rilInstr->I2Value() * 2;
4550 set_register(r1, get_pc() + offset);
4551 break;
4552 }
4553 case LLILF: {
4554 // Load Logical into lower 32-bits (zero extend upper 32-bits)
4555 int r1 = rilInstr->R1Value();
4556 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4557 set_register(r1, imm);
4558 break;
4559 }
4560 case LLIHF: {
4561 // Load Logical Immediate into high word
4562 int r1 = rilInstr->R1Value();
4563 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4564 set_register(r1, imm << 32);
4565 break;
4566 }
4567 case OILF:
4568 case NILF:
4569 case IILF: {
4570 // Bitwise Op on lower 32-bits
4571 int r1 = rilInstr->R1Value();
4572 uint32_t imm = rilInstr->I2UnsignedValue();
4573 uint32_t alu_out = get_low_register<uint32_t>(r1);
4574 if (NILF == op) {
4575 alu_out &= imm;
4576 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4577 } else if (OILF == op) {
4578 alu_out |= imm;
4579 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4580 } else if (op == IILF) {
4581 alu_out = imm;
4582 } else {
4583 DCHECK(false);
4584 }
4585 set_low_register(r1, alu_out);
4586 break;
4587 }
4588 case OIHF:
4589 case NIHF:
4590 case IIHF: {
4591 // Bitwise Op on upper 32-bits
4592 int r1 = rilInstr->R1Value();
4593 uint32_t imm = rilInstr->I2Value();
4594 uint32_t alu_out = get_high_register<uint32_t>(r1);
4595 if (op == NIHF) {
4596 alu_out &= imm;
4597 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4598 } else if (op == OIHF) {
4599 alu_out |= imm;
4600 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4601 } else if (op == IIHF) {
4602 alu_out = imm;
4603 } else {
4604 DCHECK(false);
4605 }
4606 set_high_register(r1, alu_out);
4607 break;
4608 }
4609 case CLFI: {
4610 // Compare Logical with Immediate (32)
4611 int r1 = rilInstr->R1Value();
4612 uint32_t imm = rilInstr->I2UnsignedValue();
4613 SetS390ConditionCode<uint32_t>(get_low_register<uint32_t>(r1), imm);
4614 break;
4615 }
4616 case CFI: {
4617 // Compare with Immediate (32)
4618 int r1 = rilInstr->R1Value();
4619 int32_t imm = rilInstr->I2Value();
4620 SetS390ConditionCode<int32_t>(get_low_register<int32_t>(r1), imm);
4621 break;
4622 }
4623 case CLGFI: {
4624 // Compare Logical with Immediate (64)
4625 int r1 = rilInstr->R1Value();
4626 uint64_t imm = static_cast<uint64_t>(rilInstr->I2UnsignedValue());
4627 SetS390ConditionCode<uint64_t>(get_register(r1), imm);
4628 break;
4629 }
4630 case CGFI: {
4631 // Compare with Immediate (64)
4632 int r1 = rilInstr->R1Value();
4633 int64_t imm = static_cast<int64_t>(rilInstr->I2Value());
4634 SetS390ConditionCode<int64_t>(get_register(r1), imm);
4635 break;
4636 }
4637 case BRASL: {
4638 // Branch and Save Relative Long
4639 int r1 = rilInstr->R1Value();
4640 intptr_t d2 = rilInstr->I2Value();
4641 intptr_t pc = get_pc();
4642 set_register(r1, pc + 6); // save next instruction to register
4643 set_pc(pc + d2 * 2); // update register
4644 break;
4645 }
4646 case BRCL: {
4647 // Branch on Condition Relative Long
4648 Condition m1 = (Condition)rilInstr->R1Value();
4649 if (TestConditionCode((Condition)m1)) {
4650 intptr_t offset = rilInstr->I2Value() * 2;
4651 set_pc(get_pc() + offset);
4652 }
4653 break;
4654 }
4655 case LMG:
4656 case STMG: {
4657 // Store Multiple 64-bits.
4658 int r1 = rsyInstr->R1Value();
4659 int r3 = rsyInstr->R3Value();
4660 int rb = rsyInstr->B2Value();
4661 int offset = rsyInstr->D2Value();
4662
4663 // Regs roll around if r3 is less than r1.
4664 // Artifically increase r3 by 16 so we can calculate
4665 // the number of regs stored properly.
4666 if (r3 < r1) r3 += 16;
4667
4668 int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
4669
4670 // Store each register in ascending order.
4671 for (int i = 0; i <= r3 - r1; i++) {
4672 if (op == LMG) {
4673 int64_t value = ReadDW(rb_val + offset + 8 * i);
4674 set_register((r1 + i) % 16, value);
4675 } else if (op == STMG) {
4676 int64_t value = get_register((r1 + i) % 16);
4677 WriteDW(rb_val + offset + 8 * i, value);
4678 } else {
4679 DCHECK(false);
4680 }
4681 }
4682 break;
4683 }
4684 case SLLK:
4685 case RLL:
4686 case SRLK:
4687 case SLLG:
4688 case RLLG:
4689 case SRLG: {
4690 DecodeSixByteBitShift(instr);
4691 break;
4692 }
4693 case SLAK:
4694 case SRAK: {
4695 // 32-bit non-clobbering shift-left/right arithmetic
4696 int r1 = rsyInstr->R1Value();
4697 int r3 = rsyInstr->R3Value();
4698 int b2 = rsyInstr->B2Value();
4699 intptr_t d2 = rsyInstr->D2Value();
4700 // only takes rightmost 6 bits
4701 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4702 int shiftBits = (b2_val + d2) & 0x3F;
4703 int32_t r3_val = get_low_register<int32_t>(r3);
4704 int32_t alu_out = 0;
4705 bool isOF = false;
4706 if (op == SLAK) {
4707 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4708 alu_out = r3_val << shiftBits;
4709 } else if (op == SRAK) {
4710 alu_out = r3_val >> shiftBits;
4711 }
4712 set_low_register(r1, alu_out);
4713 SetS390ConditionCode<int32_t>(alu_out, 0);
4714 SetS390OverflowCode(isOF);
4715 break;
4716 }
4717 case SLAG:
4718 case SRAG: {
4719 // 64-bit non-clobbering shift-left/right arithmetic
4720 int r1 = rsyInstr->R1Value();
4721 int r3 = rsyInstr->R3Value();
4722 int b2 = rsyInstr->B2Value();
4723 intptr_t d2 = rsyInstr->D2Value();
4724 // only takes rightmost 6 bits
4725 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4726 int shiftBits = (b2_val + d2) & 0x3F;
4727 int64_t r3_val = get_register(r3);
4728 intptr_t alu_out = 0;
4729 bool isOF = false;
4730 if (op == SLAG) {
4731 isOF = CheckOverflowForShiftLeft(r3_val, shiftBits);
4732 alu_out = r3_val << shiftBits;
4733 } else if (op == SRAG) {
4734 alu_out = r3_val >> shiftBits;
4735 }
4736 set_register(r1, alu_out);
4737 SetS390ConditionCode<intptr_t>(alu_out, 0);
4738 SetS390OverflowCode(isOF);
4739 break;
4740 }
4741 case LMY:
4742 case STMY: {
4743 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
4744 // Load/Store Multiple (32)
4745 int r1 = rsyInstr->R1Value();
4746 int r3 = rsyInstr->R3Value();
4747 int b2 = rsyInstr->B2Value();
4748 int offset = rsyInstr->D2Value();
4749
4750 // Regs roll around if r3 is less than r1.
4751 // Artifically increase r3 by 16 so we can calculate
4752 // the number of regs stored properly.
4753 if (r3 < r1) r3 += 16;
4754
4755 int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2);
4756
4757 // Store each register in ascending order.
4758 for (int i = 0; i <= r3 - r1; i++) {
4759 if (op == LMY) {
4760 int32_t value = ReadW(b2_val + offset + 4 * i, instr);
4761 set_low_register((r1 + i) % 16, value);
4762 } else {
4763 int32_t value = get_low_register<int32_t>((r1 + i) % 16);
4764 WriteW(b2_val + offset + 4 * i, value, instr);
4765 }
4766 }
4767 break;
4768 }
4769 case LT:
4770 case LTG: {
4771 // Load and Test (32/64)
4772 int r1 = rxyInstr->R1Value();
4773 int x2 = rxyInstr->X2Value();
4774 int b2 = rxyInstr->B2Value();
4775 int d2 = rxyInstr->D2Value();
4776
4777 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4778 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4779 intptr_t addr = x2_val + b2_val + d2;
4780
4781 if (op == LT) {
4782 int32_t value = ReadW(addr, instr);
4783 set_low_register(r1, value);
4784 SetS390ConditionCode<int32_t>(value, 0);
4785 } else if (op == LTG) {
4786 int64_t value = ReadDW(addr);
4787 set_register(r1, value);
4788 SetS390ConditionCode<int64_t>(value, 0);
4789 }
4790 break;
4791 }
4792 case LY:
4793 case LB:
4794 case LGB:
4795 case LG:
4796 case LGF:
4797 case LGH:
4798 case LLGF:
4799 case STG:
4800 case STY:
4801 case STCY:
4802 case STHY:
4803 case STEY:
4804 case LDY:
4805 case LHY:
4806 case STDY:
4807 case LEY: {
4808 // Miscellaneous Loads and Stores
4809 int r1 = rxyInstr->R1Value();
4810 int x2 = rxyInstr->X2Value();
4811 int b2 = rxyInstr->B2Value();
4812 int d2 = rxyInstr->D2Value();
4813 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4814 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4815 intptr_t addr = x2_val + b2_val + d2;
4816 if (op == LY) {
4817 uint32_t mem_val = ReadWU(addr, instr);
4818 set_low_register(r1, mem_val);
4819 } else if (op == LB) {
4820 int32_t mem_val = ReadB(addr);
4821 set_low_register(r1, mem_val);
4822 } else if (op == LGB) {
4823 int64_t mem_val = ReadB(addr);
4824 set_register(r1, mem_val);
4825 } else if (op == LG) {
4826 int64_t mem_val = ReadDW(addr);
4827 set_register(r1, mem_val);
4828 } else if (op == LGF) {
4829 int64_t mem_val = static_cast<int64_t>(ReadW(addr, instr));
4830 set_register(r1, mem_val);
4831 } else if (op == LGH) {
4832 int64_t mem_val = static_cast<int64_t>(ReadH(addr, instr));
4833 set_register(r1, mem_val);
4834 } else if (op == LLGF) {
4835 // int r1 = rreInst->R1Value();
4836 // int r2 = rreInst->R2Value();
4837 // int32_t r2_val = get_low_register<int32_t>(r2);
4838 // uint64_t r2_finalval = (static_cast<uint64_t>(r2_val)
4839 // & 0x00000000ffffffff);
4840 // set_register(r1, r2_finalval);
4841 // break;
4842 uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr));
4843 set_register(r1, mem_val);
4844 } else if (op == LDY) {
4845 uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
4846 set_d_register(r1, dbl_val);
4847 } else if (op == STEY) {
4848 int64_t frs_val = get_d_register(r1) >> 32;
4849 WriteW(addr, static_cast<int32_t>(frs_val), instr);
4850 } else if (op == LEY) {
4851 float float_val = *reinterpret_cast<float*>(addr);
4852 set_d_register_from_float32(r1, float_val);
4853 } else if (op == STY) {
4854 uint32_t value = get_low_register<uint32_t>(r1);
4855 WriteW(addr, value, instr);
4856 } else if (op == STG) {
4857 uint64_t value = get_register(r1);
4858 WriteDW(addr, value);
4859 } else if (op == STDY) {
4860 int64_t frs_val = get_d_register(r1);
4861 WriteDW(addr, frs_val);
4862 } else if (op == STCY) {
4863 uint8_t value = get_low_register<uint32_t>(r1);
4864 WriteB(addr, value);
4865 } else if (op == STHY) {
4866 uint16_t value = get_low_register<uint32_t>(r1);
4867 WriteH(addr, value, instr);
4868 } else if (op == LHY) {
4869 int32_t result = static_cast<int32_t>(ReadH(addr, instr));
4870 set_low_register(r1, result);
4871 }
4872 break;
4873 }
4874 case MVC: {
4875 // Move Character
4876 int b1 = ssInstr->B1Value();
4877 intptr_t d1 = ssInstr->D1Value();
4878 int b2 = ssInstr->B2Value();
4879 intptr_t d2 = ssInstr->D2Value();
4880 int length = ssInstr->Length();
4881 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4882 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4883 intptr_t src_addr = b2_val + d2;
4884 intptr_t dst_addr = b1_val + d1;
4885 // remember that the length is the actual length - 1
4886 for (int i = 0; i < length + 1; ++i) {
4887 WriteB(dst_addr++, ReadB(src_addr++));
4888 }
4889 break;
4890 }
4891 case MVHI: {
4892 // Move Integer (32)
4893 int b1 = silInstr->B1Value();
4894 intptr_t d1 = silInstr->D1Value();
4895 int16_t i2 = silInstr->I2Value();
4896 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4897 intptr_t src_addr = b1_val + d1;
4898 WriteW(src_addr, i2, instr);
4899 break;
4900 }
4901 case MVGHI: {
4902 // Move Integer (64)
4903 int b1 = silInstr->B1Value();
4904 intptr_t d1 = silInstr->D1Value();
4905 int16_t i2 = silInstr->I2Value();
4906 int64_t b1_val = (b1 == 0) ? 0 : get_register(b1);
4907 intptr_t src_addr = b1_val + d1;
4908 WriteDW(src_addr, i2);
4909 break;
4910 }
4911 case LLH:
4912 case LLGH: {
4913 // Load Logical Halfworld
4914 int r1 = rxyInstr->R1Value();
4915 int b2 = rxyInstr->B2Value();
4916 int x2 = rxyInstr->X2Value();
4917 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4918 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4919 intptr_t d2_val = rxyInstr->D2Value();
4920 uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr);
4921 if (op == LLH) {
4922 set_low_register(r1, mem_val);
4923 } else if (op == LLGH) {
4924 set_register(r1, mem_val);
4925 } else {
4926 UNREACHABLE();
4927 }
4928 break;
4929 }
4930 case LLC:
4931 case LLGC: {
4932 // Load Logical Character - loads a byte and zero extends.
4933 int r1 = rxyInstr->R1Value();
4934 int b2 = rxyInstr->B2Value();
4935 int x2 = rxyInstr->X2Value();
4936 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
4937 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
4938 intptr_t d2_val = rxyInstr->D2Value();
4939 uint8_t mem_val = ReadBU(b2_val + d2_val + x2_val);
4940 if (op == LLC) {
4941 set_low_register(r1, static_cast<uint32_t>(mem_val));
4942 } else if (op == LLGC) {
4943 set_register(r1, static_cast<uint64_t>(mem_val));
4944 } else {
4945 UNREACHABLE();
4946 }
4947 break;
4948 }
4949 case XIHF:
4950 case XILF: {
4951 int r1 = rilInstr->R1Value();
4952 uint32_t imm = rilInstr->I2UnsignedValue();
4953 uint32_t alu_out = 0;
4954 if (op == XILF) {
4955 alu_out = get_low_register<uint32_t>(r1);
4956 alu_out = alu_out ^ imm;
4957 set_low_register(r1, alu_out);
4958 } else if (op == XIHF) {
4959 alu_out = get_high_register<uint32_t>(r1);
4960 alu_out = alu_out ^ imm;
4961 set_high_register(r1, alu_out);
4962 } else {
4963 UNREACHABLE();
4964 }
4965 SetS390BitWiseConditionCode<uint32_t>(alu_out);
4966 break;
4967 }
4968 case RISBG: {
4969 // Rotate then insert selected bits
4970 int r1 = rieInstr->R1Value();
4971 int r2 = rieInstr->R2Value();
4972 // Starting Bit Position is Bits 2-7 of I3 field
4973 uint32_t start_bit = rieInstr->I3Value() & 0x3F;
4974 // Ending Bit Position is Bits 2-7 of I4 field
4975 uint32_t end_bit = rieInstr->I4Value() & 0x3F;
4976 // Shift Amount is Bits 2-7 of I5 field
4977 uint32_t shift_amount = rieInstr->I5Value() & 0x3F;
4978 // Zero out Remaining (unslected) bits if Bit 0 of I4 is 1.
4979 bool zero_remaining = (0 != (rieInstr->I4Value() & 0x80));
4980
4981 uint64_t src_val = get_register(r2);
4982
4983 // Rotate Left by Shift Amount first
4984 uint64_t rotated_val =
4985 (src_val << shift_amount) | (src_val >> (64 - shift_amount));
4986 int32_t width = end_bit - start_bit + 1;
4987
4988 uint64_t selection_mask = 0;
4989 if (width < 64) {
4990 selection_mask = (static_cast<uint64_t>(1) << width) - 1;
4991 } else {
4992 selection_mask = static_cast<uint64_t>(static_cast<int64_t>(-1));
4993 }
4994 selection_mask = selection_mask << (63 - end_bit);
4995
4996 uint64_t selected_val = rotated_val & selection_mask;
4997
4998 if (!zero_remaining) {
4999 // Merged the unselected bits from the original value
5000 selected_val = (src_val & ~selection_mask) | selected_val;
5001 }
5002
5003 // Condition code is set by treating result as 64-bit signed int
5004 SetS390ConditionCode<int64_t>(selected_val, 0);
5005 set_register(r1, selected_val);
5006 break;
5007 }
5008 default:
5009 return DecodeSixByteArithmetic(instr);
5010 }
5011 return true;
5012 }
5013
5014 void Simulator::DecodeSixByteBitShift(Instruction* instr) {
5015 Opcode op = instr->S390OpcodeValue();
5016
5017 // Pre-cast instruction to various types
5018
5019 RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr);
5020
5021 switch (op) {
5022 case SLLK:
5023 case RLL:
5024 case SRLK: {
5025 // For SLLK/SRLL, the 32-bit third operand is shifted the number
5026 // of bits specified by the second-operand address, and the result is
5027 // placed at the first-operand location. Except for when the R1 and R3
5028 // fields designate the same register, the third operand remains
5029 // unchanged in general register R3.
5030 int r1 = rsyInstr->R1Value();
5031 int r3 = rsyInstr->R3Value();
5032 int b2 = rsyInstr->B2Value();
5033 intptr_t d2 = rsyInstr->D2Value();
5034 // only takes rightmost 6 bits
5035 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5036 int shiftBits = (b2_val + d2) & 0x3F;
5037 // unsigned
5038 uint32_t r3_val = get_low_register<uint32_t>(r3);
5039 uint32_t alu_out = 0;
5040 if (SLLK == op) {
5041 alu_out = r3_val << shiftBits;
5042 } else if (SRLK == op) {
5043 alu_out = r3_val >> shiftBits;
5044 } else if (RLL == op) {
5045 uint32_t rotateBits = r3_val >> (32 - shiftBits);
5046 alu_out = (r3_val << shiftBits) | (rotateBits);
5047 } else {
5048 UNREACHABLE();
5049 }
5050 set_low_register(r1, alu_out);
5051 break;
5052 }
5053 case SLLG:
5054 case RLLG:
5055 case SRLG: {
5056 // For SLLG/SRLG, the 64-bit third operand is shifted the number
5057 // of bits specified by the second-operand address, and the result is
5058 // placed at the first-operand location. Except for when the R1 and R3
5059 // fields designate the same register, the third operand remains
5060 // unchanged in general register R3.
5061 int r1 = rsyInstr->R1Value();
5062 int r3 = rsyInstr->R3Value();
5063 int b2 = rsyInstr->B2Value();
5064 intptr_t d2 = rsyInstr->D2Value();
5065 // only takes rightmost 6 bits
5066 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5067 int shiftBits = (b2_val + d2) & 0x3F;
5068 // unsigned
5069 uint64_t r3_val = get_register(r3);
5070 uint64_t alu_out = 0;
5071 if (op == SLLG) {
5072 alu_out = r3_val << shiftBits;
5073 } else if (op == SRLG) {
5074 alu_out = r3_val >> shiftBits;
5075 } else if (op == RLLG) {
5076 uint64_t rotateBits = r3_val >> (64 - shiftBits);
5077 alu_out = (r3_val << shiftBits) | (rotateBits);
5078 } else {
5079 UNREACHABLE();
5080 }
5081 set_register(r1, alu_out);
5082 break;
5083 }
5084 default:
5085 UNREACHABLE();
5086 }
5087 }
5088
5089 /**
5090 * Decodes and simulates six byte arithmetic instructions
5091 */
5092 bool Simulator::DecodeSixByteArithmetic(Instruction* instr) {
5093 Opcode op = instr->S390OpcodeValue();
5094
5095 // Pre-cast instruction to various types
5096 SIYInstruction* siyInstr = reinterpret_cast<SIYInstruction*>(instr);
5097
5098 switch (op) {
5099 case CDB:
5100 case ADB:
5101 case SDB:
5102 case MDB:
5103 case DDB:
5104 case SQDB: {
5105 RXEInstruction* rxeInstr = reinterpret_cast<RXEInstruction*>(instr);
5106 int b2 = rxeInstr->B2Value();
5107 int x2 = rxeInstr->X2Value();
5108 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5109 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5110 intptr_t d2_val = rxeInstr->D2Value();
5111 double r1_val = get_double_from_d_register(rxeInstr->R1Value());
5112 double dbl_val = ReadDouble(b2_val + x2_val + d2_val);
5113
5114 switch (op) {
5115 case CDB:
5116 SetS390ConditionCode<double>(r1_val, dbl_val);
5117 break;
5118 case ADB:
5119 r1_val += dbl_val;
5120 set_d_register_from_double(r1, r1_val);
5121 SetS390ConditionCode<double>(r1_val, 0);
5122 break;
5123 case SDB:
5124 r1_val -= dbl_val;
5125 set_d_register_from_double(r1, r1_val);
5126 SetS390ConditionCode<double>(r1_val, 0);
5127 break;
5128 case MDB:
5129 r1_val *= dbl_val;
5130 set_d_register_from_double(r1, r1_val);
5131 SetS390ConditionCode<double>(r1_val, 0);
5132 break;
5133 case DDB:
5134 r1_val /= dbl_val;
5135 set_d_register_from_double(r1, r1_val);
5136 SetS390ConditionCode<double>(r1_val, 0);
5137 break;
5138 case SQDB:
5139 r1_val = std::sqrt(dbl_val);
5140 set_d_register_from_double(r1, r1_val);
5141 default:
5142 UNREACHABLE();
5143 break;
5144 }
5145 break;
5146 }
5147 case LRV:
5148 case LRVH:
5149 case STRV:
5150 case STRVH: {
5151 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5152 int r1 = rxyInstr->R1Value();
5153 int x2 = rxyInstr->X2Value();
5154 int b2 = rxyInstr->B2Value();
5155 int d2 = rxyInstr->D2Value();
5156 int32_t r1_val = get_low_register<int32_t>(r1);
5157 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5158 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5159 intptr_t mem_addr = b2_val + x2_val + d2;
5160
5161 if (op == LRVH) {
5162 int16_t mem_val = ReadH(mem_addr, instr);
5163 int32_t result = ByteReverse(mem_val) & 0x0000ffff;
5164 result |= r1_val & 0xffff0000;
5165 set_low_register(r1, result);
5166 } else if (op == LRV) {
5167 int32_t mem_val = ReadW(mem_addr, instr);
5168 set_low_register(r1, ByteReverse(mem_val));
5169 } else if (op == STRVH) {
5170 int16_t result = static_cast<int16_t>(r1_val >> 16);
5171 WriteH(mem_addr, ByteReverse(result), instr);
5172 } else if (op == STRV) {
5173 WriteW(mem_addr, ByteReverse(r1_val), instr);
5174 }
5175
5176 break;
5177 }
5178 case AHIK:
5179 case AGHIK: {
5180 // Non-clobbering Add Halfword Immediate
5181 RIEInstruction* rieInst = reinterpret_cast<RIEInstruction*>(instr);
5182 int r1 = rieInst->R1Value();
5183 int r2 = rieInst->R2Value();
5184 bool isOF = false;
5185 if (AHIK == op) {
5186 // 32-bit Add
5187 int32_t r2_val = get_low_register<int32_t>(r2);
5188 int32_t imm = rieInst->I6Value();
5189 isOF = CheckOverflowForIntAdd(r2_val, imm, int32_t);
5190 set_low_register(r1, r2_val + imm);
5191 SetS390ConditionCode<int32_t>(r2_val + imm, 0);
5192 } else if (AGHIK == op) {
5193 // 64-bit Add
5194 int64_t r2_val = get_register(r2);
5195 int64_t imm = static_cast<int64_t>(rieInst->I6Value());
5196 isOF = CheckOverflowForIntAdd(r2_val, imm, int64_t);
5197 set_register(r1, r2_val + imm);
5198 SetS390ConditionCode<int64_t>(r2_val + imm, 0);
5199 }
5200 SetS390OverflowCode(isOF);
5201 break;
5202 }
5203 case ALFI:
5204 case SLFI: {
5205 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5206 int r1 = rilInstr->R1Value();
5207 uint32_t imm = rilInstr->I2UnsignedValue();
5208 uint32_t alu_out = get_low_register<uint32_t>(r1);
5209 if (op == ALFI) {
5210 alu_out += imm;
5211 } else if (op == SLFI) {
5212 alu_out -= imm;
5213 }
5214 SetS390ConditionCode<uint32_t>(alu_out, 0);
5215 set_low_register(r1, alu_out);
5216 break;
5217 }
5218 case ML: {
5219 UNIMPLEMENTED();
5220 break;
5221 }
5222 case AY:
5223 case SY:
5224 case NY:
5225 case OY:
5226 case XY:
5227 case CY: {
5228 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5229 int r1 = rxyInstr->R1Value();
5230 int x2 = rxyInstr->X2Value();
5231 int b2 = rxyInstr->B2Value();
5232 int d2 = rxyInstr->D2Value();
5233 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5234 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5235 int32_t alu_out = get_low_register<int32_t>(r1);
5236 int32_t mem_val = ReadW(b2_val + x2_val + d2, instr);
5237 bool isOF = false;
5238 if (op == AY) {
5239 isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t);
5240 alu_out += mem_val;
5241 SetS390ConditionCode<int32_t>(alu_out, 0);
5242 SetS390OverflowCode(isOF);
5243 } else if (op == SY) {
5244 isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t);
5245 alu_out -= mem_val;
5246 SetS390ConditionCode<int32_t>(alu_out, 0);
5247 SetS390OverflowCode(isOF);
5248 } else if (op == NY) {
5249 alu_out &= mem_val;
5250 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5251 } else if (op == OY) {
5252 alu_out |= mem_val;
5253 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5254 } else if (op == XY) {
5255 alu_out ^= mem_val;
5256 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5257 } else if (op == CY) {
5258 SetS390ConditionCode<int32_t>(alu_out, mem_val);
5259 }
5260 if (op != CY) {
5261 set_low_register(r1, alu_out);
5262 }
5263 break;
5264 }
5265 case AHY:
5266 case SHY: {
5267 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5268 int32_t r1_val = get_low_register<int32_t>(rxyInstr->R1Value());
5269 int b2 = rxyInstr->B2Value();
5270 int x2 = rxyInstr->X2Value();
5271 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5272 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5273 intptr_t d2_val = rxyInstr->D2Value();
5274 int32_t mem_val =
5275 static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr));
5276 int32_t alu_out = 0;
5277 bool isOF = false;
5278 switch (op) {
5279 case AHY:
5280 alu_out = r1_val + mem_val;
5281 isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t);
5282 break;
5283 case SHY:
5284 alu_out = r1_val - mem_val;
5285 isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t);
5286 break;
5287 default:
5288 UNREACHABLE();
5289 break;
5290 }
5291 set_low_register(r1, alu_out);
5292 SetS390ConditionCode<int32_t>(alu_out, 0);
5293 SetS390OverflowCode(isOF);
5294 break;
5295 }
5296 case AG:
5297 case SG:
5298 case NG:
5299 case OG:
5300 case XG:
5301 case CG:
5302 case CLG: {
5303 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5304 int r1 = rxyInstr->R1Value();
5305 int x2 = rxyInstr->X2Value();
5306 int b2 = rxyInstr->B2Value();
5307 int d2 = rxyInstr->D2Value();
5308 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5309 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5310 int64_t alu_out = get_register(r1);
5311 int64_t mem_val = ReadDW(b2_val + x2_val + d2);
5312
5313 switch (op) {
5314 case AG: {
5315 alu_out += mem_val;
5316 SetS390ConditionCode<int32_t>(alu_out, 0);
5317 break;
5318 }
5319 case SG: {
5320 alu_out -= mem_val;
5321 SetS390ConditionCode<int32_t>(alu_out, 0);
5322 break;
5323 }
5324 case NG: {
5325 alu_out &= mem_val;
5326 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5327 break;
5328 }
5329 case OG: {
5330 alu_out |= mem_val;
5331 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5332 break;
5333 }
5334 case XG: {
5335 alu_out ^= mem_val;
5336 SetS390BitWiseConditionCode<uint32_t>(alu_out);
5337 break;
5338 }
5339 case CG: {
5340 SetS390ConditionCode<int64_t>(alu_out, mem_val);
5341 break;
5342 }
5343 case CLG: {
5344 SetS390ConditionCode<uint64_t>(alu_out, mem_val);
5345 break;
5346 }
5347 default: {
5348 DCHECK(false);
5349 break;
5350 }
5351 }
5352
5353 if (op != CG) {
5354 set_register(r1, alu_out);
5355 }
5356 break;
5357 }
5358 case ALY:
5359 case SLY:
5360 case CLY: {
5361 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5362 int r1 = rxyInstr->R1Value();
5363 int x2 = rxyInstr->X2Value();
5364 int b2 = rxyInstr->B2Value();
5365 int d2 = rxyInstr->D2Value();
5366 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5367 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5368 uint32_t alu_out = get_low_register<uint32_t>(r1);
5369 uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr);
5370
5371 if (op == ALY) {
5372 alu_out += mem_val;
5373 set_low_register(r1, alu_out);
5374 SetS390ConditionCode<uint32_t>(alu_out, 0);
5375 } else if (op == SLY) {
5376 alu_out -= mem_val;
5377 set_low_register(r1, alu_out);
5378 SetS390ConditionCode<uint32_t>(alu_out, 0);
5379 } else if (op == CLY) {
5380 SetS390ConditionCode<uint32_t>(alu_out, mem_val);
5381 }
5382 break;
5383 }
5384 case AGFI:
5385 case AFI: {
5386 // Clobbering Add Word Immediate
5387 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5388 int32_t r1 = rilInstr->R1Value();
5389 bool isOF = false;
5390 if (AFI == op) {
5391 // 32-bit Add (Register + 32-bit Immediate)
5392 int32_t r1_val = get_low_register<int32_t>(r1);
5393 int32_t i2 = rilInstr->I2Value();
5394 isOF = CheckOverflowForIntAdd(r1_val, i2, int32_t);
5395 int32_t alu_out = r1_val + i2;
5396 set_low_register(r1, alu_out);
5397 SetS390ConditionCode<int32_t>(alu_out, 0);
5398 } else if (AGFI == op) {
5399 // 64-bit Add (Register + 32-bit Imm)
5400 int64_t r1_val = get_register(r1);
5401 int64_t i2 = static_cast<int64_t>(rilInstr->I2Value());
5402 isOF = CheckOverflowForIntAdd(r1_val, i2, int64_t);
5403 int64_t alu_out = r1_val + i2;
5404 set_register(r1, alu_out);
5405 SetS390ConditionCode<int64_t>(alu_out, 0);
5406 }
5407 SetS390OverflowCode(isOF);
5408 break;
5409 }
5410 case ASI: {
5411 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5412 // The below static cast to 8 bit and then to 32 bit is necessary
5413 // because siyInstr->I2Value() returns a uint8_t, which a direct
5414 // cast to int32_t could incorrectly interpret.
5415 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5416 int32_t i2 = static_cast<int32_t>(i2_8bit);
5417 int b1 = siyInstr->B1Value();
5418 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5419
5420 int d1_val = siyInstr->D1Value();
5421 intptr_t addr = b1_val + d1_val;
5422
5423 int32_t mem_val = ReadW(addr, instr);
5424 bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t);
5425 int32_t alu_out = mem_val + i2;
5426 SetS390ConditionCode<int32_t>(alu_out, 0);
5427 SetS390OverflowCode(isOF);
5428 WriteW(addr, alu_out, instr);
5429 break;
5430 }
5431 case AGSI: {
5432 // TODO(bcleung): Change all fooInstr->I2Value() to template functions.
5433 // The below static cast to 8 bit and then to 32 bit is necessary
5434 // because siyInstr->I2Value() returns a uint8_t, which a direct
5435 // cast to int32_t could incorrectly interpret.
5436 int8_t i2_8bit = static_cast<int8_t>(siyInstr->I2Value());
5437 int64_t i2 = static_cast<int64_t>(i2_8bit);
5438 int b1 = siyInstr->B1Value();
5439 intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1);
5440
5441 int d1_val = siyInstr->D1Value();
5442 intptr_t addr = b1_val + d1_val;
5443
5444 int64_t mem_val = ReadDW(addr);
5445 int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t);
5446 int64_t alu_out = mem_val + i2;
5447 SetS390ConditionCode<uint64_t>(alu_out, 0);
5448 SetS390OverflowCode(isOF);
5449 WriteDW(addr, alu_out);
5450 break;
5451 }
5452 case AGF:
5453 case SGF:
5454 case ALG:
5455 case SLG: {
5456 #ifndef V8_TARGET_ARCH_S390X
5457 DCHECK(false);
5458 #endif
5459 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5460 int r1 = rxyInstr->R1Value();
5461 uint64_t r1_val = get_register(rxyInstr->R1Value());
5462 int b2 = rxyInstr->B2Value();
5463 int x2 = rxyInstr->X2Value();
5464 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5465 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5466 intptr_t d2_val = rxyInstr->D2Value();
5467 uint64_t alu_out = r1_val;
5468 if (op == ALG) {
5469 uint64_t mem_val =
5470 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5471 alu_out += mem_val;
5472 SetS390ConditionCode<uint64_t>(alu_out, 0);
5473 } else if (op == SLG) {
5474 uint64_t mem_val =
5475 static_cast<uint64_t>(ReadDW(b2_val + d2_val + x2_val));
5476 alu_out -= mem_val;
5477 SetS390ConditionCode<uint64_t>(alu_out, 0);
5478 } else if (op == AGF) {
5479 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5480 alu_out += mem_val;
5481 SetS390ConditionCode<int64_t>(alu_out, 0);
5482 } else if (op == SGF) {
5483 uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5484 alu_out -= mem_val;
5485 SetS390ConditionCode<int64_t>(alu_out, 0);
5486 } else {
5487 DCHECK(false);
5488 }
5489 set_register(r1, alu_out);
5490 break;
5491 }
5492 case ALGFI:
5493 case SLGFI: {
5494 #ifndef V8_TARGET_ARCH_S390X
5495 // should only be called on 64bit
5496 DCHECK(false);
5497 #endif
5498 RILInstruction* rilInstr = reinterpret_cast<RILInstruction*>(instr);
5499 int r1 = rilInstr->R1Value();
5500 uint32_t i2 = rilInstr->I2UnsignedValue();
5501 uint64_t r1_val = (uint64_t)(get_register(r1));
5502 uint64_t alu_out;
5503 if (op == ALGFI)
5504 alu_out = r1_val + i2;
5505 else
5506 alu_out = r1_val - i2;
5507 set_register(r1, (intptr_t)alu_out);
5508 SetS390ConditionCode<uint64_t>(alu_out, 0);
5509 break;
5510 }
5511 case MSY:
5512 case MSG: {
5513 RXYInstruction* rxyInstr = reinterpret_cast<RXYInstruction*>(instr);
5514 int r1 = rxyInstr->R1Value();
5515 int b2 = rxyInstr->B2Value();
5516 int x2 = rxyInstr->X2Value();
5517 int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
5518 int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
5519 intptr_t d2_val = rxyInstr->D2Value();
5520 if (op == MSY) {
5521 int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
5522 int32_t r1_val = get_low_register<int32_t>(r1);
5523 set_low_register(r1, mem_val * r1_val);
5524 } else if (op == MSG) {
5525 int64_t mem_val = ReadDW(b2_val + d2_val + x2_val);
5526 int64_t r1_val = get_register(r1);
5527 set_register(r1, mem_val * r1_val);
5528 } else {
5529 UNREACHABLE();
5530 }
5531 break;
5532 }
5533 case MSFI:
5534 case MSGFI: {
5535 RILInstruction* rilinst = reinterpret_cast<RILInstruction*>(instr);
5536 int r1 = rilinst->R1Value();
5537 int32_t i2 = rilinst->I2Value();
5538 if (op == MSFI) {
5539 int32_t alu_out = get_low_register<int32_t>(r1);
5540 alu_out = alu_out * i2;
5541 set_low_register(r1, alu_out);
5542 } else if (op == MSGFI) {
5543 int64_t alu_out = get_register(r1);
5544 alu_out = alu_out * i2;
5545 set_register(r1, alu_out);
5546 } else {
5547 UNREACHABLE();
5548 }
5549 break;
5550 }
5551 default:
5552 UNREACHABLE();
5553 return false;
5554 }
5555 return true;
5556 }
5557
5558 int16_t Simulator::ByteReverse(int16_t hword) { 2415 int16_t Simulator::ByteReverse(int16_t hword) {
5559 #if defined(__GNUC__) 2416 #if defined(__GNUC__)
5560 return __builtin_bswap16(hword); 2417 return __builtin_bswap16(hword);
5561 #else 2418 #else
5562 return (hword << 8) | ((hword >> 8) & 0x00ff); 2419 return (hword << 8) | ((hword >> 8) & 0x00ff);
5563 #endif 2420 #endif
5564 } 2421 }
5565 2422
5566 int32_t Simulator::ByteReverse(int32_t word) { 2423 int32_t Simulator::ByteReverse(int32_t word) {
5567 #if defined(__GNUC__) 2424 #if defined(__GNUC__)
5568 return __builtin_bswap32(word); 2425 return __builtin_bswap32(word);
5569 #else 2426 #else
5570 int32_t result = word << 24; 2427 int32_t result = word << 24;
5571 result |= (word << 8) & 0x00ff0000; 2428 result |= (word << 8) & 0x00ff0000;
5572 result |= (word >> 8) & 0x0000ff00; 2429 result |= (word >> 8) & 0x0000ff00;
5573 result |= (word >> 24) & 0x00000ff; 2430 result |= (word >> 24) & 0x00000ff;
5574 return result; 2431 return result;
5575 #endif 2432 #endif
5576 } 2433 }
5577 2434
5578 int64_t Simulator::ByteReverse(int64_t dword) { 2435 int64_t Simulator::ByteReverse(int64_t dword) {
5579 #if defined(__GNUC__) 2436 #if defined(__GNUC__)
5580 return __builtin_bswap64(dword); 2437 return __builtin_bswap64(dword);
5581 #else 2438 #else
5582 #error unsupport __builtin_bswap64 2439 #error unsupport __builtin_bswap64
5583 #endif 2440 #endif
5584 } 2441 }
5585 2442
5586 int Simulator::DecodeInstructionOriginal(Instruction* instr) {
5587 int instrLength = instr->InstructionLength();
5588 bool processed = true;
5589 if (instrLength == 2)
5590 processed = DecodeTwoByte(instr);
5591 else if (instrLength == 4)
5592 processed = DecodeFourByte(instr);
5593 else if (instrLength == 6)
5594 processed = DecodeSixByte(instr);
5595 return instrLength;
5596 }
5597
5598 int Simulator::DecodeInstruction(Instruction* instr) { 2443 int Simulator::DecodeInstruction(Instruction* instr) {
5599 Opcode op = instr->S390OpcodeValue(); 2444 Opcode op = instr->S390OpcodeValue();
5600 DCHECK(EvalTable[op] != NULL); 2445 DCHECK(EvalTable[op] != NULL);
5601 return (this->*EvalTable[op])(instr); 2446 return (this->*EvalTable[op])(instr);
5602 } 2447 }
5603 2448
5604 // Executes the current instruction. 2449 // Executes the current instruction.
5605 void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) { 2450 void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) {
5606 icount_++; 2451 icount_++;
5607 2452
(...skipping 7361 matching lines...) Expand 10 before | Expand all | Expand 10 after
12969 return 0; 9814 return 0;
12970 } 9815 }
12971 9816
12972 #undef EVALUATE 9817 #undef EVALUATE
12973 9818
12974 } // namespace internal 9819 } // namespace internal
12975 } // namespace v8 9820 } // namespace v8
12976 9821
12977 #endif // USE_SIMULATOR 9822 #endif // USE_SIMULATOR
12978 #endif // V8_TARGET_ARCH_S390 9823 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/s390/simulator-s390.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698