Index: src/s390/simulator-s390.cc |
diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc |
index 2ac522fa11d5527eda51019af6246423dffcd9a7..1932d297de91bdaeeae04a3f50022040e4a65a7b 100644 |
--- a/src/s390/simulator-s390.cc |
+++ b/src/s390/simulator-s390.cc |
@@ -1748,6 +1748,11 @@ uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) { |
return *ptr; |
} |
+int64_t Simulator::ReadW64(intptr_t addr, Instruction* instr) { |
+ int64_t* ptr = reinterpret_cast<int64_t*>(addr); |
+ return *ptr; |
+} |
+ |
int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) { |
int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
return *ptr; |
@@ -5513,15 +5518,31 @@ bool Simulator::DecodeSixByteArithmetic(Instruction* instr) { |
} |
int16_t Simulator::ByteReverse(int16_t hword) { |
+#if defined(__GNUC__) |
+ return __builtin_bswap16(hword); |
+#else |
return (hword << 8) | ((hword >> 8) & 0x00ff); |
+#endif |
} |
int32_t Simulator::ByteReverse(int32_t word) { |
+#if defined(__GNUC__) |
+ return __builtin_bswap32(word); |
+#else |
int32_t result = word << 24; |
result |= (word << 8) & 0x00ff0000; |
result |= (word >> 8) & 0x0000ff00; |
result |= (word >> 24) & 0x00000ff; |
return result; |
+#endif |
+} |
+ |
+int64_t Simulator::ByteReverse(int64_t dword) { |
+#if defined(__GNUC__) |
+ return __builtin_bswap64(dword); |
+#else |
+#error unsupport __builtin_bswap64 |
+#endif |
} |
int Simulator::DecodeInstructionOriginal(Instruction* instr) { |
@@ -9822,9 +9843,13 @@ EVALUATE(DSGR) { |
} |
EVALUATE(LRVGR) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(LRVGR); |
+ DECODE_RRE_INSTRUCTION(r1, r2); |
+ int64_t r2_val = get_register(r2); |
+ int64_t r1_val = ByteReverse(r2_val); |
+ |
+ set_register(r1, r1_val); |
+ return length; |
} |
EVALUATE(LPGFR) { |
@@ -9937,9 +9962,13 @@ EVALUATE(KMAC) { |
} |
EVALUATE(LRVR) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
+ DCHECK_OPCODE(LRVR); |
+ DECODE_RRE_INSTRUCTION(r1, r2); |
+ int32_t r2_val = get_low_register<int32_t>(r2); |
+ int32_t r1_val = ByteReverse(r2_val); |
+ |
+ set_low_register(r1, r1_val); |
+ return length; |
} |
EVALUATE(CGR) { |
@@ -10738,12 +10767,6 @@ EVALUATE(CVBG) { |
return 0; |
} |
-EVALUATE(LRVG) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
-} |
- |
EVALUATE(LT) { |
DCHECK_OPCODE(LT); |
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
@@ -10840,6 +10863,17 @@ EVALUATE(DSGF) { |
return 0; |
} |
+EVALUATE(LRVG) { |
+ DCHECK_OPCODE(LRVG); |
+ 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); |
+ intptr_t mem_addr = b2_val + x2_val + d2; |
+ int64_t mem_val = ReadW64(mem_addr, instr); |
+ set_register(r1, ByteReverse(mem_val)); |
+ return length; |
+} |
+ |
EVALUATE(LRV) { |
DCHECK_OPCODE(LRV); |
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
@@ -10907,12 +10941,6 @@ EVALUATE(CVDG) { |
return 0; |
} |
-EVALUATE(STRVG) { |
- UNIMPLEMENTED(); |
- USE(instr); |
- return 0; |
-} |
- |
EVALUATE(CGF) { |
UNIMPLEMENTED(); |
USE(instr); |
@@ -10954,6 +10982,17 @@ EVALUATE(STRV) { |
return length; |
} |
+EVALUATE(STRVG) { |
+ DCHECK_OPCODE(STRVG); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int64_t r1_val = get_register(r1); |
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ intptr_t mem_addr = b2_val + x2_val + d2; |
+ WriteDW(mem_addr, ByteReverse(r1_val)); |
+ return length; |
+} |
+ |
EVALUATE(STRVH) { |
DCHECK_OPCODE(STRVH); |
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |