| Index: src/s390/simulator-s390.cc
|
| diff --git a/src/s390/simulator-s390.cc b/src/s390/simulator-s390.cc
|
| index b86132f12c7e0dae7715a22716c642ceba42f0d4..c5d3a1c3bbfdbae5ee8ca439c286decffd6ac546 100644
|
| --- a/src/s390/simulator-s390.cc
|
| +++ b/src/s390/simulator-s390.cc
|
| @@ -6613,15 +6613,16 @@ EVALUATE(LCR) {
|
| DCHECK_OPCODE(LCR);
|
| DECODE_RR_INSTRUCTION(r1, r2);
|
| int32_t r2_val = get_low_register<int32_t>(r2);
|
| - r2_val = ~r2_val;
|
| - r2_val = r2_val + 1;
|
| - set_low_register(r1, r2_val);
|
| + int32_t result = 0;
|
| + bool isOF = false;
|
| + isOF = __builtin_ssub_overflow(0, r2_val, &result);
|
| + set_low_register(r1, result);
|
| SetS390ConditionCode<int32_t>(r2_val, 0);
|
| // Checks for overflow where r2_val = -2147483648.
|
| // Cannot do int comparison due to GCC 4.8 bug on x86.
|
| // Detect INT_MIN alternatively, as it is the only value where both
|
| // original and result are negative due to overflow.
|
| - if (r2_val == (static_cast<int32_t>(1) << 31)) {
|
| + if (isOF) {
|
| SetS390OverflowCode(true);
|
| }
|
| return length;
|
| @@ -9972,12 +9973,16 @@ EVALUATE(LCGR) {
|
| DCHECK_OPCODE(LCGR);
|
| DECODE_RRE_INSTRUCTION(r1, r2);
|
| int64_t r2_val = get_register(r2);
|
| - r2_val = ~r2_val;
|
| - r2_val = r2_val + 1;
|
| - set_register(r1, r2_val);
|
| - SetS390ConditionCode<int64_t>(r2_val, 0);
|
| - // if the input is INT_MIN, loading its compliment would be overflowing
|
| - if (r2_val == (static_cast<int64_t>(1) << 63)) {
|
| + int64_t result = 0;
|
| + bool isOF = false;
|
| +#ifdef V8_TARGET_ARCH_S390X
|
| + isOF = __builtin_ssubl_overflow(0L, r2_val, &result);
|
| +#else
|
| + isOF = __builtin_ssubll_overflow(0L, r2_val, &result);
|
| +#endif
|
| + set_register(r1, result);
|
| + SetS390ConditionCode<int64_t>(result, 0);
|
| + if (isOF) {
|
| SetS390OverflowCode(true);
|
| }
|
| return length;
|
|
|