Commit 95d6ec82 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[turbofan] Enable complex memory operands for push instructions on ia32/6x4

Change-Id: Id10be318965d7ec81af8fce8ec230557d3bf1369
Reviewed-on: https://chromium-review.googlesource.com/442126Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Daniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43191}
parent 310f9213
...@@ -1862,7 +1862,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1862,7 +1862,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} }
break; break;
case kIA32Push: case kIA32Push:
if (instr->InputAt(0)->IsFPRegister()) { if (AddressingModeField::decode(instr->opcode()) != kMode_None) {
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
__ push(operand);
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
} else if (instr->InputAt(0)->IsFPRegister()) {
__ sub(esp, Immediate(kFloatSize)); __ sub(esp, Immediate(kFloatSize));
__ movsd(Operand(esp, 0), i.InputDoubleRegister(0)); __ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize); frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
......
...@@ -1089,22 +1089,35 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -1089,22 +1089,35 @@ void InstructionSelector::EmitPrepareArguments(
} }
} else { } else {
// Push any stack arguments. // Push any stack arguments.
int effect_level = GetEffectLevel(node);
for (PushParameter input : base::Reversed(*arguments)) { for (PushParameter input : base::Reversed(*arguments)) {
// Skip any alignment holes in pushed nodes. // Skip any alignment holes in pushed nodes.
Node* input_node = input.node();
if (input.node() == nullptr) continue; if (input.node() == nullptr) continue;
InstructionOperand value = if (g.CanBeMemoryOperand(kIA32Push, node, input_node, effect_level)) {
g.CanBeImmediate(input.node()) InstructionOperand outputs[1];
? g.UseImmediate(input.node()) InstructionOperand inputs[4];
: IsSupported(ATOM) || size_t input_count = 0;
sequence()->IsFP(GetVirtualRegister(input.node())) InstructionCode opcode = kIA32Push;
? g.UseRegister(input.node()) AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
: g.Use(input.node()); input_node, inputs, &input_count);
if (input.type() == MachineType::Float32()) { opcode |= AddressingModeField::encode(mode);
Emit(kIA32PushFloat32, g.NoOutput(), value); Emit(opcode, 0, outputs, input_count, inputs);
} else if (input.type() == MachineType::Float64()) {
Emit(kIA32PushFloat64, g.NoOutput(), value);
} else { } else {
Emit(kIA32Push, g.NoOutput(), value); 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.type() == MachineType::Float32()) {
Emit(kIA32PushFloat32, g.NoOutput(), value);
} else if (input.type() == MachineType::Float64()) {
Emit(kIA32PushFloat64, g.NoOutput(), value);
} else {
Emit(kIA32Push, g.NoOutput(), value);
}
} }
} }
} }
......
...@@ -847,6 +847,7 @@ void InstructionSelector::VisitBlock(BasicBlock* block) { ...@@ -847,6 +847,7 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
int effect_level = 0; int effect_level = 0;
for (Node* const node : *block) { for (Node* const node : *block) {
SetEffectLevel(node, effect_level);
if (node->opcode() == IrOpcode::kStore || if (node->opcode() == IrOpcode::kStore ||
node->opcode() == IrOpcode::kUnalignedStore || node->opcode() == IrOpcode::kUnalignedStore ||
node->opcode() == IrOpcode::kCheckedStore || node->opcode() == IrOpcode::kCheckedStore ||
...@@ -855,7 +856,6 @@ void InstructionSelector::VisitBlock(BasicBlock* block) { ...@@ -855,7 +856,6 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
node->opcode() == IrOpcode::kProtectedStore) { node->opcode() == IrOpcode::kProtectedStore) {
++effect_level; ++effect_level;
} }
SetEffectLevel(node, effect_level);
} }
// We visit the control first, then the nodes in the block, so the block's // We visit the control first, then the nodes in the block, so the block's
......
...@@ -2097,30 +2097,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -2097,30 +2097,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ incl(i.OutputRegister()); __ incl(i.OutputRegister());
break; break;
case kX64Push: case kX64Push:
if (HasImmediateInput(instr, 0)) { if (AddressingModeField::decode(instr->opcode()) != kMode_None) {
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
__ pushq(operand);
frame_access_state()->IncreaseSPDelta(1);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
} else if (HasImmediateInput(instr, 0)) {
__ pushq(i.InputImmediate(0)); __ pushq(i.InputImmediate(0));
frame_access_state()->IncreaseSPDelta(1); frame_access_state()->IncreaseSPDelta(1);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize); kPointerSize);
} else if (instr->InputAt(0)->IsRegister()) {
__ pushq(i.InputRegister(0));
frame_access_state()->IncreaseSPDelta(1);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
} else if (instr->InputAt(0)->IsFPRegister()) {
// TODO(titzer): use another machine instruction?
__ subq(rsp, Immediate(kDoubleSize));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kDoubleSize);
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
} else { } else {
if (instr->InputAt(0)->IsRegister()) { __ pushq(i.InputOperand(0));
__ pushq(i.InputRegister(0)); frame_access_state()->IncreaseSPDelta(1);
frame_access_state()->IncreaseSPDelta(1); unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), kPointerSize);
kPointerSize);
} else if (instr->InputAt(0)->IsFPRegister()) {
// TODO(titzer): use another machine instruction?
__ subq(rsp, Immediate(kDoubleSize));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kDoubleSize);
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
} else {
__ pushq(i.InputOperand(0));
frame_access_state()->IncreaseSPDelta(1);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
}
} }
break; break;
case kX64Poke: { case kX64Poke: {
......
...@@ -58,6 +58,7 @@ class X64OperandGenerator final : public OperandGenerator { ...@@ -58,6 +58,7 @@ class X64OperandGenerator final : public OperandGenerator {
MachineRepresentation rep = MachineRepresentation rep =
LoadRepresentationOf(input->op()).representation(); LoadRepresentationOf(input->op()).representation();
switch (opcode) { switch (opcode) {
case kX64Push:
case kX64Cmp: case kX64Cmp:
case kX64Test: case kX64Test:
return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep); return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep);
...@@ -1504,17 +1505,29 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -1504,17 +1505,29 @@ void InstructionSelector::EmitPrepareArguments(
} }
} else { } else {
// Push any stack arguments. // Push any stack arguments.
int effect_level = GetEffectLevel(node);
for (PushParameter input : base::Reversed(*arguments)) { for (PushParameter input : base::Reversed(*arguments)) {
// TODO(titzer): X64Push cannot handle stack->stack double moves Node* input_node = input.node();
// because there is no way to encode fixed double slots. if (g.CanBeImmediate(input_node)) {
InstructionOperand value = Emit(kX64Push, g.NoOutput(), g.UseImmediate(input_node));
g.CanBeImmediate(input.node()) } else if (IsSupported(ATOM) ||
? g.UseImmediate(input.node()) sequence()->IsFP(GetVirtualRegister(input_node))) {
: IsSupported(ATOM) || // TODO(titzer): X64Push cannot handle stack->stack double moves
sequence()->IsFP(GetVirtualRegister(input.node())) // because there is no way to encode fixed double slots.
? g.UseRegister(input.node()) Emit(kX64Push, g.NoOutput(), g.UseRegister(input_node));
: g.Use(input.node()); } else if (g.CanBeMemoryOperand(kX64Push, node, input_node,
Emit(kX64Push, g.NoOutput(), value); effect_level)) {
InstructionOperand outputs[1];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionCode opcode = kX64Push;
AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
input_node, inputs, &input_count);
opcode |= AddressingModeField::encode(mode);
Emit(opcode, 0, outputs, input_count, inputs);
} else {
Emit(kX64Push, g.NoOutput(), g.Use(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