[turbofan] Add the StackSlot operator to turbofan.
The StackSlot operator allows to allocate a spill slot on the stack. We are going to use this operator to pass floats through pointers to c functions, which we need for floating point rounding in the case where the architecture does not provide rounding instructions. R=titzer@chromium.org, v8-arm-ports@googlegroups.com, v8-ppc-ports@googlegroups.com, v8-mips-ports@googlegroups.com Review URL: https://codereview.chromium.org/1645653002 Cr-Commit-Position: refs/heads/master@{#33600}
This commit is contained in:
parent
3251a03e81
commit
7a69343778
@ -535,6 +535,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
Register base;
|
||||
if (offset.from_stack_pointer()) {
|
||||
base = sp;
|
||||
} else {
|
||||
base = fp;
|
||||
}
|
||||
__ add(i.OutputRegister(0), base, Operand(offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kArmAdd:
|
||||
__ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
|
||||
i.OutputSBit());
|
||||
|
@ -646,6 +646,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ Bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
Register base;
|
||||
if (offset.from_stack_pointer()) {
|
||||
base = __ StackPointer();
|
||||
} else {
|
||||
base = fp;
|
||||
}
|
||||
__ Add(i.OutputRegister(0), base, Operand(offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kArm64Float32RoundDown:
|
||||
__ Frintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
||||
break;
|
||||
|
@ -499,6 +499,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
Register base;
|
||||
if (offset.from_stack_pointer()) {
|
||||
base = esp;
|
||||
} else {
|
||||
base = ebp;
|
||||
}
|
||||
__ lea(i.OutputRegister(), Operand(base, offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kIA32Add:
|
||||
if (HasImmediateInput(instr, 1)) {
|
||||
__ add(i.InputOperand(0), i.InputImmediate(1));
|
||||
|
@ -72,7 +72,8 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny };
|
||||
V(CheckedStoreWord32) \
|
||||
V(CheckedStoreWord64) \
|
||||
V(CheckedStoreFloat32) \
|
||||
V(CheckedStoreFloat64)
|
||||
V(CheckedStoreFloat64) \
|
||||
V(ArchStackSlot)
|
||||
|
||||
#define ARCH_OPCODE_LIST(V) \
|
||||
COMMON_ARCH_OPCODE_LIST(V) \
|
||||
|
@ -175,6 +175,7 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
|
||||
case kArchStackPointer:
|
||||
case kArchFramePointer:
|
||||
case kArchTruncateDoubleToI:
|
||||
case kArchStackSlot:
|
||||
return kNoOpcodeFlags;
|
||||
|
||||
case kArchPrepareCallCFunction:
|
||||
|
@ -21,7 +21,7 @@ namespace compiler {
|
||||
InstructionSelector::InstructionSelector(
|
||||
Zone* zone, size_t node_count, Linkage* linkage,
|
||||
InstructionSequence* sequence, Schedule* schedule,
|
||||
SourcePositionTable* source_positions,
|
||||
SourcePositionTable* source_positions, Frame* frame,
|
||||
SourcePositionMode source_position_mode, Features features)
|
||||
: zone_(zone),
|
||||
linkage_(linkage),
|
||||
@ -36,7 +36,8 @@ InstructionSelector::InstructionSelector(
|
||||
used_(node_count, false, zone),
|
||||
virtual_registers_(node_count,
|
||||
InstructionOperand::kInvalidVirtualRegister, zone),
|
||||
scheduler_(nullptr) {
|
||||
scheduler_(nullptr),
|
||||
frame_(frame) {
|
||||
instructions_.reserve(node_count);
|
||||
}
|
||||
|
||||
@ -1066,6 +1067,8 @@ void InstructionSelector::VisitNode(Node* node) {
|
||||
return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
|
||||
case IrOpcode::kFloat64InsertHighWord32:
|
||||
return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
|
||||
case IrOpcode::kStackSlot:
|
||||
return VisitStackSlot(node);
|
||||
case IrOpcode::kLoadStackPointer:
|
||||
return VisitLoadStackPointer(node);
|
||||
case IrOpcode::kLoadFramePointer:
|
||||
@ -1133,6 +1136,14 @@ void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
|
||||
Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitStackSlot(Node* node) {
|
||||
int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op()));
|
||||
int slot = frame_->AllocateSpillSlot(size);
|
||||
OperandGenerator g(this);
|
||||
|
||||
Emit(kArchStackSlot, g.DefineAsRegister(node),
|
||||
sequence()->AddImmediate(Constant(slot)), 0, nullptr);
|
||||
}
|
||||
|
||||
// 32 bit targets do not implement the following instructions.
|
||||
#if V8_TARGET_ARCH_32_BIT
|
||||
|
@ -52,7 +52,7 @@ class InstructionSelector final {
|
||||
InstructionSelector(
|
||||
Zone* zone, size_t node_count, Linkage* linkage,
|
||||
InstructionSequence* sequence, Schedule* schedule,
|
||||
SourcePositionTable* source_positions,
|
||||
SourcePositionTable* source_positions, Frame* frame,
|
||||
SourcePositionMode source_position_mode = kCallSourcePositions,
|
||||
Features features = SupportedFeatures());
|
||||
|
||||
@ -271,6 +271,7 @@ class InstructionSelector final {
|
||||
BoolVector used_;
|
||||
IntVector virtual_registers_;
|
||||
InstructionScheduler* scheduler_;
|
||||
Frame* frame_;
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
|
@ -91,6 +91,10 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
|
||||
return OpParameter<CheckedStoreRepresentation>(op);
|
||||
}
|
||||
|
||||
MachineRepresentation StackSlotRepresentationOf(Operator const* op) {
|
||||
DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
|
||||
return OpParameter<MachineRepresentation>(op);
|
||||
}
|
||||
|
||||
#define PURE_OP_LIST(V) \
|
||||
V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
|
||||
@ -281,6 +285,18 @@ struct MachineOperatorGlobalCache {
|
||||
MACHINE_TYPE_LIST(LOAD)
|
||||
#undef LOAD
|
||||
|
||||
#define STACKSLOT(Type) \
|
||||
struct StackSlot##Type##Operator final \
|
||||
: public Operator1<MachineRepresentation> { \
|
||||
StackSlot##Type##Operator() \
|
||||
: Operator1<MachineRepresentation>( \
|
||||
IrOpcode::kStackSlot, Operator::kNoThrow, "StackSlot", 0, 0, 0, \
|
||||
1, 0, 0, MachineType::Type().representation()) {} \
|
||||
}; \
|
||||
StackSlot##Type##Operator kStackSlot##Type;
|
||||
MACHINE_TYPE_LIST(STACKSLOT)
|
||||
#undef STACKSLOT
|
||||
|
||||
#define STORE(Type) \
|
||||
struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
|
||||
explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
|
||||
@ -381,6 +397,16 @@ const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep) {
|
||||
#define STACKSLOT(Type) \
|
||||
if (rep == MachineType::Type().representation()) { \
|
||||
return &cache_.kStackSlot##Type; \
|
||||
}
|
||||
MACHINE_TYPE_LIST(STACKSLOT)
|
||||
#undef STACKSLOT
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
|
||||
switch (store_rep.representation()) {
|
||||
|
@ -102,6 +102,7 @@ typedef MachineRepresentation CheckedStoreRepresentation;
|
||||
|
||||
CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
|
||||
|
||||
MachineRepresentation StackSlotRepresentationOf(Operator const* op);
|
||||
|
||||
// Interface for building machine-level operators. These operators are
|
||||
// machine-level but machine-independent and thus define a language suitable
|
||||
@ -305,6 +306,8 @@ class MachineOperatorBuilder final : public ZoneObject {
|
||||
// store [base + index], value
|
||||
const Operator* Store(StoreRepresentation rep);
|
||||
|
||||
const Operator* StackSlot(MachineRepresentation rep);
|
||||
|
||||
// Access to the machine stack.
|
||||
const Operator* LoadStackPointer();
|
||||
const Operator* LoadFramePointer();
|
||||
|
@ -625,6 +625,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
__ Addu(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
|
||||
Operand(offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kMipsAdd:
|
||||
__ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
||||
break;
|
||||
|
@ -635,6 +635,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
__ Daddu(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
|
||||
Operand(offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kMips64Add:
|
||||
__ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
||||
break;
|
||||
|
@ -227,6 +227,7 @@
|
||||
MACHINE_COMPARE_BINOP_LIST(V) \
|
||||
V(Load) \
|
||||
V(Store) \
|
||||
V(StackSlot) \
|
||||
V(Word32And) \
|
||||
V(Word32Or) \
|
||||
V(Word32Xor) \
|
||||
|
@ -276,11 +276,8 @@ class PipelineData {
|
||||
info()->isolate(), instruction_zone(), instruction_blocks);
|
||||
}
|
||||
|
||||
void InitializeRegisterAllocationData(const RegisterConfiguration* config,
|
||||
CallDescriptor* descriptor,
|
||||
const char* debug_name) {
|
||||
void InitializeFrameData(CallDescriptor* descriptor) {
|
||||
DCHECK(frame_ == nullptr);
|
||||
DCHECK(register_allocation_data_ == nullptr);
|
||||
int fixed_frame_size = 0;
|
||||
if (descriptor != nullptr) {
|
||||
fixed_frame_size = (descriptor->IsCFunctionCall())
|
||||
@ -289,6 +286,12 @@ class PipelineData {
|
||||
: StandardFrameConstants::kFixedSlotCount;
|
||||
}
|
||||
frame_ = new (instruction_zone()) Frame(fixed_frame_size, descriptor);
|
||||
}
|
||||
|
||||
void InitializeRegisterAllocationData(const RegisterConfiguration* config,
|
||||
CallDescriptor* descriptor,
|
||||
const char* debug_name) {
|
||||
DCHECK(register_allocation_data_ == nullptr);
|
||||
register_allocation_data_ = new (register_allocation_zone())
|
||||
RegisterAllocationData(config, register_allocation_zone(), frame(),
|
||||
sequence(), debug_name);
|
||||
@ -816,7 +819,7 @@ struct InstructionSelectionPhase {
|
||||
void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
|
||||
InstructionSelector selector(
|
||||
temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
|
||||
data->schedule(), data->source_positions(),
|
||||
data->schedule(), data->source_positions(), data->frame(),
|
||||
data->info()->is_source_positions_enabled()
|
||||
? InstructionSelector::kAllSourcePositions
|
||||
: InstructionSelector::kCallSourcePositions);
|
||||
@ -1282,6 +1285,7 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
|
||||
PipelineData data(&zone_pool, &info, sequence);
|
||||
Pipeline pipeline(&info);
|
||||
pipeline.data_ = &data;
|
||||
pipeline.data_->InitializeFrameData(nullptr);
|
||||
pipeline.AllocateRegisters(config, nullptr, run_verifier);
|
||||
return !data.compilation_failed();
|
||||
}
|
||||
@ -1304,6 +1308,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
|
||||
|
||||
data->InitializeInstructionSequence();
|
||||
|
||||
data->InitializeFrameData(call_descriptor);
|
||||
// Select and schedule instructions covering the scheduled graph.
|
||||
Linkage linkage(call_descriptor);
|
||||
Run<InstructionSelectionPhase>(&linkage);
|
||||
@ -1325,6 +1330,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
|
||||
BeginPhaseKind("register allocation");
|
||||
|
||||
bool run_verifier = FLAG_turbo_verify_allocation;
|
||||
|
||||
// Allocate registers.
|
||||
AllocateRegisters(
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
|
||||
|
@ -823,6 +823,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
__ addi(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
|
||||
Operand(offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kPPC_And:
|
||||
if (HasRegisterInput(instr, 1)) {
|
||||
__ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
|
||||
|
@ -79,6 +79,9 @@ class RawMachineAssembler {
|
||||
Node* Int32Constant(int32_t value) {
|
||||
return AddNode(common()->Int32Constant(value));
|
||||
}
|
||||
Node* StackSlot(MachineRepresentation rep) {
|
||||
return AddNode(machine()->StackSlot(rep));
|
||||
}
|
||||
Node* Int64Constant(int64_t value) {
|
||||
return AddNode(common()->Int64Constant(value));
|
||||
}
|
||||
|
@ -1962,6 +1962,7 @@ Type* Typer::Visitor::TypeObjectIsSmi(Node* node) {
|
||||
|
||||
Type* Typer::Visitor::TypeLoad(Node* node) { return Type::Any(); }
|
||||
|
||||
Type* Typer::Visitor::TypeStackSlot(Node* node) { return Type::Any(); }
|
||||
|
||||
Type* Typer::Visitor::TypeStore(Node* node) {
|
||||
UNREACHABLE();
|
||||
|
@ -831,6 +831,7 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
// -----------------------
|
||||
case IrOpcode::kLoad:
|
||||
case IrOpcode::kStore:
|
||||
case IrOpcode::kStackSlot:
|
||||
case IrOpcode::kWord32And:
|
||||
case IrOpcode::kWord32Or:
|
||||
case IrOpcode::kWord32Xor:
|
||||
|
@ -740,6 +740,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
Register base;
|
||||
if (offset.from_stack_pointer()) {
|
||||
base = rsp;
|
||||
} else {
|
||||
base = rbp;
|
||||
}
|
||||
__ leaq(i.OutputRegister(), Operand(base, offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kX64Add32:
|
||||
ASSEMBLE_BINOP(addl);
|
||||
break;
|
||||
|
@ -587,6 +587,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ bind(ool->exit());
|
||||
break;
|
||||
}
|
||||
case kArchStackSlot: {
|
||||
FrameOffset offset =
|
||||
frame_access_state()->GetFrameOffset(i.InputInt32(0));
|
||||
Register base;
|
||||
if (offset.from_stack_pointer()) {
|
||||
base = esp;
|
||||
} else {
|
||||
base = ebp;
|
||||
}
|
||||
__ lea(i.OutputRegister(), Operand(base, offset.offset()));
|
||||
break;
|
||||
}
|
||||
case kX87Add:
|
||||
if (HasImmediateInput(instr, 1)) {
|
||||
__ add(i.InputOperand(0), i.InputImmediate(1));
|
||||
|
@ -96,7 +96,6 @@ class BufferedRawMachineAssemblerTester
|
||||
return parameter_nodes_[index];
|
||||
}
|
||||
|
||||
|
||||
// The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
|
||||
// to store the graph's return value in memory. The memory address for the
|
||||
// Store node is provided as a parameter. By storing the return value in
|
||||
@ -245,7 +244,6 @@ class BufferedRawMachineAssemblerTester<void>
|
||||
: Load(p3, RawMachineAssembler::Parameter(3));
|
||||
}
|
||||
|
||||
|
||||
// The BufferedRawMachineAssemblerTester does not pass parameters directly
|
||||
// to the constructed IR graph. Instead it passes a pointer to the parameter
|
||||
// to the IR graph, and adds Load nodes to the IR graph to load the
|
||||
|
@ -72,7 +72,6 @@ TEST(RunWord32Ctz) {
|
||||
CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
|
||||
}
|
||||
|
||||
|
||||
TEST(RunWord32Clz) {
|
||||
BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
|
||||
m.Return(m.Word32Clz(m.Parameter(0)));
|
||||
|
@ -1157,6 +1157,86 @@ TEST(MixedParams_1) { MixedParamTest(1); }
|
||||
TEST(MixedParams_2) { MixedParamTest(2); }
|
||||
TEST(MixedParams_3) { MixedParamTest(3); }
|
||||
|
||||
template <typename T>
|
||||
void TestStackSlot(MachineType slot_type, T expected) {
|
||||
// Test: Generate with a function f which reserves a stack slot, call an inner
|
||||
// function g from f which writes into the stack slot of f.
|
||||
|
||||
if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->num_double_registers() < 2)
|
||||
return;
|
||||
|
||||
Isolate* isolate = CcTest::InitIsolateOnce();
|
||||
|
||||
// Lots of code to generate the build descriptor for the inner function.
|
||||
int parray_gp[] = {
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableGeneralCode(0),
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableGeneralCode(1)};
|
||||
int rarray_gp[] = {
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableGeneralCode(0)};
|
||||
int parray_fp[] = {
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableDoubleCode(0),
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableDoubleCode(1)};
|
||||
int rarray_fp[] = {
|
||||
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
|
||||
->GetAllocatableDoubleCode(0)};
|
||||
Allocator palloc(parray_gp, 2, parray_fp, 2);
|
||||
Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
|
||||
RegisterConfig config(palloc, ralloc);
|
||||
|
||||
Zone zone;
|
||||
HandleScope scope(isolate);
|
||||
MachineSignature::Builder builder(&zone, 1, 12);
|
||||
builder.AddReturn(MachineType::Int32());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
builder.AddParam(MachineType::Int32());
|
||||
}
|
||||
builder.AddParam(slot_type);
|
||||
builder.AddParam(MachineType::Pointer());
|
||||
MachineSignature* sig = builder.Build();
|
||||
CallDescriptor* desc = config.Create(&zone, sig);
|
||||
|
||||
// Create inner function g. g has lots of parameters so that they are passed
|
||||
// over the stack.
|
||||
Handle<Code> inner;
|
||||
Graph graph(&zone);
|
||||
RawMachineAssembler g(isolate, &graph, desc);
|
||||
|
||||
g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10),
|
||||
WriteBarrierKind::kNoWriteBarrier);
|
||||
g.Return(g.Parameter(9));
|
||||
inner = CompileGraph("Compute", desc, &graph, g.Export());
|
||||
|
||||
// Create function f with a stack slot which calls the inner function g.
|
||||
BufferedRawMachineAssemblerTester<T> f(slot_type);
|
||||
Node* target = f.HeapConstant(inner);
|
||||
Node* stack_slot = f.StackSlot(slot_type.representation());
|
||||
Node* args[12];
|
||||
for (int i = 0; i < 10; i++) {
|
||||
args[i] = f.Int32Constant(i);
|
||||
}
|
||||
args[10] = f.Parameter(0);
|
||||
args[11] = stack_slot;
|
||||
|
||||
f.CallN(desc, target, args);
|
||||
f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));
|
||||
|
||||
CHECK_EQ(expected, f.Call(expected));
|
||||
}
|
||||
|
||||
TEST(RunStackSlotInt32) { TestStackSlot(MachineType::Int32(), 0x12345678); }
|
||||
#if !V8_TARGET_ARCH_32_BIT
|
||||
TEST(RunStackSlotInt64) {
|
||||
TestStackSlot(MachineType::Int64(), 0x123456789abcdef0);
|
||||
}
|
||||
#endif
|
||||
TEST(RunStackSlotFloat32) { TestStackSlot(MachineType::Float32(), 1234.125f); }
|
||||
TEST(RunStackSlotFloat64) { TestStackSlot(MachineType::Float64(), 3456.375); }
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -40,7 +40,7 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
|
||||
instruction_blocks);
|
||||
SourcePositionTable source_position_table(graph());
|
||||
InstructionSelector selector(test_->zone(), node_count, &linkage, &sequence,
|
||||
schedule, &source_position_table,
|
||||
schedule, &source_position_table, nullptr,
|
||||
source_position_mode, features);
|
||||
selector.SelectInstructions();
|
||||
if (FLAG_trace_turbo) {
|
||||
|
Loading…
Reference in New Issue
Block a user