Index: src/s390/simulator-s390.cc |
diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc |
index 371a98f91b2322271663475c5597086b308af4d7..151d4c124475bdf43afeaae020547fa9aa83aaac 100644 |
--- a/src/s390/simulator-s390.cc |
+++ b/src/s390/simulator-s390.cc |
@@ -10117,15 +10117,26 @@ EVALUATE(SLGFR) { |
} |
EVALUATE(MSGFR) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(MSGFR); |
+ DECODE_RRE_INSTRUCTION(r1, r2); |
+ int64_t r1_val = get_register(r1); |
+ int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
+ int64_t product = r1_val * r2_val; |
+ set_register(r1, product); |
+ return length; |
} |
EVALUATE(DSGFR) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(DSGFR); |
+ DECODE_RRE_INSTRUCTION(r1, r2); |
+ DCHECK(r1 % 2 == 0); |
+ int64_t r1_val = get_register(r1 + 1); |
+ int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
+ int64_t quotient = r1_val / r2_val; |
+ int64_t remainder = r1_val % r2_val; |
+ set_register(r1, remainder); |
+ set_register(r1 + 1, quotient); |
+ return length; |
} |
EVALUATE(KMAC) { |
@@ -10201,9 +10212,13 @@ EVALUATE(KMC) { |
} |
EVALUATE(CGFR) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(CGFR); |
+ DECODE_RRE_INSTRUCTION(r1, r2); |
+ // Compare (64) |
+ int64_t r1_val = get_register(r1); |
+ int64_t r2_val = static_cast<int64_t>(get_low_register<int32_t>(r2)); |
+ SetS390ConditionCode<int64_t>(r1_val, r2_val); |
+ return length; |
} |
EVALUATE(KIMD) { |
@@ -11031,15 +11046,34 @@ EVALUATE(SLGF) { |
} |
EVALUATE(MSGF) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(MSGF); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
+ intptr_t d2_val = d2; |
+ int64_t mem_val = |
+ static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr)); |
+ int64_t r1_val = get_register(r1); |
+ int64_t product = r1_val * mem_val; |
+ set_register(r1, product); |
+ return length; |
} |
EVALUATE(DSGF) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(DSGF); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ DCHECK(r1 % 2 == 0); |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
+ intptr_t d2_val = d2; |
+ int64_t mem_val = |
+ static_cast<int64_t>(ReadW(b2_val + d2_val + x2_val, instr)); |
+ int64_t r1_val = get_register(r1 + 1); |
+ int64_t quotient = r1_val / mem_val; |
+ int64_t remainder = r1_val % mem_val; |
+ set_register(r1, remainder); |
+ set_register(r1 + 1, quotient); |
+ return length; |
} |
EVALUATE(LRVG) { |
@@ -11598,9 +11632,20 @@ EVALUATE(ML) { |
} |
EVALUATE(DL) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(ML); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ DCHECK(r1 % 2 == 0); |
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); |
+ uint32_t r1_val = get_low_register<uint32_t>(r1 + 1); |
+ uint64_t quotient = |
+ static_cast<uint64_t>(r1_val) / static_cast<uint64_t>(mem_val); |
+ uint64_t remainder = |
+ static_cast<uint64_t>(r1_val) % static_cast<uint64_t>(mem_val); |
+ set_low_register(r1, remainder); |
+ set_low_register(r1 + 1, quotient); |
+ return length; |
} |
EVALUATE(ALC) { |