Index: src/s390/simulator-s390.cc |
diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc |
index 57806d5393f58e85475377177addf805112ae907..7503b477116920d6a1c7fcc51f08dc5bdcb381bb 100644 |
--- a/src/s390/simulator-s390.cc |
+++ b/src/s390/simulator-s390.cc |
@@ -5948,6 +5948,18 @@ uintptr_t Simulator::PopAddress() { |
uint8_t imm_val = AS(SIInstruction)->I2Value(); \ |
int length = 4; |
+#define DECODE_SIL_INSTRUCTION(b1, d1, i2) \ |
+ int b1 = AS(SILInstruction)->B1Value(); \ |
+ intptr_t d1 = AS(SILInstruction)->D1Value(); \ |
+ int16_t i2 = AS(SILInstruction)->I2Value(); \ |
+ int length = 6; |
+ |
+#define DECODE_SIY_INSTRUCTION(b1, d1, i2) \ |
+ int b1 = AS(SIYInstruction)->B1Value(); \ |
+ intptr_t d1 = AS(SIYInstruction)->D1Value(); \ |
+ uint8_t i2 = AS(SIYInstruction)->I2Value(); \ |
+ int length = 6; |
+ |
#define DECODE_RRE_INSTRUCTION(r1, r2) \ |
int r1 = AS(RREInstruction)->R1Value(); \ |
int r2 = AS(RREInstruction)->R2Value(); \ |
@@ -6017,6 +6029,13 @@ uintptr_t Simulator::PopAddress() { |
int16_t i2 = AS(RIInstruction)->I2Value(); \ |
int length = 4; |
+#define DECODE_RXE_INSTRUCTION(r1, b2, x2, d2) \ |
+ int r1 = AS(RXEInstruction)->R1Value(); \ |
+ int b2 = AS(RXEInstruction)->B2Value(); \ |
+ int x2 = AS(RXEInstruction)->X2Value(); \ |
+ int d2 = AS(RXEInstruction)->D2Value(); \ |
+ int length = 6; |
+ |
#define GET_ADDRESS(index_reg, base_reg, offset) \ |
(((index_reg) == 0) ? 0 : get_register(index_reg)) + \ |
(((base_reg) == 0) ? 0 : get_register(base_reg)) + offset |
@@ -9164,13 +9183,49 @@ EVALUATE(LGH) { |
return length; |
} |
-EVALUATE(LLGF) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LLGF) { |
+ DCHECK_OPCODE(LLGF); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ // Miscellaneous Loads and Stores |
+ int64_t x2_val = (x2 == 0) ? 0 : get_register(x2); |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ intptr_t addr = x2_val + b2_val + d2; |
+ uint64_t mem_val = static_cast<uint64_t>(ReadWU(addr, instr)); |
+ set_register(r1, mem_val); |
+ return length; |
+} |
EVALUATE(LLGT) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(AGF) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(AGF) { |
+ DCHECK_OPCODE(AGF); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ uint64_t r1_val = get_register(r1); |
+ 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; |
+ uint64_t alu_out = r1_val; |
+ uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); |
+ alu_out += mem_val; |
+ SetS390ConditionCode<int64_t>(alu_out, 0); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(SGF) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SGF) { |
+ DCHECK_OPCODE(SGF); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ uint64_t r1_val = get_register(r1); |
+ 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; |
+ uint64_t alu_out = r1_val; |
+ uint32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr); |
+ alu_out -= mem_val; |
+ SetS390ConditionCode<int64_t>(alu_out, 0); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(ALGF) { return DecodeInstructionOriginal(instr); } |
@@ -9180,13 +9235,54 @@ EVALUATE(MSGF) { return DecodeInstructionOriginal(instr); } |
EVALUATE(DSGF) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LRV) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LRV) { |
+ DCHECK_OPCODE(LRV); |
+ 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; |
+ int32_t mem_val = ReadW(mem_addr, instr); |
+ set_low_register(r1, ByteReverse(mem_val)); |
+ return length; |
+} |
-EVALUATE(LRVH) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LRVH) { |
+ DCHECK_OPCODE(LRVH); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int32_t r1_val = get_low_register<int32_t>(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; |
+ int16_t mem_val = ReadH(mem_addr, instr); |
+ int32_t result = ByteReverse(mem_val) & 0x0000ffff; |
+ result |= r1_val & 0xffff0000; |
+ set_low_register(r1, result); |
+ return length; |
+} |
-EVALUATE(CG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CG) { |
+ DCHECK_OPCODE(CG); |
+ 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); |
+ int64_t alu_out = get_register(r1); |
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2); |
+ SetS390ConditionCode<int64_t>(alu_out, mem_val); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(CLG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CLG) { |
+ DCHECK_OPCODE(CLG); |
+ 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); |
+ int64_t alu_out = get_register(r1); |
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2); |
+ SetS390ConditionCode<uint64_t>(alu_out, mem_val); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(NTSTG) { return DecodeInstructionOriginal(instr); } |
@@ -9206,9 +9302,28 @@ EVALUATE(CGH) { return DecodeInstructionOriginal(instr); } |
EVALUATE(PFD) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(STRV) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(STRV) { |
+ DCHECK_OPCODE(STRV); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int32_t r1_val = get_low_register<int32_t>(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; |
+ WriteW(mem_addr, ByteReverse(r1_val), instr); |
+ return length; |
+} |
-EVALUATE(STRVH) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(STRVH) { |
+ DCHECK_OPCODE(STRVH); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int32_t r1_val = get_low_register<int32_t>(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; |
+ int16_t result = static_cast<int16_t>(r1_val >> 16); |
+ WriteH(mem_addr, ByteReverse(result), instr); |
+ return length; |
+} |
EVALUATE(BCTG) { return DecodeInstructionOriginal(instr); } |
@@ -9224,25 +9339,126 @@ EVALUATE(MSY) { |
return length; |
} |
-EVALUATE(NY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(NY) { |
+ DCHECK_OPCODE(NY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ alu_out &= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(CLY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CLY) { |
+ DCHECK_OPCODE(CLY); |
+ 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); |
+ uint32_t alu_out = get_low_register<uint32_t>(r1); |
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); |
+ SetS390ConditionCode<uint32_t>(alu_out, mem_val); |
+ return length; |
+} |
-EVALUATE(OY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(OY) { |
+ DCHECK_OPCODE(OY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ alu_out |= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(XY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(XY) { |
+ DCHECK_OPCODE(XY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ alu_out ^= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(CY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CY) { |
+ DCHECK_OPCODE(CY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ SetS390ConditionCode<int32_t>(alu_out, mem_val); |
+ return length; |
+} |
-EVALUATE(AY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(AY) { |
+ DCHECK_OPCODE(AY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ bool isOF = false; |
+ isOF = CheckOverflowForIntAdd(alu_out, mem_val, int32_t); |
+ alu_out += mem_val; |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(SY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SY) { |
+ DCHECK_OPCODE(SY); |
+ 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); |
+ int32_t alu_out = get_low_register<int32_t>(r1); |
+ int32_t mem_val = ReadW(b2_val + x2_val + d2, instr); |
+ bool isOF = false; |
+ isOF = CheckOverflowForIntSub(alu_out, mem_val, int32_t); |
+ alu_out -= mem_val; |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(MFY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(ALY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(ALY) { |
+ DCHECK_OPCODE(ALY); |
+ 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); |
+ uint32_t alu_out = get_low_register<uint32_t>(r1); |
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); |
+ alu_out += mem_val; |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<uint32_t>(alu_out, 0); |
+ return length; |
+} |
-EVALUATE(SLY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SLY) { |
+ DCHECK_OPCODE(SLY); |
+ 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); |
+ uint32_t alu_out = get_low_register<uint32_t>(r1); |
+ uint32_t mem_val = ReadWU(b2_val + x2_val + d2, instr); |
+ alu_out -= mem_val; |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<uint32_t>(alu_out, 0); |
+ return length; |
+} |
EVALUATE(STHY) { |
DCHECK_OPCODE(STHY); |
@@ -9256,7 +9472,18 @@ EVALUATE(STHY) { |
return length; |
} |
-EVALUATE(LAY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LAY) { |
+ DCHECK_OPCODE(LAY); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ // Load Address |
+ int rb = b2; |
+ int rx = x2; |
+ int offset = d2; |
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb); |
+ int64_t rx_val = (rx == 0) ? 0 : get_register(rx); |
+ set_register(r1, rx_val + rb_val + offset); |
+ return length; |
+} |
EVALUATE(STCY) { |
DCHECK_OPCODE(STCY); |
@@ -9274,7 +9501,17 @@ EVALUATE(ICY) { return DecodeInstructionOriginal(instr); } |
EVALUATE(LAEY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LB) { |
+ DCHECK_OPCODE(LB); |
+ // Miscellaneous Loads and Stores |
+ 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 addr = x2_val + b2_val + d2; |
+ int32_t mem_val = ReadB(addr); |
+ set_low_register(r1, mem_val); |
+ return length; |
+} |
EVALUATE(LGB) { |
DCHECK_OPCODE(LGB); |
@@ -9302,17 +9539,84 @@ EVALUATE(LHY) { |
EVALUATE(CHY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(AHY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(AHY) { |
+ DCHECK_OPCODE(AHY); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int32_t r1_val = get_low_register<int32_t>(r1); |
+ 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; |
+ int32_t mem_val = |
+ static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr)); |
+ int32_t alu_out = 0; |
+ bool isOF = false; |
+ alu_out = r1_val + mem_val; |
+ isOF = CheckOverflowForIntAdd(r1_val, mem_val, int32_t); |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
-EVALUATE(SHY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SHY) { |
+ DCHECK_OPCODE(SHY); |
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2); |
+ int32_t r1_val = get_low_register<int32_t>(r1); |
+ 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; |
+ int32_t mem_val = |
+ static_cast<int32_t>(ReadH(b2_val + d2_val + x2_val, instr)); |
+ int32_t alu_out = 0; |
+ bool isOF = false; |
+ alu_out = r1_val - mem_val; |
+ isOF = CheckOverflowForIntSub(r1_val, mem_val, int64_t); |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
EVALUATE(MHY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(NG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(NG) { |
+ DCHECK_OPCODE(NG); |
+ 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); |
+ int64_t alu_out = get_register(r1); |
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2); |
+ alu_out &= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(OG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(OG) { |
+ DCHECK_OPCODE(OG); |
+ 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); |
+ int64_t alu_out = get_register(r1); |
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2); |
+ alu_out |= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(XG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(XG) { |
+ DCHECK_OPCODE(XG); |
+ 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); |
+ int64_t alu_out = get_register(r1); |
+ int64_t mem_val = ReadDW(b2_val + x2_val + d2); |
+ alu_out ^= mem_val; |
+ SetS390BitWiseConditionCode<uint32_t>(alu_out); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(LGAT) { return DecodeInstructionOriginal(instr); } |
@@ -9328,9 +9632,29 @@ EVALUATE(STPQ) { return DecodeInstructionOriginal(instr); } |
EVALUATE(LPQ) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LLGH) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LLGH) { |
+ DCHECK_OPCODE(LLGH); |
+ // Load Logical Halfword |
+ 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; |
+ uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr); |
+ set_register(r1, mem_val); |
+ return length; |
+} |
-EVALUATE(LLH) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LLH) { |
+ DCHECK_OPCODE(LLH); |
+ // Load Logical Halfword |
+ 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; |
+ uint16_t mem_val = ReadHU(b2_val + d2_val + x2_val, instr); |
+ set_low_register(r1, mem_val); |
+ return length; |
+} |
EVALUATE(ML) { return DecodeInstructionOriginal(instr); } |
@@ -9370,9 +9694,25 @@ EVALUATE(MVCDK) { return DecodeInstructionOriginal(instr); } |
EVALUATE(MVHHI) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(MVGHI) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(MVGHI) { |
+ DCHECK_OPCODE(MVGHI); |
+ // Move Integer (64) |
+ DECODE_SIL_INSTRUCTION(b1, d1, i2); |
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ intptr_t src_addr = b1_val + d1; |
+ WriteDW(src_addr, i2); |
+ return length; |
+} |
-EVALUATE(MVHI) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(MVHI) { |
+ DCHECK_OPCODE(MVHI); |
+ // Move Integer (32) |
+ DECODE_SIL_INSTRUCTION(b1, d1, i2); |
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ intptr_t src_addr = b1_val + d1; |
+ WriteW(src_addr, i2, instr); |
+ return length; |
+} |
EVALUATE(CHHSI) { return DecodeInstructionOriginal(instr); } |
@@ -9386,21 +9726,143 @@ EVALUATE(TBEGIN) { return DecodeInstructionOriginal(instr); } |
EVALUATE(TBEGINC) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LMG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LMG) { |
+ DCHECK_OPCODE(LMG); |
+ // Store Multiple 64-bits. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ int rb = b2; |
+ int offset = d2; |
+ |
+ // Regs roll around if r3 is less than r1. |
+ // Artifically increase r3 by 16 so we can calculate |
+ // the number of regs stored properly. |
+ if (r3 < r1) r3 += 16; |
+ |
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb); |
-EVALUATE(SRAG) { return DecodeInstructionOriginal(instr); } |
+ // Store each register in ascending order. |
+ for (int i = 0; i <= r3 - r1; i++) { |
+ int64_t value = ReadDW(rb_val + offset + 8 * i); |
+ set_register((r1 + i) % 16, value); |
+ } |
+ return length; |
+} |
+ |
+EVALUATE(SRAG) { |
+ DCHECK_OPCODE(SRAG); |
+ // 64-bit non-clobbering shift-left/right arithmetic |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ int64_t r3_val = get_register(r3); |
+ intptr_t alu_out = 0; |
+ bool isOF = false; |
+ alu_out = r3_val >> shiftBits; |
+ set_register(r1, alu_out); |
+ SetS390ConditionCode<intptr_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
-EVALUATE(SLAG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SLAG) { |
+ DCHECK_OPCODE(SLAG); |
+ // 64-bit non-clobbering shift-left/right arithmetic |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ int64_t r3_val = get_register(r3); |
+ intptr_t alu_out = 0; |
+ bool isOF = false; |
+ isOF = CheckOverflowForShiftLeft(r3_val, shiftBits); |
+ alu_out = r3_val << shiftBits; |
+ set_register(r1, alu_out); |
+ SetS390ConditionCode<intptr_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
-EVALUATE(SRLG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SRLG) { |
+ DCHECK_OPCODE(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. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 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; |
+ alu_out = r3_val >> shiftBits; |
+ set_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(SLLG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SLLG) { |
+ DCHECK_OPCODE(SLLG); |
+ // 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. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 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; |
+ alu_out = r3_val << shiftBits; |
+ set_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(CSY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(RLLG) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(RLLG) { |
+ DCHECK_OPCODE(RLLG); |
+ // 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. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 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; |
+ uint64_t rotateBits = r3_val >> (64 - shiftBits); |
+ alu_out = (r3_val << shiftBits) | (rotateBits); |
+ set_register(r1, alu_out); |
+ return length; |
+} |
+ |
+EVALUATE(STMG) { |
+ DCHECK_OPCODE(STMG); |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ int rb = b2; |
+ int offset = d2; |
-EVALUATE(STMG) { return DecodeInstructionOriginal(instr); } |
+ // Regs roll around if r3 is less than r1. |
+ // Artifically increase r3 by 16 so we can calculate |
+ // the number of regs stored properly. |
+ if (r3 < r1) r3 += 16; |
+ |
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb); |
+ |
+ // Store each register in ascending order. |
+ for (int i = 0; i <= r3 - r1; i++) { |
+ int64_t value = get_register((r1 + i) % 16); |
+ WriteDW(rb_val + offset + 8 * i, value); |
+ } |
+ return length; |
+} |
EVALUATE(STMH) { return DecodeInstructionOriginal(instr); } |
@@ -9418,23 +9880,97 @@ EVALUATE(BXLEG) { return DecodeInstructionOriginal(instr); } |
EVALUATE(ECAG) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(TMY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(TMY) { |
+ DCHECK_OPCODE(TMY); |
+ // Test Under Mask (Mem - Imm) (8) |
+ DECODE_SIY_INSTRUCTION(b1, d1, i2); |
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ intptr_t d1_val = d1; |
+ intptr_t addr = b1_val + d1_val; |
+ uint8_t mem_val = ReadB(addr); |
+ uint8_t imm_val = i2; |
+ uint8_t selected_bits = mem_val & imm_val; |
+ // CC0: Selected bits are zero |
+ // CC1: Selected bits mixed zeros and ones |
+ // CC3: Selected bits all ones |
+ if (0 == selected_bits) { |
+ condition_reg_ = CC_EQ; // CC0 |
+ } else if (selected_bits == imm_val) { |
+ condition_reg_ = 0x1; // CC3 |
+ } else { |
+ condition_reg_ = 0x4; // CC1 |
+ } |
+ return length; |
+} |
EVALUATE(MVIY) { return DecodeInstructionOriginal(instr); } |
EVALUATE(NIY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(CLIY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CLIY) { |
+ DCHECK_OPCODE(CLIY); |
+ DECODE_SIY_INSTRUCTION(b1, d1, i2); |
+ // Compare Immediate (Mem - Imm) (8) |
+ int64_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ intptr_t d1_val = d1; |
+ intptr_t addr = b1_val + d1_val; |
+ uint8_t mem_val = ReadB(addr); |
+ uint8_t imm_val = i2; |
+ SetS390ConditionCode<uint8_t>(mem_val, imm_val); |
+ return length; |
+} |
EVALUATE(OIY) { return DecodeInstructionOriginal(instr); } |
EVALUATE(XIY) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(ASI) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(ASI) { |
+ DCHECK_OPCODE(ASI); |
+ // TODO(bcleung): Change all fooInstr->I2Value() to template functions. |
+ // The below static cast to 8 bit and then to 32 bit is necessary |
+ // because siyInstr->I2Value() returns a uint8_t, which a direct |
+ // cast to int32_t could incorrectly interpret. |
+ DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned); |
+ int8_t i2_8bit = static_cast<int8_t>(i2_unsigned); |
+ int32_t i2 = static_cast<int32_t>(i2_8bit); |
+ intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ |
+ int d1_val = d1; |
+ intptr_t addr = b1_val + d1_val; |
+ |
+ int32_t mem_val = ReadW(addr, instr); |
+ bool isOF = CheckOverflowForIntAdd(mem_val, i2, int32_t); |
+ int32_t alu_out = mem_val + i2; |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ WriteW(addr, alu_out, instr); |
+ return length; |
+} |
EVALUATE(ALSI) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(AGSI) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(AGSI) { |
+ DCHECK_OPCODE(AGSI); |
+ // TODO(bcleung): Change all fooInstr->I2Value() to template functions. |
+ // The below static cast to 8 bit and then to 32 bit is necessary |
+ // because siyInstr->I2Value() returns a uint8_t, which a direct |
+ // cast to int32_t could incorrectly interpret. |
+ DECODE_SIY_INSTRUCTION(b1, d1, i2_unsigned); |
+ int8_t i2_8bit = static_cast<int8_t>(i2_unsigned); |
+ int64_t i2 = static_cast<int64_t>(i2_8bit); |
+ intptr_t b1_val = (b1 == 0) ? 0 : get_register(b1); |
+ |
+ int d1_val = d1; |
+ intptr_t addr = b1_val + d1_val; |
+ |
+ int64_t mem_val = ReadDW(addr); |
+ int isOF = CheckOverflowForIntAdd(mem_val, i2, int64_t); |
+ int64_t alu_out = mem_val + i2; |
+ SetS390ConditionCode<uint64_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ WriteDW(addr, alu_out); |
+ return length; |
+} |
EVALUATE(ALGSI) { return DecodeInstructionOriginal(instr); } |
@@ -9446,21 +9982,124 @@ EVALUATE(MVCLU) { return DecodeInstructionOriginal(instr); } |
EVALUATE(CLCLU) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(STMY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(STMY) { |
+ DCHECK_OPCODE(STMY); |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // Load/Store Multiple (32) |
+ int offset = d2; |
+ |
+ // Regs roll around if r3 is less than r1. |
+ // Artifically increase r3 by 16 so we can calculate |
+ // the number of regs stored properly. |
+ if (r3 < r1) r3 += 16; |
+ |
+ int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2); |
+ |
+ // Store each register in ascending order. |
+ for (int i = 0; i <= r3 - r1; i++) { |
+ int32_t value = get_low_register<int32_t>((r1 + i) % 16); |
+ WriteW(b2_val + offset + 4 * i, value, instr); |
+ } |
+ return length; |
+} |
EVALUATE(LMH) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LMY) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LMY) { |
+ DCHECK_OPCODE(LMY); |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // Load/Store Multiple (32) |
+ int offset = d2; |
+ |
+ // Regs roll around if r3 is less than r1. |
+ // Artifically increase r3 by 16 so we can calculate |
+ // the number of regs stored properly. |
+ if (r3 < r1) r3 += 16; |
+ |
+ int32_t b2_val = (b2 == 0) ? 0 : get_low_register<int32_t>(b2); |
+ |
+ // Store each register in ascending order. |
+ for (int i = 0; i <= r3 - r1; i++) { |
+ int32_t value = ReadW(b2_val + offset + 4 * i, instr); |
+ set_low_register((r1 + i) % 16, value); |
+ } |
+ return length; |
+} |
EVALUATE(TP) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(SRAK) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SRAK) { |
+ DCHECK_OPCODE(SRAK); |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 32-bit non-clobbering shift-left/right arithmetic |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ int32_t r3_val = get_low_register<int32_t>(r3); |
+ int32_t alu_out = 0; |
+ bool isOF = false; |
+ alu_out = r3_val >> shiftBits; |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
-EVALUATE(SLAK) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SLAK) { |
+ DCHECK_OPCODE(SLAK); |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 32-bit non-clobbering shift-left/right arithmetic |
+ // only takes rightmost 6 bits |
+ int64_t b2_val = (b2 == 0) ? 0 : get_register(b2); |
+ int shiftBits = (b2_val + d2) & 0x3F; |
+ int32_t r3_val = get_low_register<int32_t>(r3); |
+ int32_t alu_out = 0; |
+ bool isOF = false; |
+ isOF = CheckOverflowForShiftLeft(r3_val, shiftBits); |
+ alu_out = r3_val << shiftBits; |
+ set_low_register(r1, alu_out); |
+ SetS390ConditionCode<int32_t>(alu_out, 0); |
+ SetS390OverflowCode(isOF); |
+ return length; |
+} |
-EVALUATE(SRLK) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SRLK) { |
+ DCHECK_OPCODE(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. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 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; |
+ alu_out = r3_val >> shiftBits; |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
-EVALUATE(SLLK) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SLLK) { |
+ DCHECK_OPCODE(SLLK); |
+ // 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. |
+ DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2); |
+ // 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; |
+ alu_out = r3_val << shiftBits; |
+ set_low_register(r1, alu_out); |
+ return length; |
+} |
EVALUATE(LOCG) { return DecodeInstructionOriginal(instr); } |
@@ -9528,7 +10167,20 @@ EVALUATE(CGIB) { return DecodeInstructionOriginal(instr); } |
EVALUATE(CIB) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(LDEB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(LDEB) { |
+ DCHECK_OPCODE(LDEB); |
+ // Load Float |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, d2); |
+ int rb = b2; |
+ int rx = x2; |
+ int offset = d2; |
+ int64_t rb_val = (rb == 0) ? 0 : get_register(rb); |
+ int64_t rx_val = (rx == 0) ? 0 : get_register(rx); |
+ double ret = |
+ static_cast<double>(*reinterpret_cast<float*>(rx_val + rb_val + offset)); |
+ set_d_register_from_double(r1, ret); |
+ return length; |
+} |
EVALUATE(LXDB) { return DecodeInstructionOriginal(instr); } |
@@ -9560,21 +10212,92 @@ EVALUATE(TCXB) { return DecodeInstructionOriginal(instr); } |
EVALUATE(SQEB) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(SQDB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SQDB) { |
+ DCHECK_OPCODE(SQDB); |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ r1_val = std::sqrt(dbl_val); |
+ set_d_register_from_double(r1, r1_val); |
+ return length; |
+} |
EVALUATE(MEEB) { return DecodeInstructionOriginal(instr); } |
EVALUATE(KDB) { return DecodeInstructionOriginal(instr); } |
-EVALUATE(CDB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(CDB) { |
+ DCHECK_OPCODE(CDB); |
-EVALUATE(ADB) { return DecodeInstructionOriginal(instr); } |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ SetS390ConditionCode<double>(r1_val, dbl_val); |
+ return length; |
+} |
-EVALUATE(SDB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(ADB) { |
+ DCHECK_OPCODE(ADB); |
-EVALUATE(MDB) { return DecodeInstructionOriginal(instr); } |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ r1_val += dbl_val; |
+ set_d_register_from_double(r1, r1_val); |
+ SetS390ConditionCode<double>(r1_val, 0); |
+ return length; |
+} |
-EVALUATE(DDB) { return DecodeInstructionOriginal(instr); } |
+EVALUATE(SDB) { |
+ DCHECK_OPCODE(SDB); |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ r1_val -= dbl_val; |
+ set_d_register_from_double(r1, r1_val); |
+ SetS390ConditionCode<double>(r1_val, 0); |
+ return length; |
+} |
+ |
+EVALUATE(MDB) { |
+ DCHECK_OPCODE(MDB); |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ r1_val *= dbl_val; |
+ set_d_register_from_double(r1, r1_val); |
+ SetS390ConditionCode<double>(r1_val, 0); |
+ return length; |
+} |
+ |
+EVALUATE(DDB) { |
+ DCHECK_OPCODE(DDB); |
+ DECODE_RXE_INSTRUCTION(r1, b2, x2, 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; |
+ double r1_val = get_double_from_d_register(r1); |
+ double dbl_val = ReadDouble(b2_val + x2_val + d2_val); |
+ r1_val /= dbl_val; |
+ set_d_register_from_double(r1, r1_val); |
+ SetS390ConditionCode<double>(r1_val, 0); |
+ return length; |
+} |
EVALUATE(MADB) { return DecodeInstructionOriginal(instr); } |