diff options
Diffstat (limited to 'deps/v8/src/s390/simulator-s390.cc')
-rw-r--r-- | deps/v8/src/s390/simulator-s390.cc | 244 |
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) { |