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

Unified Diff: src/s390/simulator-s390.cc

Issue 1993063002: S390: Added 56 new instructions to the simulator EVALUATE code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Removed DCHECKs prohibiting generation of AGF, SGF on 31-bit Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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); }
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698