[turbofan] Enable complex memory operands for push instructions on ia32/6x4
Change-Id: Id10be318965d7ec81af8fce8ec230557d3bf1369 Reviewed-on: https://chromium-review.googlesource.com/442126 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Daniel Clifford <danno@chromium.org> Cr-Commit-Position: refs/heads/master@{#43191}
This commit is contained in:
parent
310f921377
commit
95d6ec827f
@ -1862,7 +1862,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
break;
|
||||
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));
|
||||
__ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
|
||||
frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
|
||||
|
@ -1089,22 +1089,35 @@ void InstructionSelector::EmitPrepareArguments(
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
int effect_level = GetEffectLevel(node);
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// Skip any alignment holes in pushed nodes.
|
||||
Node* input_node = input.node();
|
||||
if (input.node() == nullptr) continue;
|
||||
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);
|
||||
if (g.CanBeMemoryOperand(kIA32Push, node, input_node, effect_level)) {
|
||||
InstructionOperand outputs[1];
|
||||
InstructionOperand inputs[4];
|
||||
size_t input_count = 0;
|
||||
InstructionCode opcode = kIA32Push;
|
||||
AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
|
||||
input_node, inputs, &input_count);
|
||||
opcode |= AddressingModeField::encode(mode);
|
||||
Emit(opcode, 0, outputs, input_count, inputs);
|
||||
} 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) {
|
||||
|
||||
int effect_level = 0;
|
||||
for (Node* const node : *block) {
|
||||
SetEffectLevel(node, effect_level);
|
||||
if (node->opcode() == IrOpcode::kStore ||
|
||||
node->opcode() == IrOpcode::kUnalignedStore ||
|
||||
node->opcode() == IrOpcode::kCheckedStore ||
|
||||
@ -855,7 +856,6 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
|
||||
node->opcode() == IrOpcode::kProtectedStore) {
|
||||
++effect_level;
|
||||
}
|
||||
SetEffectLevel(node, effect_level);
|
||||
}
|
||||
|
||||
// We visit the control first, then the nodes in the block, so the block's
|
||||
|
@ -2097,30 +2097,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ incl(i.OutputRegister());
|
||||
break;
|
||||
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));
|
||||
frame_access_state()->IncreaseSPDelta(1);
|
||||
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
|
||||
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 {
|
||||
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 {
|
||||
__ pushq(i.InputOperand(0));
|
||||
frame_access_state()->IncreaseSPDelta(1);
|
||||
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
|
||||
kPointerSize);
|
||||
}
|
||||
__ pushq(i.InputOperand(0));
|
||||
frame_access_state()->IncreaseSPDelta(1);
|
||||
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
|
||||
kPointerSize);
|
||||
}
|
||||
break;
|
||||
case kX64Poke: {
|
||||
|
@ -58,6 +58,7 @@ class X64OperandGenerator final : public OperandGenerator {
|
||||
MachineRepresentation rep =
|
||||
LoadRepresentationOf(input->op()).representation();
|
||||
switch (opcode) {
|
||||
case kX64Push:
|
||||
case kX64Cmp:
|
||||
case kX64Test:
|
||||
return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep);
|
||||
@ -1504,17 +1505,29 @@ void InstructionSelector::EmitPrepareArguments(
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
int effect_level = GetEffectLevel(node);
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// TODO(titzer): X64Push cannot handle stack->stack double moves
|
||||
// because there is no way to encode fixed double slots.
|
||||
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());
|
||||
Emit(kX64Push, g.NoOutput(), value);
|
||||
Node* input_node = input.node();
|
||||
if (g.CanBeImmediate(input_node)) {
|
||||
Emit(kX64Push, g.NoOutput(), g.UseImmediate(input_node));
|
||||
} else if (IsSupported(ATOM) ||
|
||||
sequence()->IsFP(GetVirtualRegister(input_node))) {
|
||||
// TODO(titzer): X64Push cannot handle stack->stack double moves
|
||||
// because there is no way to encode fixed double slots.
|
||||
Emit(kX64Push, g.NoOutput(), g.UseRegister(input_node));
|
||||
} else if (g.CanBeMemoryOperand(kX64Push, node, input_node,
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user