Commit c0c8c756 authored by ahaas's avatar ahaas Committed by Commit bot

[turbofan] Pass type information of arguments to EmitPrepareArguments.

On ia32 the code which pushes parameters on the stack depends on the
types of the parameters which are to be pushed. I provide this type
information now by not only passing parameter nodes to
EmitPrepareArguments, but also the index in the call descriptor which
belongs to the parameter nodes.

This type information will also be necessary if we want to use the
PokePair instruction on arm64 again.

R=bradnelson@chromium.org, bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1534593004

Cr-Commit-Position: refs/heads/master@{#32982}
parent bf8c5160
......@@ -1158,9 +1158,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
ArmOperandGenerator g(this);
// Prepare for C function call.
......@@ -1171,18 +1171,19 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
PushParameter input = (*arguments)[n];
if (input.node()) {
int slot = static_cast<int>(n);
Emit(kArmPoke | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(input));
g.UseRegister(input.node()));
}
}
} else {
// Push any stack arguments.
for (Node* input : base::Reversed(*arguments)) {
for (PushParameter input : base::Reversed(*arguments)) {
// Skip any alignment holes in pushed nodes.
if (input == nullptr) continue;
Emit(kArmPush, g.NoOutput(), g.UseRegister(input));
if (input.node() == nullptr) continue;
Emit(kArmPush, g.NoOutput(), g.UseRegister(input.node()));
}
}
}
......
......@@ -1574,9 +1574,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
Arm64OperandGenerator g(this);
// Push the arguments to the stack.
......@@ -1602,7 +1602,7 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Move arguments to the stack.
int slot = aligned_push_count - 1;
while (slot >= 0) {
Emit(kArm64Poke, g.NoOutput(), g.UseRegister((*arguments)[slot]),
Emit(kArm64Poke, g.NoOutput(), g.UseRegister((*arguments)[slot].node()),
g.TempImmediate(slot));
slot--;
// TODO(ahaas): Poke arguments in pairs if two subsequent arguments have the
......
......@@ -1000,6 +1000,40 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
break;
}
case kIA32PushFloat32:
if (instr->InputAt(0)->IsDoubleRegister()) {
__ sub(esp, Immediate(kDoubleSize));
__ movss(Operand(esp, 0), i.InputDoubleRegister(0));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else if (HasImmediateInput(instr, 0)) {
__ Move(kScratchDoubleReg, i.InputDouble(0));
__ sub(esp, Immediate(kDoubleSize));
__ movss(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else {
__ movsd(kScratchDoubleReg, i.InputOperand(0));
__ sub(esp, Immediate(kDoubleSize));
__ movss(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
}
break;
case kIA32PushFloat64:
if (instr->InputAt(0)->IsDoubleRegister()) {
__ sub(esp, Immediate(kDoubleSize));
__ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else if (HasImmediateInput(instr, 0)) {
__ Move(kScratchDoubleReg, i.InputDouble(0));
__ sub(esp, Immediate(kDoubleSize));
__ movsd(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else {
__ movsd(kScratchDoubleReg, i.InputOperand(0));
__ sub(esp, Immediate(kDoubleSize));
__ movsd(Operand(esp, 0), kScratchDoubleReg);
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
}
break;
case kIA32Push:
if (instr->InputAt(0)->IsDoubleRegister()) {
__ sub(esp, Immediate(kDoubleSize));
......
......@@ -96,6 +96,8 @@ namespace compiler {
V(IA32BitcastIF) \
V(IA32Lea) \
V(IA32Push) \
V(IA32PushFloat32) \
V(IA32PushFloat64) \
V(IA32Poke) \
V(IA32StackCheck)
......
......@@ -108,6 +108,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
return kIsLoadOperation;
case kIA32Push:
case kIA32PushFloat32:
case kIA32PushFloat64:
case kIA32Poke:
return kHasSideEffect;
......
......@@ -896,9 +896,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
IA32OperandGenerator g(this);
// Prepare for C function call.
......@@ -911,29 +911,34 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
PushParameter input = (*arguments)[n];
if (input.node()) {
int const slot = static_cast<int>(n);
InstructionOperand value = g.CanBeImmediate(node)
? g.UseImmediate(input)
: g.UseRegister(input);
? g.UseImmediate(input.node())
: g.UseRegister(input.node());
Emit(kIA32Poke | MiscField::encode(slot), g.NoOutput(), value);
}
}
} else {
// Push any stack arguments.
for (Node* input : base::Reversed(*arguments)) {
for (PushParameter input : base::Reversed(*arguments)) {
// Skip any alignment holes in pushed nodes.
if (input == nullptr) continue;
// TODO(titzer): IA32Push cannot handle stack->stack double moves
// because there is no way to encode fixed double slots.
if (input.node() == nullptr) continue;
InstructionOperand value =
g.CanBeImmediate(input)
? g.UseImmediate(input)
g.CanBeImmediate(input.node())
? g.UseImmediate(input.node())
: IsSupported(ATOM) ||
sequence()->IsFloat(GetVirtualRegister(input))
? g.UseRegister(input)
: g.Use(input);
Emit(kIA32Push, g.NoOutput(), value);
sequence()->IsFloat(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);
}
}
}
}
......
......@@ -397,7 +397,7 @@ struct CallBuffer {
NodeVector output_nodes;
InstructionOperandVector outputs;
InstructionOperandVector instruction_args;
NodeVector pushed_nodes;
ZoneVector<PushParameter> pushed_nodes;
size_t input_count() const { return descriptor->InputCount(); }
......@@ -539,10 +539,10 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
buffer->pushed_nodes.resize(stack_index + 1, NULL);
buffer->pushed_nodes.resize(stack_index + 1);
}
DCHECK(!buffer->pushed_nodes[stack_index]);
buffer->pushed_nodes[stack_index] = *iter;
PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
buffer->pushed_nodes[stack_index] = parameter;
pushed_count++;
} else {
buffer->instruction_args.push_back(op);
......
......@@ -28,6 +28,20 @@ struct SwitchInfo;
typedef ZoneVector<InstructionOperand> InstructionOperandVector;
// This struct connects nodes of parameters which are going to be pushed on the
// call stack with their parameter index in the call descriptor of the callee.
class PushParameter {
public:
PushParameter() : node_(nullptr), type_(MachineType::None()) {}
PushParameter(Node* node, MachineType type) : node_(node), type_(type) {}
Node* node() const { return node_; }
MachineType type() const { return type_; }
private:
Node* node_;
MachineType type_;
};
// Instruction selection generates an InstructionSequence for a given Schedule.
class InstructionSelector final {
......@@ -233,7 +247,7 @@ class InstructionSelector final {
void VisitReturn(Node* ret);
void VisitThrow(Node* value);
void EmitPrepareArguments(NodeVector* arguments,
void EmitPrepareArguments(ZoneVector<compiler::PushParameter>* arguments,
const CallDescriptor* descriptor, Node* node);
// ===========================================================================
......
......@@ -805,9 +805,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
MipsOperandGenerator g(this);
// Prepare for C function call.
......@@ -818,8 +818,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
int slot = kCArgSlotCount;
for (Node* input : (*arguments)) {
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input),
for (PushParameter input : (*arguments)) {
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot << kPointerSizeLog2));
++slot;
}
......@@ -831,8 +831,9 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
g.TempImmediate(push_count << kPointerSizeLog2));
}
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input),
PushParameter input = (*arguments)[n];
if (input.node()) {
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(n << kPointerSizeLog2));
}
}
......
......@@ -1241,9 +1241,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
Mips64OperandGenerator g(this);
// Prepare for C function call.
......@@ -1254,8 +1254,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
int slot = kCArgSlotCount;
for (Node* input : (*arguments)) {
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
for (PushParameter input : (*arguments)) {
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot << kPointerSizeLog2));
++slot;
}
......@@ -1266,8 +1266,9 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
g.TempImmediate(push_count << kPointerSizeLog2));
}
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
PushParameter input = (*arguments)[n];
if (input.node()) {
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(static_cast<int>(n << kPointerSizeLog2)));
}
}
......
......@@ -1611,9 +1611,9 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
PPCOperandGenerator g(this);
// Prepare for C function call.
......@@ -1624,8 +1624,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
int slot = kStackFrameExtraParamSlot;
for (Node* node : (*arguments)) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(node),
for (PushParameter input : (*arguments)) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot));
++slot;
}
......@@ -1633,15 +1633,15 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Push any stack arguments.
int num_slots = static_cast<int>(descriptor->StackParameterCount());
int slot = 0;
for (Node* input : (*arguments)) {
for (PushParameter input : (*arguments)) {
if (slot == 0) {
DCHECK(input);
Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input),
DCHECK(input.node());
Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(num_slots));
} else {
// Skip any alignment holes in pushed nodes.
if (input) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
if (input.node()) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot));
}
}
......
......@@ -1233,9 +1233,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
X64OperandGenerator g(this);
// Prepare for C function call.
......@@ -1246,26 +1246,27 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
PushParameter input = (*arguments)[n];
if (input.node()) {
int slot = static_cast<int>(n);
InstructionOperand value = g.CanBeImmediate(input)
? g.UseImmediate(input)
: g.UseRegister(input);
InstructionOperand value = g.CanBeImmediate(input.node())
? g.UseImmediate(input.node())
: g.UseRegister(input.node());
Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value);
}
}
} else {
// Push any stack arguments.
for (Node* input : base::Reversed(*arguments)) {
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)
? g.UseImmediate(input)
g.CanBeImmediate(input.node())
? g.UseImmediate(input.node())
: IsSupported(ATOM) ||
sequence()->IsFloat(GetVirtualRegister(input))
? g.UseRegister(input)
: g.Use(input);
sequence()->IsFloat(GetVirtualRegister(input.node()))
? g.UseRegister(input.node())
: g.Use(input.node());
Emit(kX64Push, g.NoOutput(), value);
}
}
......
......@@ -903,9 +903,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
}
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
const CallDescriptor* descriptor,
Node* node) {
void InstructionSelector::EmitPrepareArguments(
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
Node* node) {
X87OperandGenerator g(this);
// Prepare for C function call.
......@@ -918,26 +918,27 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
// Poke any stack arguments.
for (size_t n = 0; n < arguments->size(); ++n) {
if (Node* input = (*arguments)[n]) {
PushParameter input = (*arguments)[n];
if (input.node()) {
int const slot = static_cast<int>(n);
InstructionOperand value = g.CanBeImmediate(input)
? g.UseImmediate(input)
: g.UseRegister(input);
InstructionOperand value = g.CanBeImmediate(input.node())
? g.UseImmediate(input.node())
: g.UseRegister(input.node());
Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value);
}
}
} else {
// Push any stack arguments.
for (Node* input : base::Reversed(*arguments)) {
for (PushParameter input : base::Reversed(*arguments)) {
// TODO(titzer): handle pushing double parameters.
if (input == nullptr) continue;
if (input.node() == nullptr) continue;
InstructionOperand value =
g.CanBeImmediate(input)
? g.UseImmediate(input)
g.CanBeImmediate(input.node())
? g.UseImmediate(input.node())
: IsSupported(ATOM) ||
sequence()->IsFloat(GetVirtualRegister(input))
? g.UseRegister(input)
: g.Use(input);
sequence()->IsFloat(GetVirtualRegister(input.node()))
? g.UseRegister(input.node())
: g.Use(input.node());
Emit(kX87Push, g.NoOutput(), value);
}
}
......
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