| Index: src/s390/simulator-s390.cc
|
| diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc
|
| index c1b6ba3a1167f6aeb80f2bf53e7c99c401699638..74a25d53572d4fd5b7e08af3a8312fe05bbfa34d 100644
|
| --- a/src/s390/simulator-s390.cc
|
| +++ b/src/s390/simulator-s390.cc
|
| @@ -842,6 +842,7 @@ void Simulator::EvalTableInit() {
|
| EvalTable[OI] = &Simulator::Evaluate_OI;
|
| EvalTable[XI] = &Simulator::Evaluate_XI;
|
| EvalTable[LM] = &Simulator::Evaluate_LM;
|
| + EvalTable[CS] = &Simulator::Evaluate_CS;
|
| EvalTable[MVCLE] = &Simulator::Evaluate_MVCLE;
|
| EvalTable[CLCLE] = &Simulator::Evaluate_CLCLE;
|
| EvalTable[MC] = &Simulator::Evaluate_MC;
|
| @@ -6446,7 +6447,7 @@ EVALUATE(RISBG) {
|
|
|
| if (!zero_remaining) {
|
| // Merged the unselected bits from the original value
|
| - selected_val = (src_val & ~selection_mask) | selected_val;
|
| + selected_val = (get_register(r1) & ~selection_mask) | selected_val;
|
| }
|
|
|
| // Condition code is set by treating result as 64-bit signed int
|
| @@ -7811,10 +7812,10 @@ EVALUATE(TMLL) {
|
| mask = 0x80000000u >> leadingZeros;
|
| if (mask & r1_val) {
|
| // leftmost bit is one
|
| - condition_reg_ = 0x4;
|
| + condition_reg_ = 0x2;
|
| } else {
|
| // leftmost bit is zero
|
| - condition_reg_ = 0x2;
|
| + condition_reg_ = 0x4;
|
| }
|
| return length; // Done!
|
| #else
|
| @@ -10499,9 +10500,13 @@ EVALUATE(LLCR) {
|
| }
|
|
|
| EVALUATE(LLHR) {
|
| - UNIMPLEMENTED();
|
| - USE(instr);
|
| - return 0;
|
| + DCHECK_OPCODE(LLHR);
|
| + DECODE_RRE_INSTRUCTION(r1, r2);
|
| + uint32_t r2_val = get_low_register<uint32_t>(r2);
|
| + r2_val <<= 16;
|
| + r2_val >>= 16;
|
| + set_low_register(r1, r2_val);
|
| + return length;
|
| }
|
|
|
| EVALUATE(MLR) {
|
| @@ -11979,7 +11984,53 @@ EVALUATE(SLLG) {
|
| return length;
|
| }
|
|
|
| +EVALUATE(CS) {
|
| + DCHECK_OPCODE(CS);
|
| + DECODE_RS_A_INSTRUCTION(r1, r3, rb, d2);
|
| + int32_t offset = d2;
|
| + int64_t rb_val = (rb == 0) ? 0 : get_register(rb);
|
| + intptr_t target_addr = static_cast<intptr_t>(rb_val) + offset;
|
| +
|
| + int32_t r1_val = get_low_register<int32_t>(r1);
|
| + int32_t r3_val = get_low_register<int32_t>(r3);
|
| +
|
| + DCHECK((target_addr & 0x3) == 0);
|
| + bool is_success = __atomic_compare_exchange_n(
|
| + reinterpret_cast<int32_t*>(target_addr), &r1_val, r3_val, true,
|
| + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
| + if (!is_success) {
|
| + set_low_register(r1, r1_val);
|
| + condition_reg_ = 0x4;
|
| + } else {
|
| + condition_reg_ = 0x8;
|
| + }
|
| + return length;
|
| +}
|
| +
|
| EVALUATE(CSY) {
|
| + DCHECK_OPCODE(CSY);
|
| + DECODE_RSY_A_INSTRUCTION(r1, r3, b2, d2);
|
| + int32_t offset = d2;
|
| + int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
|
| + intptr_t target_addr = static_cast<intptr_t>(b2_val) + offset;
|
| +
|
| + int32_t r1_val = get_low_register<int32_t>(r1);
|
| + int32_t r3_val = get_low_register<int32_t>(r3);
|
| +
|
| + DCHECK((target_addr & 0x3) == 0);
|
| + bool is_success = __atomic_compare_exchange_n(
|
| + reinterpret_cast<int32_t*>(target_addr), &r1_val, r3_val, true,
|
| + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
| + if (!is_success) {
|
| + set_low_register(r1, r1_val);
|
| + condition_reg_ = 0x4;
|
| + } else {
|
| + condition_reg_ = 0x8;
|
| + }
|
| + return length;
|
| +}
|
| +
|
| +EVALUATE(CSG) {
|
| UNIMPLEMENTED();
|
| USE(instr);
|
| return 0;
|
|
|