Index: src/s390/simulator-s390.cc |
diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc |
index 53e18d410036577936cb8e4eafe0d9f570048cf1..ec1f66c0b3a02d6df823bb815826295c0b404a2f 100644 |
--- a/src/s390/simulator-s390.cc |
+++ b/src/s390/simulator-s390.cc |
@@ -3819,60 +3819,11 @@ bool Simulator::DecodeSixByte(Instruction* instr) { |
} |
case SLLK: |
case RLL: |
- case SRLK: { |
- // For SLLK/SRLL, the 32-bit third operand is shifted the number |
- // of bits specified by the second-operand address, and the result is |
- // placed at the first-operand location. Except for when the R1 and R3 |
- // fields designate the same register, the third operand remains |
- // unchanged in general register R3. |
- int r1 = rsyInstr->R1Value(); |
- int r3 = rsyInstr->R3Value(); |
- int b2 = rsyInstr->B2Value(); |
- intptr_t d2 = rsyInstr->D2Value(); |
- // only takes rightmost 6 bits |
- int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
- int shiftBits = (b2_val + d2) & 0x3F; |
- // unsigned |
- uint32_t r3_val = get_low_register<uint32_t>(r3); |
- uint32_t alu_out = 0; |
- if (SLLK == op) { |
- alu_out = r3_val << shiftBits; |
- } else if (SRLK == op) { |
- alu_out = r3_val >> shiftBits; |
- } else if (RLL == op) { |
- uint32_t rotateBits = r3_val >> (32 - shiftBits); |
- alu_out = (r3_val << shiftBits) | (rotateBits); |
- } else { |
- UNREACHABLE(); |
- } |
- set_low_register(r1, alu_out); |
- break; |
- } |
+ case SRLK: |
case SLLG: |
+ case RLLG: |
case SRLG: { |
- // For SLLG/SRLG, the 64-bit third operand is shifted the number |
- // of bits specified by the second-operand address, and the result is |
- // placed at the first-operand location. Except for when the R1 and R3 |
- // fields designate the same register, the third operand remains |
- // unchanged in general register R3. |
- int r1 = rsyInstr->R1Value(); |
- int r3 = rsyInstr->R3Value(); |
- int b2 = rsyInstr->B2Value(); |
- intptr_t d2 = rsyInstr->D2Value(); |
- // only takes rightmost 6 bits |
- int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
- int shiftBits = (b2_val + d2) & 0x3F; |
- // unsigned |
- uint64_t r3_val = get_register(r3); |
- uint64_t alu_out = 0; |
- if (op == SLLG) { |
- alu_out = r3_val << shiftBits; |
- } else if (op == SRLG) { |
- alu_out = r3_val >> shiftBits; |
- } else { |
- UNREACHABLE(); |
- } |
- set_register(r1, alu_out); |
+ DecodeSixByteBitShift(instr); |
break; |
} |
case SLAK: |
@@ -4196,6 +4147,81 @@ bool Simulator::DecodeSixByte(Instruction* instr) { |
return true; |
} |
+void Simulator::DecodeSixByteBitShift(Instruction* instr) { |
+ Opcode op = instr->S390OpcodeValue(); |
+ |
+ // Pre-cast instruction to various types |
+ |
+ RSYInstruction* rsyInstr = reinterpret_cast<RSYInstruction*>(instr); |
+ |
+ switch (op) { |
+ case SLLK: |
+ case RLL: |
+ case SRLK: { |
+ // For SLLK/SRLL, the 32-bit third operand is shifted the number |
+ // of bits specified by the second-operand address, and the result is |
+ // placed at the first-operand location. Except for when the R1 and R3 |
+ // fields designate the same register, the third operand remains |
+ // unchanged in general register R3. |
+ int r1 = rsyInstr->R1Value(); |
+ int r3 = rsyInstr->R3Value(); |
+ int b2 = rsyInstr->B2Value(); |
+ intptr_t d2 = rsyInstr->D2Value(); |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ // unsigned |
+ uint32_t r3_val = get_low_register<uint32_t>(r3); |
+ uint32_t alu_out = 0; |
+ if (SLLK == op) { |
+ alu_out = r3_val << shiftBits; |
+ } else if (SRLK == op) { |
+ alu_out = r3_val >> shiftBits; |
+ } else if (RLL == op) { |
+ uint32_t rotateBits = r3_val >> (32 - shiftBits); |
+ alu_out = (r3_val << shiftBits) | (rotateBits); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ set_low_register(r1, alu_out); |
+ break; |
+ } |
+ case SLLG: |
+ case RLLG: |
+ case SRLG: { |
+ // For SLLG/SRLG, the 64-bit third operand is shifted the number |
+ // of bits specified by the second-operand address, and the result is |
+ // placed at the first-operand location. Except for when the R1 and R3 |
+ // fields designate the same register, the third operand remains |
+ // unchanged in general register R3. |
+ int r1 = rsyInstr->R1Value(); |
+ int r3 = rsyInstr->R3Value(); |
+ int b2 = rsyInstr->B2Value(); |
+ intptr_t d2 = rsyInstr->D2Value(); |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ // unsigned |
+ uint64_t r3_val = get_register(r3); |
+ uint64_t alu_out = 0; |
+ if (op == SLLG) { |
+ alu_out = r3_val << shiftBits; |
+ } else if (op == SRLG) { |
+ alu_out = r3_val >> shiftBits; |
+ } else if (op == RLLG) { |
+ uint64_t rotateBits = r3_val >> (64 - shiftBits); |
+ alu_out = (r3_val << shiftBits) | (rotateBits); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ set_register(r1, alu_out); |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
/** |
* Decodes and simulates six byte arithmetic instructions |
*/ |