[compiler][backend][x64] Fix gap checking for X64Push codegen

- Removes DCHECKs that will be incorrect when SIMD operands
  are intermixed.
- Reworks the code structure to break out 3 major cases:
  Immediate, MemoryOperand, and LocationOperand.

Bug: v8:9198

Change-Id: I1be426bc450dda0fd670a2483aae9afd2c96ce17
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2673271
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72551}
This commit is contained in:
Bill Budge 2021-02-04 17:03:42 -08:00 committed by Commit Bot
parent 65893d84e5
commit c394be4f7e
3 changed files with 40 additions and 38 deletions

View File

@ -3018,11 +3018,13 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
}
void TurboAssembler::AllocateStackSpace(int bytes) {
DCHECK_GE(bytes, 0);
while (bytes > kStackPageSize) {
subq(rsp, Immediate(kStackPageSize));
movb(Operand(rsp, 0), Immediate(0));
bytes -= kStackPageSize;
}
if (bytes == 0) return;
subq(rsp, Immediate(bytes));
}
#endif

View File

@ -657,7 +657,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void AllocateStackSpace(int bytes);
#else
void AllocateStackSpace(Register bytes) { subq(rsp, bytes); }
void AllocateStackSpace(int bytes) { subq(rsp, Immediate(bytes)); }
void AllocateStackSpace(int bytes) {
DCHECK_GE(bytes, 0);
if (bytes == 0) return;
subq(rsp, Immediate(bytes));
}
#endif
// Removes current frame and its arguments from the stack preserving the

View File

@ -2264,48 +2264,44 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kX64Push: {
int stack_decrement = i.InputInt32(0);
if (HasAddressingMode(instr)) {
// 1 slot values are never padded.
DCHECK_EQ(stack_decrement, kSystemPointerSize);
int slots = stack_decrement / kSystemPointerSize;
// Whenever codegen uses pushq, we need to check if stack_decrement
// contains any extra padding and adjust the stack before the pushq.
if (HasImmediateInput(instr, 1)) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
__ pushq(i.InputImmediate(1));
} else if (HasAddressingMode(instr)) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
size_t index = 1;
Operand operand = i.MemoryOperand(&index);
__ pushq(operand);
} else if (HasImmediateInput(instr, 1)) {
// 1 slot values are never padded.
DCHECK_EQ(stack_decrement, kSystemPointerSize);
__ pushq(i.InputImmediate(1));
} else if (HasRegisterInput(instr, 1)) {
// 1 slot values are never padded.
DCHECK_EQ(stack_decrement, kSystemPointerSize);
__ pushq(i.InputRegister(1));
} else if (instr->InputAt(1)->IsFloatRegister() ||
instr->InputAt(1)->IsDoubleRegister()) {
// 1 slot values are never padded.
DCHECK_EQ(stack_decrement, kSystemPointerSize);
__ AllocateStackSpace(kSystemPointerSize);
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
} else if (instr->InputAt(1)->IsSimd128Register()) {
// 2 slot values have up to 1 slot of padding.
DCHECK_GE(stack_decrement, kSimd128Size);
__ AllocateStackSpace(stack_decrement);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(Operand(rsp, 0), i.InputSimd128Register(1));
} else if (instr->InputAt(1)->IsStackSlot() ||
instr->InputAt(1)->IsFloatStackSlot() ||
instr->InputAt(1)->IsDoubleStackSlot()) {
// 1 slot values are never padded.
DCHECK_EQ(stack_decrement, kSystemPointerSize);
__ pushq(i.InputOperand(1));
} else {
DCHECK(instr->InputAt(1)->IsSimd128StackSlot());
// 2 slot values have up to 1 slot of padding.
DCHECK_GE(stack_decrement, kSimd128Size);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
__ Movups(Operand(rsp, 0), kScratchDoubleReg);
InstructionOperand* input = instr->InputAt(1);
if (input->IsRegister()) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
__ pushq(i.InputRegister(1));
} else if (input->IsFloatRegister() || input->IsDoubleRegister()) {
DCHECK_GE(stack_decrement, kSystemPointerSize);
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
} else if (input->IsSimd128Register()) {
DCHECK_GE(stack_decrement, kSimd128Size);
__ AllocateStackSpace(stack_decrement);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(Operand(rsp, 0), i.InputSimd128Register(1));
} else if (input->IsStackSlot() || input->IsFloatStackSlot() ||
input->IsDoubleStackSlot()) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
__ pushq(i.InputOperand(1));
} else {
DCHECK(input->IsSimd128StackSlot());
DCHECK_GE(stack_decrement, kSimd128Size);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
__ Movups(Operand(rsp, 0), kScratchDoubleReg);
}
}
int slots = stack_decrement / kSystemPointerSize;
frame_access_state()->IncreaseSPDelta(slots);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
stack_decrement);