Version 5.1.281.30 (cherry-pick)

Merged 59b9ff3f7a7cbe848e77ffc86ead998ffd9508
Merged 141bc11e131e6d9fcffb4a30ca0ed2ea92d22

S390X: Prevent upper 32bit corruption in 32bit ops

S390: Fix storing to below stack to avoid sampler handler corrupting stored value

R=joransiu@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1947263006 .

Cr-Commit-Position: refs/branch-heads/5.1@{#34}
Cr-Branched-From: 167dc63b4c9a1d0f0fe1b19af93644ac9a561e83-refs/heads/5.1.281@{#1}
Cr-Branched-From: 03953f52bd4a184983a551927c406be6489ef89b-refs/heads/master@{#35282}
diff --git a/include/v8-version.h b/include/v8-version.h
index efc47e8..a4ab9270 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 5
 #define V8_MINOR_VERSION 1
 #define V8_BUILD_NUMBER 281
-#define V8_PATCH_LEVEL 29
+#define V8_PATCH_LEVEL 30
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/compiler/s390/code-generator-s390.cc b/src/compiler/s390/code-generator-s390.cc
index 9ede84d..7439008 100644
--- a/src/compiler/s390/code-generator-s390.cc
+++ b/src/compiler/s390/code-generator-s390.cc
@@ -813,7 +813,8 @@
       break;
     case kS390_ShiftLeft32:
       if (HasRegisterInput(instr, 1)) {
-        if (i.OutputRegister().is(i.InputRegister(1))) {
+        if (i.OutputRegister().is(i.InputRegister(1)) &&
+            !CpuFeatures::IsSupported(DISTINCT_OPS)) {
           __ LoadRR(kScratchReg, i.InputRegister(1));
           __ ShiftLeft(i.OutputRegister(), i.InputRegister(0), kScratchReg);
         } else {
@@ -822,9 +823,7 @@
       } else {
         ASSEMBLE_BINOP(ShiftLeft, ShiftLeft);
       }
-#if V8_TARGET_ARCH_S390X
-      __ lgfr(i.OutputRegister(0), i.OutputRegister(0));
-#endif
+      __ LoadlW(i.OutputRegister(0), i.OutputRegister(0));
       break;
 #if V8_TARGET_ARCH_S390X
     case kS390_ShiftLeft64:
@@ -833,7 +832,8 @@
 #endif
     case kS390_ShiftRight32:
       if (HasRegisterInput(instr, 1)) {
-        if (i.OutputRegister().is(i.InputRegister(1))) {
+        if (i.OutputRegister().is(i.InputRegister(1)) &&
+            !CpuFeatures::IsSupported(DISTINCT_OPS)) {
           __ LoadRR(kScratchReg, i.InputRegister(1));
           __ ShiftRight(i.OutputRegister(), i.InputRegister(0), kScratchReg);
         } else {
@@ -842,9 +842,7 @@
       } else {
         ASSEMBLE_BINOP(ShiftRight, ShiftRight);
       }
-#if V8_TARGET_ARCH_S390X
-      __ lgfr(i.OutputRegister(0), i.OutputRegister(0));
-#endif
+      __ LoadlW(i.OutputRegister(0), i.OutputRegister(0));
       break;
 #if V8_TARGET_ARCH_S390X
     case kS390_ShiftRight64:
@@ -853,7 +851,8 @@
 #endif
     case kS390_ShiftRightArith32:
       if (HasRegisterInput(instr, 1)) {
-        if (i.OutputRegister().is(i.InputRegister(1))) {
+        if (i.OutputRegister().is(i.InputRegister(1)) &&
+            !CpuFeatures::IsSupported(DISTINCT_OPS)) {
           __ LoadRR(kScratchReg, i.InputRegister(1));
           __ ShiftRightArith(i.OutputRegister(), i.InputRegister(0),
                              kScratchReg);
@@ -863,6 +862,7 @@
       } else {
         ASSEMBLE_BINOP(ShiftRightArith, ShiftRightArith);
       }
+      __ LoadlW(i.OutputRegister(), i.OutputRegister());
       break;
 #if V8_TARGET_ARCH_S390X
     case kS390_ShiftRightArith64:
@@ -1098,12 +1098,12 @@
     case kS390_MulHigh32:
       __ LoadRR(r1, i.InputRegister(0));
       __ mr_z(r0, i.InputRegister(1));
-      __ LoadRR(i.OutputRegister(), r0);
+      __ LoadW(i.OutputRegister(), r0);
       break;
     case kS390_MulHighU32:
       __ LoadRR(r1, i.InputRegister(0));
       __ mlr(r0, i.InputRegister(1));
-      __ LoadRR(i.OutputRegister(), r0);
+      __ LoadlW(i.OutputRegister(), r0);
       break;
     case kS390_MulFloat:
       // Ensure we don't clobber right
@@ -1136,7 +1136,8 @@
       __ LoadRR(r0, i.InputRegister(0));
       __ srda(r0, Operand(32));
       __ dr(r0, i.InputRegister(1));
-      __ ltr(i.OutputRegister(), r1);
+      __ LoadAndTestP_ExtendSrc(i.OutputRegister(),
+                                r1);  // Copy R1: Quotient to output
       break;
 #if V8_TARGET_ARCH_S390X
     case kS390_DivU64:
@@ -1150,7 +1151,8 @@
       __ LoadRR(r0, i.InputRegister(0));
       __ srdl(r0, Operand(32));
       __ dlr(r0, i.InputRegister(1));  // R0:R1: Dividend
-      __ ltr(i.OutputRegister(), r1);  // Copy R1: Quotient to output
+      __ LoadlW(i.OutputRegister(), r1);  // Copy R1: Quotient to output
+      __ LoadAndTestP_ExtendSrc(r1, r1);
       break;
 
     case kS390_DivFloat:
@@ -1292,11 +1294,7 @@
       } else {
         __ AndP(r0, i.InputRegister(0), i.InputImmediate(1));
       }
-#if V8_TARGET_ARCH_S390X
-      // TODO(john.yan): use ltgfr here.
-      __ lgfr(r0, r0);
-      __ LoadAndTestP(r0, r0);
-#endif
+      __ LoadAndTestP_ExtendSrc(r0, r0);
       break;
 #if V8_TARGET_ARCH_S390X
     case kS390_Tst64:
diff --git a/src/crankshaft/s390/lithium-codegen-s390.cc b/src/crankshaft/s390/lithium-codegen-s390.cc
index b7c112b..6b4b388 100644
--- a/src/crankshaft/s390/lithium-codegen-s390.cc
+++ b/src/crankshaft/s390/lithium-codegen-s390.cc
@@ -5202,14 +5202,11 @@
 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
   DoubleRegister value_reg = ToDoubleRegister(instr->value());
   Register result_reg = ToRegister(instr->result());
-  // TODO(joransiu): Use non-memory version.
-  __ stdy(value_reg, MemOperand(sp, -kDoubleSize));
+  __ lgdr(result_reg, value_reg);
   if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
-    __ LoadlW(result_reg,
-              MemOperand(sp, -kDoubleSize + Register::kExponentOffset));
+    __ srlg(result_reg, result_reg, Operand(32));
   } else {
-    __ LoadlW(result_reg,
-              MemOperand(sp, -kDoubleSize + Register::kMantissaOffset));
+    __ llgfr(result_reg, result_reg);
   }
 }
 
@@ -5217,7 +5214,6 @@
   Register hi_reg = ToRegister(instr->hi());
   Register lo_reg = ToRegister(instr->lo());
   DoubleRegister result_reg = ToDoubleRegister(instr->result());
-  // TODO(joransiu): Construct with ldgr
   Register scratch = scratch0();
 
   // Combine hi_reg:lo_reg into a single 64-bit register.
diff --git a/src/s390/assembler-s390.cc b/src/s390/assembler-s390.cc
index e4d63a8..35ba431 100644
--- a/src/s390/assembler-s390.cc
+++ b/src/s390/assembler-s390.cc
@@ -364,7 +364,7 @@
   if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
     int16_t imm16 = target_pos - pos;
     instr &= (~0xffff);
-    CHECK(is_int16(imm16));
+    DCHECK(is_int16(imm16));
     instr_at_put<FourByteInstr>(pos, instr | (imm16 >> 1));
     return;
   } else if (BRCL == opcode || LARL == opcode || BRASL == opcode) {
@@ -374,7 +374,7 @@
     instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1));
     return;
   } else if (LLILF == opcode) {
-    CHECK(target_pos == kEndOfChain || target_pos >= 0);
+    DCHECK(target_pos == kEndOfChain || target_pos >= 0);
     // Emitted label constant, not part of a branch.
     // Make label relative to Code* of generated Code object.
     int32_t imm32 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
@@ -2538,6 +2538,7 @@
 
 // Store Register (64)
 void Assembler::stg(Register src, const MemOperand& dst) {
+  DCHECK(!(dst.rb().code() == 15 && dst.offset() < 0));
   rxy_form(STG, src, dst.rx(), dst.rb(), dst.offset());
 }
 
@@ -2735,6 +2736,7 @@
 
 // Store Double (64)
 void Assembler::stdy(DoubleRegister r1, const MemOperand& opnd) {
+  DCHECK(!(opnd.rb().code() == 15 && opnd.offset() < 0));
   rxy_form(STDY, r1, opnd.rx(), opnd.rb(), opnd.offset());
 }
 
@@ -2745,6 +2747,7 @@
 
 // Store Float (32)
 void Assembler::stey(DoubleRegister r1, const MemOperand& opnd) {
+  DCHECK(!(opnd.rb().code() == 15 && opnd.offset() < 0));
   rxy_form(STEY, r1, opnd.rx(), opnd.rb(), opnd.offset());
 }
 
diff --git a/src/s390/code-stubs-s390.cc b/src/s390/code-stubs-s390.cc
index 10ab249..aab8f0d 100644
--- a/src/s390/code-stubs-s390.cc
+++ b/src/s390/code-stubs-s390.cc
@@ -4260,10 +4260,9 @@
   // zLinux ABI requires caller's frame to have sufficient space for callee
   // preserved regsiter save area.
   __ LoadImmP(r0, Operand::Zero());
-  __ StoreP(r0, MemOperand(sp, -kCalleeRegisterSaveAreaSize -
-                                   kNumRequiredStackFrameSlots * kPointerSize));
   __ lay(sp, MemOperand(sp, -kCalleeRegisterSaveAreaSize -
                                 kNumRequiredStackFrameSlots * kPointerSize));
+  __ StoreP(r0, MemOperand(sp));
 #if defined(USE_SIMULATOR)
   // Under the simulator we need to indirect the entry hook through a
   // trampoline function at a known address.
diff --git a/src/s390/macro-assembler-s390.cc b/src/s390/macro-assembler-s390.cc
index 8465fd7..e6abf68 100644
--- a/src/s390/macro-assembler-s390.cc
+++ b/src/s390/macro-assembler-s390.cc
@@ -1929,7 +1929,7 @@
   // observing object alignment.
   DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
 
-  ShiftLeft(scratch1, length, Operand(1));  // Length in bytes, not chars.
+  ShiftLeftP(scratch1, length, Operand(1));  // Length in bytes, not chars.
   AddP(scratch1, Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize));
 
   AndP(scratch1, Operand(~kObjectAlignmentMask));
@@ -4889,6 +4889,15 @@
 }
 
 // Load 32-bits and sign extend if necessary.
+void MacroAssembler::LoadW(Register dst, Register src) {
+#if V8_TARGET_ARCH_S390X
+  lgfr(dst, src);
+#else
+  if (!dst.is(src)) lr(dst, src);
+#endif
+}
+
+// Load 32-bits and sign extend if necessary.
 void MacroAssembler::LoadW(Register dst, const MemOperand& mem,
                            Register scratch) {
   int offset = mem.offset();
@@ -4914,6 +4923,15 @@
   }
 }
 
+// Load 32-bits and zero extend if necessary.
+void MacroAssembler::LoadlW(Register dst, Register src) {
+#if V8_TARGET_ARCH_S390X
+  llgfr(dst, src);
+#else
+  if (!dst.is(src)) lr(dst, src);
+#endif
+}
+
 // Variable length depending on whether offset fits into immediate field
 // MemOperand of RX or RXY format
 void MacroAssembler::LoadlW(Register dst, const MemOperand& mem,
diff --git a/src/s390/macro-assembler-s390.h b/src/s390/macro-assembler-s390.h
index eb1c167..d8d543e 100644
--- a/src/s390/macro-assembler-s390.h
+++ b/src/s390/macro-assembler-s390.h
@@ -333,7 +333,9 @@
   void Load(Register dst, const MemOperand& opnd);
   void Load(Register dst, const Operand& opnd);
   void LoadW(Register dst, const MemOperand& opnd, Register scratch = no_reg);
+  void LoadW(Register dst, Register src);
   void LoadlW(Register dst, const MemOperand& opnd, Register scratch = no_reg);
+  void LoadlW(Register dst, Register src);
   void LoadB(Register dst, const MemOperand& opnd);
   void LoadlB(Register dst, const MemOperand& opnd);