aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/s390/simulator-s390.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/s390/simulator-s390.cc')
-rw-r--r--deps/v8/src/s390/simulator-s390.cc244
1 files changed, 200 insertions, 44 deletions
diff --git a/deps/v8/src/s390/simulator-s390.cc b/deps/v8/src/s390/simulator-s390.cc
index 74d37bc20a..311e59d5e6 100644
--- a/deps/v8/src/s390/simulator-s390.cc
+++ b/deps/v8/src/s390/simulator-s390.cc
@@ -743,6 +743,18 @@ void Simulator::EvalTableInit() {
EvalTable[i] = &Simulator::Evaluate_Unknown;
}
+#define S390_SUPPORTED_VECTOR_OPCODE_LIST(V) \
+ V(vfs, VFS, 0xE7E2) /* type = VRR_C VECTOR FP SUBTRACT */ \
+ V(vfa, VFA, 0xE7E3) /* type = VRR_C VECTOR FP ADD */ \
+ V(vfd, VFD, 0xE7E5) /* type = VRR_C VECTOR FP DIVIDE */ \
+ V(vfm, VFM, 0xE7E7) /* type = VRR_C VECTOR FP MULTIPLY */
+
+#define CREATE_EVALUATE_TABLE(name, op_name, op_value) \
+ EvalTable[op_name] = &Simulator::Evaluate_##op_name;
+ S390_SUPPORTED_VECTOR_OPCODE_LIST(CREATE_EVALUATE_TABLE);
+#undef CREATE_EVALUATE_TABLE
+
+ EvalTable[DUMY] = &Simulator::Evaluate_DUMY;
EvalTable[BKPT] = &Simulator::Evaluate_BKPT;
EvalTable[SPM] = &Simulator::Evaluate_SPM;
EvalTable[BALR] = &Simulator::Evaluate_BALR;
@@ -953,6 +965,7 @@ void Simulator::EvalTableInit() {
EvalTable[ALSIH] = &Simulator::Evaluate_ALSIH;
EvalTable[ALSIHN] = &Simulator::Evaluate_ALSIHN;
EvalTable[CIH] = &Simulator::Evaluate_CIH;
+ EvalTable[CLIH] = &Simulator::Evaluate_CLIH;
EvalTable[STCK] = &Simulator::Evaluate_STCK;
EvalTable[CFC] = &Simulator::Evaluate_CFC;
EvalTable[IPM] = &Simulator::Evaluate_IPM;
@@ -972,6 +985,7 @@ void Simulator::EvalTableInit() {
EvalTable[SAR] = &Simulator::Evaluate_SAR;
EvalTable[EAR] = &Simulator::Evaluate_EAR;
EvalTable[MSR] = &Simulator::Evaluate_MSR;
+ EvalTable[MSRKC] = &Simulator::Evaluate_MSRKC;
EvalTable[MVST] = &Simulator::Evaluate_MVST;
EvalTable[CUSE] = &Simulator::Evaluate_CUSE;
EvalTable[SRST] = &Simulator::Evaluate_SRST;
@@ -1145,6 +1159,7 @@ void Simulator::EvalTableInit() {
EvalTable[ALGR] = &Simulator::Evaluate_ALGR;
EvalTable[SLGR] = &Simulator::Evaluate_SLGR;
EvalTable[MSGR] = &Simulator::Evaluate_MSGR;
+ EvalTable[MSGRKC] = &Simulator::Evaluate_MSGRKC;
EvalTable[DSGR] = &Simulator::Evaluate_DSGR;
EvalTable[LRVGR] = &Simulator::Evaluate_LRVGR;
EvalTable[LPGFR] = &Simulator::Evaluate_LPGFR;
@@ -6049,6 +6064,15 @@ uintptr_t Simulator::PopAddress() {
int d2 = AS(RXEInstruction)->D2Value(); \
int length = 6;
+#define DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4) \
+ int r1 = AS(VRR_C_Instruction)->R1Value(); \
+ int r2 = AS(VRR_C_Instruction)->R2Value(); \
+ int r3 = AS(VRR_C_Instruction)->R3Value(); \
+ int m6 = AS(VRR_C_Instruction)->M6Value(); \
+ int m5 = AS(VRR_C_Instruction)->M5Value(); \
+ int m4 = AS(VRR_C_Instruction)->M4Value(); \
+ 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
@@ -6058,6 +6082,77 @@ int Simulator::Evaluate_Unknown(Instruction* instr) {
return 0;
}
+EVALUATE(VFA) {
+ DCHECK_OPCODE(VFA);
+ DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
+ USE(m6);
+ USE(m5);
+ USE(m4);
+ DCHECK(m5 == 8);
+ DCHECK(m4 == 3);
+ double r2_val = get_double_from_d_register(r2);
+ double r3_val = get_double_from_d_register(r3);
+ double r1_val = r2_val + r3_val;
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
+
+EVALUATE(VFS) {
+ DCHECK_OPCODE(VFS);
+ DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
+ USE(m6);
+ USE(m5);
+ USE(m4);
+ DCHECK(m5 == 8);
+ DCHECK(m4 == 3);
+ double r2_val = get_double_from_d_register(r2);
+ double r3_val = get_double_from_d_register(r3);
+ double r1_val = r2_val - r3_val;
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
+
+EVALUATE(VFM) {
+ DCHECK_OPCODE(VFM);
+ DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
+ USE(m6);
+ USE(m5);
+ USE(m4);
+ DCHECK(m5 == 8);
+ DCHECK(m4 == 3);
+ double r2_val = get_double_from_d_register(r2);
+ double r3_val = get_double_from_d_register(r3);
+ double r1_val = r2_val * r3_val;
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
+
+EVALUATE(VFD) {
+ DCHECK_OPCODE(VFD);
+ DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
+ USE(m6);
+ USE(m5);
+ USE(m4);
+ DCHECK(m5 == 8);
+ DCHECK(m4 == 3);
+ double r2_val = get_double_from_d_register(r2);
+ double r3_val = get_double_from_d_register(r3);
+ double r1_val = r2_val / r3_val;
+ set_d_register_from_double(r1, r1_val);
+ return length;
+}
+
+EVALUATE(DUMY) {
+ DCHECK_OPCODE(DUMY);
+ DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
+ USE(r1);
+ USE(x2);
+ USE(b2);
+ USE(d2);
+ // dummy instruction does nothing.
+ return length;
+}
+
EVALUATE(CLR) {
DCHECK_OPCODE(CLR);
DECODE_RR_INSTRUCTION(r1, r2);
@@ -6474,9 +6569,18 @@ EVALUATE(CLCL) {
}
EVALUATE(LPR) {
- UNIMPLEMENTED();
- USE(instr);
- return 0;
+ DCHECK_OPCODE(LPR);
+ // Load Positive (32)
+ DECODE_RR_INSTRUCTION(r1, r2);
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ // If negative, then negate it.
+ r2_val = (r2_val < 0) ? -r2_val : r2_val;
+ set_low_register(r1, r2_val);
+ SetS390ConditionCode<int32_t>(r2_val, 0);
+ if (r2_val == (static_cast<int32_t>(1) << 31)) {
+ SetS390OverflowCode(true);
+ }
+ return length;
}
EVALUATE(LNR) {
@@ -7677,47 +7781,38 @@ EVALUATE(TMLH) {
EVALUATE(TMLL) {
DCHECK_OPCODE(TMLL);
DECODE_RI_A_INSTRUCTION(instr, r1, i2);
- int mask = i2 & 0x0000FFFF;
- if (mask == 0) {
- condition_reg_ = 0x0;
- return length;
- }
+ uint32_t mask = i2 & 0x0000FFFF;
uint32_t r1_val = get_low_register<uint32_t>(r1);
r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
- // Test if all selected bits are Zero
- bool allSelectedBitsAreZeros = true;
- for (int i = 0; i < 15; i++) {
- if (mask & (1 << i)) {
- if (r1_val & (1 << i)) {
- allSelectedBitsAreZeros = false;
- break;
- }
- }
- }
- if (allSelectedBitsAreZeros) {
+ // Test if all selected bits are zeros or mask is zero
+ if (0 == (mask & r1_val)) {
condition_reg_ = 0x8;
return length; // Done!
}
+ DCHECK(mask != 0);
// Test if all selected bits are one
- bool allSelectedBitsAreOnes = true;
- for (int i = 0; i < 15; i++) {
- if (mask & (1 << i)) {
- if (!(r1_val & (1 << i))) {
- allSelectedBitsAreOnes = false;
- break;
- }
- }
- }
- if (allSelectedBitsAreOnes) {
+ if (mask == (mask & r1_val)) {
condition_reg_ = 0x1;
return length; // Done!
}
// Now we know selected bits mixed zeros and ones
// Test if the leftmost bit is zero or one
- for (int i = 14; i >= 0; i--) {
+#if defined(__GNUC__)
+ int leadingZeros = __builtin_clz(mask);
+ mask = 0x80000000u >> leadingZeros;
+ if (mask & r1_val) {
+ // leftmost bit is one
+ condition_reg_ = 0x4;
+ } else {
+ // leftmost bit is zero
+ condition_reg_ = 0x2;
+ }
+ return length; // Done!
+#else
+ for (int i = 15; i >= 0; i--) {
if (mask & (1 << i)) {
if (r1_val & (1 << i)) {
// leftmost bit is one
@@ -7729,6 +7824,8 @@ EVALUATE(TMLL) {
return length; // Done!
}
}
+#endif
+ UNREACHABLE();
return length;
}
@@ -8220,9 +8317,15 @@ EVALUATE(BRCTH) {
}
EVALUATE(AIH) {
- UNIMPLEMENTED();
- USE(instr);
- return 0;
+ DCHECK_OPCODE(AIH);
+ DECODE_RIL_A_INSTRUCTION(r1, i2);
+ int32_t r1_val = get_high_register<int32_t>(r1);
+ bool isOF = CheckOverflowForIntAdd(r1_val, static_cast<int32_t>(i2), int32_t);
+ r1_val += static_cast<int32_t>(i2);
+ set_high_register(r1, r1_val);
+ SetS390ConditionCode<int32_t>(r1_val, 0);
+ SetS390OverflowCode(isOF);
+ return length;
}
EVALUATE(ALSIH) {
@@ -8238,9 +8341,19 @@ EVALUATE(ALSIHN) {
}
EVALUATE(CIH) {
- UNIMPLEMENTED();
- USE(instr);
- return 0;
+ DCHECK_OPCODE(CIH);
+ DECODE_RIL_A_INSTRUCTION(r1, imm);
+ int32_t r1_val = get_high_register<int32_t>(r1);
+ SetS390ConditionCode<int32_t>(r1_val, static_cast<int32_t>(imm));
+ return length;
+}
+
+EVALUATE(CLIH) {
+ DCHECK_OPCODE(CLIH);
+ // Compare Logical with Immediate (32)
+ DECODE_RIL_A_INSTRUCTION(r1, imm);
+ SetS390ConditionCode<uint32_t>(get_high_register<uint32_t>(r1), imm);
+ return length;
}
EVALUATE(STCK) {
@@ -8360,6 +8473,21 @@ EVALUATE(MSR) {
return length;
}
+EVALUATE(MSRKC) {
+ DCHECK_OPCODE(MSRKC);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ int32_t r3_val = get_low_register<int32_t>(r3);
+ int64_t result64 =
+ static_cast<int64_t>(r2_val) * static_cast<int64_t>(r3_val);
+ int32_t result32 = static_cast<int32_t>(result64);
+ bool isOF = (static_cast<int64_t>(result32) != result64);
+ SetS390ConditionCode<int32_t>(result32, 0);
+ SetS390OverflowCode(isOF);
+ set_low_register(r1, result32);
+ return length;
+}
+
EVALUATE(MVST) {
UNIMPLEMENTED();
USE(instr);
@@ -9800,9 +9928,17 @@ EVALUATE(RRXTR) {
}
EVALUATE(LPGR) {
- UNIMPLEMENTED();
- USE(instr);
- return 0;
+ DCHECK_OPCODE(LPGR);
+ // Load Positive (32)
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int64_t r2_val = get_register(r2);
+ r2_val = (r2_val < 0) ? -r2_val : r2_val; // If negative, then negate it.
+ set_register(r1, r2_val);
+ SetS390ConditionCode<int64_t>(r2_val, 0);
+ if (r2_val == (static_cast<int64_t>(1) << 63)) {
+ SetS390OverflowCode(true);
+ }
+ return length;
}
EVALUATE(LNGR) {
@@ -9877,6 +10013,20 @@ EVALUATE(MSGR) {
return length;
}
+EVALUATE(MSGRKC) {
+ DCHECK_OPCODE(MSGRKC);
+ DECODE_RRF_A_INSTRUCTION(r1, r2, r3);
+ int64_t r2_val = get_register(r2);
+ int64_t r3_val = get_register(r3);
+ volatile int64_t result64 = r2_val * r3_val;
+ bool isOF = ((r2_val == -1 && result64 == (static_cast<int64_t>(1L) << 63)) ||
+ (r2_val != 0 && result64 / r2_val != r3_val));
+ SetS390ConditionCode<int64_t>(result64, 0);
+ SetS390OverflowCode(isOF);
+ set_register(r1, result64);
+ return length;
+}
+
EVALUATE(DSGR) {
DCHECK_OPCODE(DSGR);
DECODE_RRE_INSTRUCTION(r1, r2);
@@ -9901,9 +10051,15 @@ EVALUATE(LRVGR) {
}
EVALUATE(LPGFR) {
- UNIMPLEMENTED();
- USE(instr);
- return 0;
+ DCHECK_OPCODE(LPGFR);
+ // Load Positive (32)
+ DECODE_RRE_INSTRUCTION(r1, r2);
+ int32_t r2_val = get_low_register<int32_t>(r2);
+ // If negative, then negate it.
+ int64_t r1_val = static_cast<int64_t>((r2_val < 0) ? -r2_val : r2_val);
+ set_register(r1, r1_val);
+ SetS390ConditionCode<int64_t>(r1_val, 0);
+ return length;
}
EVALUATE(LNGFR) {
@@ -11020,9 +11176,9 @@ EVALUATE(CGH) {
}
EVALUATE(PFD) {
- UNIMPLEMENTED();
+ DCHECK_OPCODE(PFD);
USE(instr);
- return 0;
+ return 6;
}
EVALUATE(STRV) {