Commit e5699fda authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[compiler][backend][ia32] Merge opcodes into a single IA32Push

- Reworks the code structure to break out 3 major cases:
  Immediate, MemoryOperand, and LocationOperand.
- InstructionSelector passes an additional immediate operand,
  the push size in bytes, so we can generate correct code
  for the Immediate case.

Bug: v8:9198

Change-Id: I86cd41826150aa84b158fdbb1d3e8f3e93755119
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2673273
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72553}
parent 6b1c27fa
......@@ -1038,11 +1038,13 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
}
void TurboAssembler::AllocateStackSpace(int bytes) {
DCHECK_GE(bytes, 0);
while (bytes > kStackPageSize) {
sub(esp, Immediate(kStackPageSize));
mov(Operand(esp, 0), Immediate(0));
bytes -= kStackPageSize;
}
if (bytes == 0) return;
sub(esp, Immediate(bytes));
}
#endif
......
......@@ -96,7 +96,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void AllocateStackSpace(int bytes);
#else
void AllocateStackSpace(Register bytes) { sub(esp, bytes); }
void AllocateStackSpace(int bytes) { sub(esp, Immediate(bytes)); }
void AllocateStackSpace(int bytes) {
DCHECK_GE(bytes, 0);
if (bytes == 0) return;
sub(esp, Immediate(bytes));
}
#endif
// Print a message to stdout and abort execution.
......
......@@ -1782,82 +1782,55 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
case kIA32PushFloat32: {
int stack_decrement = i.InputInt32(0);
if (instr->InputAt(1)->IsFPRegister()) {
__ AllocateStackSpace(stack_decrement);
__ Movss(Operand(esp, 0), i.InputDoubleRegister(1));
} else if (HasImmediateInput(instr, 1)) {
__ Move(kScratchDoubleReg, i.InputFloat32(1));
__ AllocateStackSpace(stack_decrement);
__ Movss(Operand(esp, 0), kScratchDoubleReg);
} else {
__ Movss(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
__ Movss(Operand(esp, 0), kScratchDoubleReg);
}
int slots = stack_decrement / kSystemPointerSize;
frame_access_state()->IncreaseSPDelta(slots);
break;
}
case kIA32PushFloat64: {
int stack_decrement = i.InputInt32(0);
if (instr->InputAt(1)->IsFPRegister()) {
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 0), i.InputDoubleRegister(1));
} else if (HasImmediateInput(instr, 1)) {
__ Move(kScratchDoubleReg, i.InputDouble(1));
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 0), kScratchDoubleReg);
} else {
__ Movsd(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 0), kScratchDoubleReg);
}
int slots = stack_decrement / kSystemPointerSize;
frame_access_state()->IncreaseSPDelta(slots);
break;
}
case kIA32PushSimd128: {
int stack_decrement = i.InputInt32(0);
if (instr->InputAt(1)->IsFPRegister()) {
__ AllocateStackSpace(stack_decrement);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(Operand(esp, 0), i.InputSimd128Register(1));
} else {
__ Movups(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
// TODO(bbudge) Use Movaps when slots are aligned.
__ Movups(Operand(esp, 0), kScratchDoubleReg);
}
int slots = stack_decrement / kSystemPointerSize;
frame_access_state()->IncreaseSPDelta(slots);
break;
}
case kIA32Push: {
// TODO(bbudge) Merge the push opcodes into a single one, as on x64.
int stack_decrement = i.InputInt32(0);
if (instr->InputAt(1)->IsFPRegister()) {
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 0), i.InputDoubleRegister(1));
int slots = stack_decrement / kSystemPointerSize;
// Whenever codegen uses push, we need to check if stack_decrement
// contains any extra padding and adjust the stack before the push.
if (HasImmediateInput(instr, 1)) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
__ push(i.InputImmediate(1));
} else if (HasAddressingMode(instr)) {
// Only single slot pushes from memory are supported.
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
size_t index = 1;
Operand operand = i.MemoryOperand(&index);
__ push(operand);
} else {
// Slot-sized arguments are never padded but there may be a gap if
// the slot allocator reclaimed other padding slots. Adjust the stack
// here to skip any gap.
if (stack_decrement > kSystemPointerSize) {
InstructionOperand* input = instr->InputAt(1);
if (input->IsRegister()) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
__ push(i.InputRegister(1));
} else if (input->IsFloatRegister()) {
DCHECK_GE(stack_decrement, kFloatSize);
__ AllocateStackSpace(stack_decrement);
__ Movss(Operand(esp, 0), i.InputDoubleRegister(1));
} else if (input->IsDoubleRegister()) {
DCHECK_GE(stack_decrement, kDoubleSize);
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 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(esp, 0), i.InputSimd128Register(1));
} else if (input->IsStackSlot() || input->IsFloatStackSlot()) {
__ AllocateStackSpace(stack_decrement - kSystemPointerSize);
}
if (HasAddressingMode(instr)) {
size_t index = 1;
Operand operand = i.MemoryOperand(&index);
__ push(operand);
} else if (HasImmediateInput(instr, 1)) {
__ push(i.InputImmediate(1));
} else {
__ push(i.InputOperand(1));
} else if (input->IsDoubleStackSlot()) {
DCHECK_GE(stack_decrement, kDoubleSize);
__ Movsd(kScratchDoubleReg, i.InputOperand(1));
__ AllocateStackSpace(stack_decrement);
__ Movsd(Operand(esp, 0), kScratchDoubleReg);
} 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(esp, 0), kScratchDoubleReg);
}
}
int slots = stack_decrement / kSystemPointerSize;
frame_access_state()->IncreaseSPDelta(slots);
break;
}
......
......@@ -114,9 +114,6 @@ namespace compiler {
V(IA32BitcastIF) \
V(IA32Lea) \
V(IA32Push) \
V(IA32PushFloat32) \
V(IA32PushFloat64) \
V(IA32PushSimd128) \
V(IA32Poke) \
V(IA32Peek) \
V(IA32F64x2Splat) \
......
......@@ -425,9 +425,6 @@ int InstructionScheduler::GetTargetInstructionFlags(
return kIsLoadOperation;
case kIA32Push:
case kIA32PushFloat32:
case kIA32PushFloat64:
case kIA32PushSimd128:
case kIA32Poke:
case kIA32MFence:
case kIA32LFence:
......
......@@ -1401,7 +1401,15 @@ void InstructionSelector::EmitPrepareArguments(
if (input.node == nullptr) continue;
InstructionOperand decrement = g.UseImmediate(stack_decrement);
stack_decrement = 0;
if (g.CanBeMemoryOperand(kIA32Push, node, input.node, effect_level)) {
if (g.CanBeImmediate(input.node)) {
Emit(kIA32Push, g.NoOutput(), decrement, g.UseImmediate(input.node));
} else if (IsSupported(ATOM) ||
sequence()->IsFP(GetVirtualRegister(input.node))) {
// TODO(bbudge): IA32Push cannot handle stack->stack double moves
// because there is no way to encode fixed double slots.
Emit(kIA32Push, g.NoOutput(), decrement, g.UseRegister(input.node));
} else if (g.CanBeMemoryOperand(kIA32Push, node, input.node,
effect_level)) {
InstructionOperand outputs[1];
InstructionOperand inputs[5];
size_t input_count = 0;
......@@ -1411,22 +1419,7 @@ void InstructionSelector::EmitPrepareArguments(
InstructionCode opcode = kIA32Push | AddressingModeField::encode(mode);
Emit(opcode, 0, outputs, input_count, inputs);
} else {
InstructionOperand value =
g.CanBeImmediate(input.node)
? g.UseImmediate(input.node)
: IsSupported(ATOM) ||
sequence()->IsFP(GetVirtualRegister(input.node))
? g.UseRegister(input.node)
: g.Use(input.node);
if (input.location.GetType() == MachineType::Float32()) {
Emit(kIA32PushFloat32, g.NoOutput(), decrement, value);
} else if (input.location.GetType() == MachineType::Float64()) {
Emit(kIA32PushFloat64, g.NoOutput(), decrement, value);
} else if (input.location.GetType() == MachineType::Simd128()) {
Emit(kIA32PushSimd128, g.NoOutput(), decrement, value);
} else {
Emit(kIA32Push, g.NoOutput(), decrement, value);
}
Emit(kIA32Push, g.NoOutput(), decrement, g.UseAny(input.node));
}
}
}
......
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