X87: [turbofan] Add basic support for calling to (a subset of) C functions.
port a58ba8d801
(r29279).
original commit message:
This introduces some initial building blocks for calling out to
C/C++ functions directly from TurboFan generated code objects.
BUG=
Review URL: https://codereview.chromium.org/1214903007
Cr-Commit-Position: refs/heads/master@{#29408}
This commit is contained in:
parent
68020ce546
commit
4ed8444e73
@ -385,6 +385,22 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
|
||||
break;
|
||||
}
|
||||
case kArchPrepareCallCFunction: {
|
||||
int const num_parameters = MiscField::decode(instr->opcode());
|
||||
__ PrepareCallCFunction(num_parameters, i.TempRegister(0));
|
||||
break;
|
||||
}
|
||||
case kArchCallCFunction: {
|
||||
int const num_parameters = MiscField::decode(instr->opcode());
|
||||
if (HasImmediateInput(instr, 0)) {
|
||||
ExternalReference ref = i.InputExternalReference(0);
|
||||
__ CallCFunction(ref, num_parameters);
|
||||
} else {
|
||||
Register func = i.InputRegister(0);
|
||||
__ CallCFunction(func, num_parameters);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kArchJmp:
|
||||
AssembleArchJump(i.InputRpo(0));
|
||||
break;
|
||||
@ -1100,6 +1116,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ push(i.InputOperand(0));
|
||||
}
|
||||
break;
|
||||
case kX87Poke: {
|
||||
int const slot = MiscField::decode(instr->opcode());
|
||||
if (HasImmediateInput(instr, 0)) {
|
||||
__ mov(Operand(esp, slot * kPointerSize), i.InputImmediate(0));
|
||||
} else {
|
||||
__ mov(Operand(esp, slot * kPointerSize), i.InputRegister(0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kX87PushFloat32:
|
||||
__ lea(esp, Operand(esp, -kFloatSize));
|
||||
if (instr->InputAt(0)->IsDoubleStackSlot()) {
|
||||
|
@ -77,6 +77,7 @@ namespace compiler {
|
||||
V(X87Push) \
|
||||
V(X87PushFloat64) \
|
||||
V(X87PushFloat32) \
|
||||
V(X87Poke) \
|
||||
V(X87StoreWriteBarrier) \
|
||||
V(X87StackCheck)
|
||||
|
||||
|
@ -814,14 +814,33 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
|
||||
// Compute InstructionOperands for inputs and outputs.
|
||||
InitializeCallBuffer(node, &buffer, true, true);
|
||||
|
||||
// Push any stack arguments.
|
||||
for (Node* node : base::Reversed(buffer.pushed_nodes)) {
|
||||
// TODO(titzer): handle pushing double parameters.
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(node)
|
||||
? g.UseImmediate(node)
|
||||
: IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node);
|
||||
Emit(kX87Push, g.NoOutput(), value);
|
||||
// Prepare for C function call.
|
||||
if (descriptor->IsCFunctionCall()) {
|
||||
InstructionOperand temps[] = {g.TempRegister()};
|
||||
size_t const temp_count = arraysize(temps);
|
||||
Emit(kArchPrepareCallCFunction |
|
||||
MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
|
||||
0, nullptr, 0, nullptr, temp_count, temps);
|
||||
|
||||
// Poke any stack arguments.
|
||||
for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) {
|
||||
if (Node* node = buffer.pushed_nodes[n]) {
|
||||
int const slot = static_cast<int>(n);
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node);
|
||||
Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
for (Node* node : base::Reversed(buffer.pushed_nodes)) {
|
||||
// TODO(titzer): handle pushing double parameters.
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(node)
|
||||
? g.UseImmediate(node)
|
||||
: IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node);
|
||||
Emit(kX87Push, g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass label of exception handler block.
|
||||
@ -839,18 +858,21 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
|
||||
// Select the appropriate opcode based on the call type.
|
||||
InstructionCode opcode;
|
||||
switch (descriptor->kind()) {
|
||||
case CallDescriptor::kCallCodeObject: {
|
||||
opcode = kArchCallCodeObject;
|
||||
case CallDescriptor::kCallAddress:
|
||||
opcode =
|
||||
kArchCallCFunction |
|
||||
MiscField::encode(static_cast<int>(descriptor->CParameterCount()));
|
||||
break;
|
||||
case CallDescriptor::kCallCodeObject:
|
||||
opcode = kArchCallCodeObject | MiscField::encode(flags);
|
||||
break;
|
||||
}
|
||||
case CallDescriptor::kCallJSFunction:
|
||||
opcode = kArchCallJSFunction;
|
||||
opcode = kArchCallJSFunction | MiscField::encode(flags);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
opcode |= MiscField::encode(flags);
|
||||
|
||||
// Emit the call instruction.
|
||||
size_t const output_count = buffer.outputs.size();
|
||||
|
@ -24,6 +24,7 @@ struct X87LinkageHelperTraits {
|
||||
}
|
||||
static Register CRegisterParameter(int i) { return no_reg; }
|
||||
static int CRegisterParametersLength() { return 0; }
|
||||
static int CStackBackingStoreLength() { return 0; }
|
||||
};
|
||||
|
||||
typedef LinkageHelper<X87LinkageHelperTraits> LH;
|
||||
|
Loading…
Reference in New Issue
Block a user