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