Commit 141bc11e authored by jyan's avatar jyan Committed by Commit bot

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

R=joransiu@ca.ibm.com, mbrandy@us.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review-Url: https://codereview.chromium.org/1936953004
Cr-Commit-Position: refs/heads/master@{#35953}
parent 59b9ff3f
......@@ -1302,8 +1302,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#endif
case kS390_Push:
if (instr->InputAt(0)->IsDoubleRegister()) {
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
__ lay(sp, MemOperand(sp, -kDoubleSize));
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else {
__ Push(i.InputRegister(0));
......@@ -1312,14 +1312,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kS390_PushFrame: {
int num_slots = i.InputInt32(1);
__ lay(sp, MemOperand(sp, -num_slots * kPointerSize));
if (instr->InputAt(0)->IsDoubleRegister()) {
__ StoreDouble(i.InputDoubleRegister(0),
MemOperand(sp, -num_slots * kPointerSize));
MemOperand(sp));
} else {
__ StoreP(i.InputRegister(0),
MemOperand(sp, -num_slots * kPointerSize));
MemOperand(sp));
}
__ lay(sp, MemOperand(sp, -num_slots * kPointerSize));
break;
}
case kS390_StoreToStackSlot: {
......@@ -1494,36 +1494,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ldebr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kS390_DoubleExtractLowWord32:
// TODO(john.yan): this can cause problem when interrupting,
// use freg->greg instruction
__ stdy(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
__ LoadlW(i.OutputRegister(),
MemOperand(sp, -kDoubleSize + Register::kMantissaOffset));
__ lgdr(i.OutputRegister(), i.InputDoubleRegister(0));
__ llgfr(i.OutputRegister(), i.OutputRegister());
break;
case kS390_DoubleExtractHighWord32:
// TODO(john.yan): this can cause problem when interrupting,
// use freg->greg instruction
__ stdy(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
__ LoadlW(i.OutputRegister(),
MemOperand(sp, -kDoubleSize + Register::kExponentOffset));
__ lgdr(i.OutputRegister(), i.InputDoubleRegister(0));
__ srlg(i.OutputRegister(), i.OutputRegister(), Operand(32));
break;
case kS390_DoubleInsertLowWord32:
__ InsertDoubleLow(i.OutputDoubleRegister(), i.InputRegister(1));
__ lgdr(kScratchReg, i.OutputDoubleRegister());
__ lr(kScratchReg, i.InputRegister(1));
__ ldgr(i.OutputDoubleRegister(), kScratchReg);
break;
case kS390_DoubleInsertHighWord32:
__ InsertDoubleHigh(i.OutputDoubleRegister(), i.InputRegister(1));
__ sllg(kScratchReg, i.InputRegister(1), Operand(32));
__ lgdr(r0, i.OutputDoubleRegister());
__ lr(kScratchReg, r0);
__ ldgr(i.OutputDoubleRegister(), kScratchReg);
break;
case kS390_DoubleConstruct:
// TODO(john.yan): this can cause problem when interrupting,
// use greg->freg instruction
#if V8_TARGET_LITTLE_ENDIAN
__ StoreW(i.InputRegister(0), MemOperand(sp, -kDoubleSize / 2));
__ StoreW(i.InputRegister(1), MemOperand(sp, -kDoubleSize));
#else
__ StoreW(i.InputRegister(1), MemOperand(sp, -kDoubleSize / 2));
__ StoreW(i.InputRegister(0), MemOperand(sp, -kDoubleSize));
#endif
__ ldy(i.OutputDoubleRegister(), MemOperand(sp, -kDoubleSize));
__ sllg(kScratchReg, i.InputRegister(0), Operand(32));
__ lr(kScratchReg, i.InputRegister(1));
// Bitwise convert from GPR to FPR
__ ldgr(i.OutputDoubleRegister(), kScratchReg);
break;
case kS390_LoadWordS8:
ASSEMBLE_LOAD_INTEGER(LoadlB);
......
......@@ -5210,14 +5210,11 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
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);
}
}
......@@ -5225,7 +5222,6 @@ void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
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.
......
......@@ -364,7 +364,7 @@ void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
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 @@ void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
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 @@ void Assembler::mvghi(const MemOperand& opnd1, const Operand& i2) {
// 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 @@ void Assembler::std(DoubleRegister r1, const MemOperand& opnd) {
// 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 @@ void Assembler::ste(DoubleRegister r1, const MemOperand& opnd) {
// 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());
}
......
......@@ -4260,10 +4260,9 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
// 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.
......
......@@ -205,26 +205,6 @@ void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
}
}
void MacroAssembler::InsertDoubleLow(DoubleRegister dst, Register src) {
StoreDouble(dst, MemOperand(sp, -kDoubleSize));
#if V8_TARGET_LITTLE_ENDIAN
StoreW(src, MemOperand(sp, -kDoubleSize));
#else
StoreW(src, MemOperand(sp, -kDoubleSize / 2));
#endif
ldy(dst, MemOperand(sp, -kDoubleSize));
}
void MacroAssembler::InsertDoubleHigh(DoubleRegister dst, Register src) {
StoreDouble(dst, MemOperand(sp, -kDoubleSize));
#if V8_TARGET_LITTLE_ENDIAN
StoreW(src, MemOperand(sp, -kDoubleSize / 2));
#else
StoreW(src, MemOperand(sp, -kDoubleSize));
#endif
ldy(dst, MemOperand(sp, -kDoubleSize));
}
void MacroAssembler::MultiPush(RegList regs, Register location) {
int16_t num_to_push = NumberOfBitsSet(regs);
int16_t stack_offset = num_to_push * kPointerSize;
......@@ -1113,9 +1093,8 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
ClearRightImm(sp, sp, Operand(3)); // equivalent to &= -8
}
StoreP(MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize),
Operand::Zero(), r0);
lay(sp, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize));
StoreP(MemOperand(sp), Operand::Zero(), r0);
// Set the exit frame sp value to point just before the return address
// location.
lay(r1, MemOperand(sp, kStackFrameSPSlot * kPointerSize));
......@@ -2330,9 +2309,8 @@ void MacroAssembler::TestDoubleIsMinusZero(DoubleRegister input,
}
void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) {
stdy(input, MemOperand(sp, -kDoubleSize));
LoadlW(scratch, MemOperand(sp, -kDoubleSize + Register::kExponentOffset));
Cmp32(scratch, Operand::Zero());
lgdr(scratch, input);
cgfi(scratch, Operand::Zero());
}
void MacroAssembler::TestHeapNumberSign(Register input, Register scratch) {
......@@ -2377,8 +2355,8 @@ void MacroAssembler::TryInt32Floor(Register result, DoubleRegister double_input,
Label exception;
// Move high word into input_high
StoreDouble(double_input, MemOperand(sp, -kDoubleSize));
lay(sp, MemOperand(sp, -kDoubleSize));
StoreDouble(double_input, MemOperand(sp));
LoadlW(input_high, MemOperand(sp, Register::kExponentOffset));
la(sp, MemOperand(sp, kDoubleSize));
......@@ -2444,8 +2422,8 @@ void MacroAssembler::TruncateDoubleToI(Register result,
// If we fell through then inline version didn't succeed - call stub instead.
push(r14);
// Put input on stack.
StoreDouble(double_input, MemOperand(sp, -kDoubleSize));
lay(sp, MemOperand(sp, -kDoubleSize));
StoreDouble(double_input, MemOperand(sp));
DoubleToIStub stub(isolate(), sp, result, 0, true, true);
CallStub(&stub);
......
......@@ -214,9 +214,6 @@ class MacroAssembler : public Assembler {
void Move(Register dst, Register src, Condition cond = al);
void Move(DoubleRegister dst, DoubleRegister src);
void InsertDoubleLow(DoubleRegister dst, Register src);
void InsertDoubleHigh(DoubleRegister dst, Register src);
void MultiPush(RegList regs, Register location = sp);
void MultiPop(RegList regs, Register location = sp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment