Commit 4116900d authored by dcarney's avatar dcarney Committed by Commit bot

[turbofan] Don't allocate UnallocatedOperands in Zone memory during instruction selection

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26424}
parent 275e088a
...@@ -30,7 +30,7 @@ class Arm64OperandGenerator FINAL : public OperandGenerator { ...@@ -30,7 +30,7 @@ class Arm64OperandGenerator FINAL : public OperandGenerator {
explicit Arm64OperandGenerator(InstructionSelector* selector) explicit Arm64OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {} : OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, ImmediateMode mode) { InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
if (CanBeImmediate(node, mode)) { if (CanBeImmediate(node, mode)) {
return UseImmediate(node); return UseImmediate(node);
} }
...@@ -174,9 +174,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -174,9 +174,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) { FlagsContinuation* cont) {
Arm64OperandGenerator g(selector); Arm64OperandGenerator g(selector);
Matcher m(node); Matcher m(node);
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
InstructionOperand* outputs[2]; InstructionOperand outputs[2];
size_t output_count = 0; size_t output_count = 0;
bool try_ror_operand = true; bool try_ror_operand = true;
...@@ -313,8 +313,8 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -313,8 +313,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. // TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; InstructionOperand temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10), Emit(kArm64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, x10),
g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps), g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps),
temps); temps);
return; return;
...@@ -354,10 +354,10 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -354,10 +354,10 @@ void InstructionSelector::VisitStore(Node* node) {
return; return;
} }
if (g.CanBeImmediate(index, immediate_mode)) { if (g.CanBeImmediate(index, immediate_mode)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
} else { } else {
Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL, Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
} }
} }
...@@ -424,7 +424,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -424,7 +424,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset), Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
g.UseOperand(length, kArithmeticImm), g.UseRegister(value)); g.UseOperand(length, kArithmeticImm), g.UseRegister(value));
} }
...@@ -864,7 +864,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { ...@@ -864,7 +864,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
void InstructionSelector::VisitInt32MulHigh(Node* node) { void InstructionSelector::VisitInt32MulHigh(Node* node) {
// TODO(arm64): Can we do better here? // TODO(arm64): Can we do better here?
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
InstructionOperand* const smull_operand = g.TempRegister(); InstructionOperand const smull_operand = g.TempRegister();
Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1))); g.UseRegister(node->InputAt(1)));
Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
...@@ -874,7 +874,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) { ...@@ -874,7 +874,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) {
void InstructionSelector::VisitUint32MulHigh(Node* node) { void InstructionSelector::VisitUint32MulHigh(Node* node) {
// TODO(arm64): Can we do better here? // TODO(arm64): Can we do better here?
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
InstructionOperand* const smull_operand = g.TempRegister(); InstructionOperand const smull_operand = g.TempRegister();
Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)), Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1))); g.UseRegister(node->InputAt(1)));
Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
...@@ -1107,7 +1107,7 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -1107,7 +1107,7 @@ void InstructionSelector::VisitCall(Node* node) {
if (aligned_push_count > 0) { if (aligned_push_count > 0) {
// TODO(dcarney): it would be better to bump the csp here only // TODO(dcarney): it would be better to bump the csp here only
// and emit paired stores with increment for non c frames. // and emit paired stores with increment for non c frames.
Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); Emit(kArm64Claim | MiscField::encode(aligned_push_count), g.NoOutput());
} }
// Move arguments to the stack. // Move arguments to the stack.
{ {
...@@ -1115,12 +1115,13 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -1115,12 +1115,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Emit the uneven pushes. // Emit the uneven pushes.
if (pushed_count_uneven) { if (pushed_count_uneven) {
Node* input = buffer.pushed_nodes[slot]; Node* input = buffer.pushed_nodes[slot];
Emit(kArm64Poke | MiscField::encode(slot), NULL, g.UseRegister(input)); Emit(kArm64Poke | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(input));
slot--; slot--;
} }
// Now all pushes can be done in pairs. // Now all pushes can be done in pairs.
for (; slot >= 0; slot -= 2) { for (; slot >= 0; slot -= 2) {
Emit(kArm64PokePair | MiscField::encode(slot), NULL, Emit(kArm64PokePair | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(buffer.pushed_nodes[slot]), g.UseRegister(buffer.pushed_nodes[slot]),
g.UseRegister(buffer.pushed_nodes[slot - 1])); g.UseRegister(buffer.pushed_nodes[slot - 1]));
} }
...@@ -1143,7 +1144,7 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -1143,7 +1144,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags()); opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction. // Emit the call instruction.
InstructionOperand** first_output = InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr = Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output, Emit(opcode, buffer.outputs.size(), first_output,
...@@ -1154,12 +1155,13 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -1154,12 +1155,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Shared routine for multiple compare operations. // Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right, InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) { FlagsContinuation* cont) {
Arm64OperandGenerator g(selector); Arm64OperandGenerator g(selector);
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
...@@ -1348,7 +1350,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1348,7 +1350,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// If the mask has only one bit set, we can use tbz/tbnz. // If the mask has only one bit set, we can use tbz/tbnz.
DCHECK((cont.condition() == kEqual) || DCHECK((cont.condition() == kEqual) ||
(cont.condition() == kNotEqual)); (cont.condition() == kNotEqual));
Emit(cont.Encode(kArm64TestAndBranch32), NULL, Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(),
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate( g.TempImmediate(
base::bits::CountTrailingZeros32(m.right().Value())), base::bits::CountTrailingZeros32(m.right().Value())),
...@@ -1366,7 +1368,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1366,7 +1368,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// If the mask has only one bit set, we can use tbz/tbnz. // If the mask has only one bit set, we can use tbz/tbnz.
DCHECK((cont.condition() == kEqual) || DCHECK((cont.condition() == kEqual) ||
(cont.condition() == kNotEqual)); (cont.condition() == kNotEqual));
Emit(cont.Encode(kArm64TestAndBranch), NULL, Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(),
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate( g.TempImmediate(
base::bits::CountTrailingZeros64(m.right().Value())), base::bits::CountTrailingZeros64(m.right().Value())),
...@@ -1383,8 +1385,8 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, ...@@ -1383,8 +1385,8 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
} }
// Branch could not be combined with a compare, compare against 0 and branch. // Branch could not be combined with a compare, compare against 0 and branch.
Emit(cont.Encode(kArm64CompareAndBranch32), NULL, g.UseRegister(value), Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(),
g.Label(cont.true_block()), g.UseRegister(value), g.Label(cont.true_block()),
g.Label(cont.false_block()))->MarkAsControl(); g.Label(cont.false_block()))->MarkAsControl();
} }
......
...@@ -16,7 +16,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { ...@@ -16,7 +16,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
explicit IA32OperandGenerator(InstructionSelector* selector) explicit IA32OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {} : OperandGenerator(selector) {}
InstructionOperand* UseByteRegister(Node* node) { InstructionOperand UseByteRegister(Node* node) {
// TODO(dcarney): relax constraint. // TODO(dcarney): relax constraint.
return UseFixed(node, edx); return UseFixed(node, edx);
} }
...@@ -41,7 +41,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { ...@@ -41,7 +41,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
Node* displacement_node, Node* displacement_node,
InstructionOperand* inputs[], InstructionOperand inputs[],
size_t* input_count) { size_t* input_count) {
AddressingMode mode = kMode_MRI; AddressingMode mode = kMode_MRI;
int32_t displacement = (displacement_node == NULL) int32_t displacement = (displacement_node == NULL)
...@@ -99,7 +99,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { ...@@ -99,7 +99,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
} }
AddressingMode GetEffectiveAddressMemoryOperand(Node* node, AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
InstructionOperand* inputs[], InstructionOperand inputs[],
size_t* input_count) { size_t* input_count) {
BaseWithIndexAndDisplacement32Matcher m(node, true); BaseWithIndexAndDisplacement32Matcher m(node, true);
DCHECK(m.matches()); DCHECK(m.matches());
...@@ -157,9 +157,9 @@ void InstructionSelector::VisitLoad(Node* node) { ...@@ -157,9 +157,9 @@ void InstructionSelector::VisitLoad(Node* node) {
} }
IA32OperandGenerator g(this); IA32OperandGenerator g(this);
InstructionOperand* outputs[1]; InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node); outputs[0] = g.DefineAsRegister(node);
InstructionOperand* inputs[3]; InstructionOperand inputs[3];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
...@@ -181,8 +181,8 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -181,8 +181,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. // TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
temps); temps);
return; return;
...@@ -213,7 +213,7 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -213,7 +213,7 @@ void InstructionSelector::VisitStore(Node* node) {
return; return;
} }
InstructionOperand* val; InstructionOperand val;
if (g.CanBeImmediate(value)) { if (g.CanBeImmediate(value)) {
val = g.UseImmediate(value); val = g.UseImmediate(value);
} else if (rep == kRepWord8 || rep == kRepBit) { } else if (rep == kRepWord8 || rep == kRepBit) {
...@@ -222,13 +222,13 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -222,13 +222,13 @@ void InstructionSelector::VisitStore(Node* node) {
val = g.UseRegister(value); val = g.UseRegister(value);
} }
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode); InstructionCode code = opcode | AddressingModeField::encode(mode);
inputs[input_count++] = val; inputs[input_count++] = val;
Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
} }
...@@ -260,8 +260,8 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { ...@@ -260,8 +260,8 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* offset_operand = g.UseRegister(offset); InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
if (g.CanBeImmediate(buffer)) { if (g.CanBeImmediate(buffer)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), Emit(opcode | AddressingModeField::encode(kMode_MRI),
...@@ -303,20 +303,20 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -303,20 +303,20 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* value_operand = InstructionOperand value_operand =
g.CanBeImmediate(value) g.CanBeImmediate(value)
? g.UseImmediate(value) ? g.UseImmediate(value)
: ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value)
: g.UseRegister(value)); : g.UseRegister(value));
InstructionOperand* offset_operand = g.UseRegister(offset); InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
if (g.CanBeImmediate(buffer)) { if (g.CanBeImmediate(buffer)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
offset_operand, length_operand, value_operand, offset_operand, offset_operand, length_operand, value_operand, offset_operand,
g.UseImmediate(buffer)); g.UseImmediate(buffer));
} else { } else {
Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(),
offset_operand, length_operand, value_operand, g.UseRegister(buffer), offset_operand, length_operand, value_operand, g.UseRegister(buffer),
offset_operand); offset_operand);
} }
...@@ -330,9 +330,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -330,9 +330,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
Node* left = m.left().node(); Node* left = m.left().node();
Node* right = m.right().node(); Node* right = m.right().node();
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
InstructionOperand* outputs[2]; InstructionOperand outputs[2];
size_t output_count = 0; size_t output_count = 0;
// TODO(turbofan): match complex addressing modes. // TODO(turbofan): match complex addressing modes.
...@@ -344,7 +344,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -344,7 +344,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
// mov eax, [ebp-0x10] // mov eax, [ebp-0x10]
// add eax, [ebp-0x10] // add eax, [ebp-0x10]
// jo label // jo label
InstructionOperand* const input = g.UseRegister(left); InstructionOperand const input = g.UseRegister(left);
inputs[input_count++] = input; inputs[input_count++] = input;
inputs[input_count++] = input; inputs[input_count++] = input;
} else if (g.CanBeImmediate(right)) { } else if (g.CanBeImmediate(right)) {
...@@ -440,7 +440,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node, ...@@ -440,7 +440,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node,
void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
IA32OperandGenerator g(selector); IA32OperandGenerator g(selector);
InstructionOperand* temps[] = {g.TempRegister(edx)}; InstructionOperand temps[] = {g.TempRegister(edx)};
selector->Emit(opcode, g.DefineAsFixed(node, eax), selector->Emit(opcode, g.DefineAsFixed(node, eax),
g.UseFixed(node->InputAt(0), eax), g.UseFixed(node->InputAt(0), eax),
g.UseUnique(node->InputAt(1)), arraysize(temps), temps); g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
...@@ -457,7 +457,7 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { ...@@ -457,7 +457,7 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
void EmitLea(InstructionSelector* selector, Node* result, Node* index, void EmitLea(InstructionSelector* selector, Node* result, Node* index,
int scale, Node* base, Node* displacement) { int scale, Node* base, Node* displacement) {
IA32OperandGenerator g(selector); IA32OperandGenerator g(selector);
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs( AddressingMode mode = g.GenerateMemoryOperandInputs(
index, scale, base, displacement, inputs, &input_count); index, scale, base, displacement, inputs, &input_count);
...@@ -465,7 +465,7 @@ void EmitLea(InstructionSelector* selector, Node* result, Node* index, ...@@ -465,7 +465,7 @@ void EmitLea(InstructionSelector* selector, Node* result, Node* index,
DCHECK_NE(0, static_cast<int>(input_count)); DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count); DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1]; InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(result); outputs[0] = g.DefineAsRegister(result);
InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
...@@ -510,7 +510,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { ...@@ -510,7 +510,7 @@ void InstructionSelector::VisitInt32Add(Node* node) {
BaseWithIndexAndDisplacement32Matcher m(node); BaseWithIndexAndDisplacement32Matcher m(node);
if (m.matches() && if (m.matches() &&
(m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) { (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs( AddressingMode mode = g.GenerateMemoryOperandInputs(
m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count); m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
...@@ -518,7 +518,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { ...@@ -518,7 +518,7 @@ void InstructionSelector::VisitInt32Add(Node* node) {
DCHECK_NE(0, static_cast<int>(input_count)); DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count); DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1]; InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node); outputs[0] = g.DefineAsRegister(node);
InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
...@@ -682,7 +682,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) { ...@@ -682,7 +682,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) {
void InstructionSelector::VisitFloat64Mod(Node* node) { void InstructionSelector::VisitFloat64Mod(Node* node) {
IA32OperandGenerator g(this); IA32OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(eax)}; InstructionOperand temps[] = {g.TempRegister(eax)};
Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
temps); temps);
...@@ -738,11 +738,11 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -738,11 +738,11 @@ void InstructionSelector::VisitCall(Node* node) {
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) { ++i) {
// TODO(titzer): handle pushing double parameters. // TODO(titzer): handle pushing double parameters.
InstructionOperand* value = InstructionOperand value =
g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
? g.UseRegister(*i) ? g.UseRegister(*i)
: g.Use(*i); : g.Use(*i);
Emit(kIA32Push, nullptr, value); Emit(kIA32Push, g.NoOutput(), value);
} }
// Select the appropriate opcode based on the call type. // Select the appropriate opcode based on the call type.
...@@ -762,7 +762,7 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -762,7 +762,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags()); opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction. // Emit the call instruction.
InstructionOperand** first_output = InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr = Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output, Emit(opcode, buffer.outputs.size(), first_output,
...@@ -775,11 +775,11 @@ namespace { ...@@ -775,11 +775,11 @@ namespace {
// Shared routine for multiple compare operations. // Shared routine for multiple compare operations.
void VisitCompare(InstructionSelector* selector, InstructionCode opcode, void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right, InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) { FlagsContinuation* cont) {
IA32OperandGenerator g(selector); IA32OperandGenerator g(selector);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(cont->Encode(opcode), NULL, left, right, selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
g.Label(cont->true_block()), g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
......
This diff is collapsed.
This diff is collapsed.
...@@ -23,6 +23,9 @@ class FlagsContinuation; ...@@ -23,6 +23,9 @@ class FlagsContinuation;
class Linkage; class Linkage;
typedef ZoneVector<InstructionOperand> InstructionOperandVector;
// Instruction selection generates an InstructionSequence for a given Schedule. // Instruction selection generates an InstructionSequence for a given Schedule.
class InstructionSelector FINAL { class InstructionSelector FINAL {
public: public:
...@@ -41,36 +44,36 @@ class InstructionSelector FINAL { ...@@ -41,36 +44,36 @@ class InstructionSelector FINAL {
// ============= Architecture-independent code emission methods. ============= // ============= Architecture-independent code emission methods. =============
// =========================================================================== // ===========================================================================
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
size_t temp_count = 0, InstructionOperand* *temps = NULL); size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, size_t temp_count = 0, InstructionOperand a, size_t temp_count = 0,
InstructionOperand* *temps = NULL); InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, InstructionOperand* b, InstructionOperand a, InstructionOperand b,
size_t temp_count = 0, InstructionOperand* *temps = NULL); size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, InstructionOperand* b, InstructionOperand a, InstructionOperand b,
InstructionOperand* c, size_t temp_count = 0, InstructionOperand c, size_t temp_count = 0,
InstructionOperand* *temps = NULL); InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, InstructionOperand* b, InstructionOperand a, InstructionOperand b,
InstructionOperand* c, InstructionOperand* d, InstructionOperand c, InstructionOperand d,
size_t temp_count = 0, InstructionOperand* *temps = NULL); size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, InstructionOperand* b, InstructionOperand a, InstructionOperand b,
InstructionOperand* c, InstructionOperand* d, InstructionOperand c, InstructionOperand d,
InstructionOperand* e, size_t temp_count = 0, InstructionOperand e, size_t temp_count = 0,
InstructionOperand* *temps = NULL); InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output, Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand* a, InstructionOperand* b, InstructionOperand a, InstructionOperand b,
InstructionOperand* c, InstructionOperand* d, InstructionOperand c, InstructionOperand d,
InstructionOperand* e, InstructionOperand* f, InstructionOperand e, InstructionOperand f,
size_t temp_count = 0, InstructionOperand* *temps = NULL); size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, size_t output_count, Instruction* Emit(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count, InstructionOperand* outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count = 0, InstructionOperand* inputs, size_t temp_count = 0,
InstructionOperand* *temps = NULL); InstructionOperand* temps = NULL);
Instruction* Emit(Instruction* instr); Instruction* Emit(Instruction* instr);
// =========================================================================== // ===========================================================================
...@@ -154,7 +157,7 @@ class InstructionSelector FINAL { ...@@ -154,7 +157,7 @@ class InstructionSelector FINAL {
// Inform the register allocation of the representation of the unallocated // Inform the register allocation of the representation of the unallocated
// operand {op}. // operand {op}.
void MarkAsRepresentation(MachineType rep, InstructionOperand* op); void MarkAsRepresentation(MachineType rep, const InstructionOperand& op);
// Initialize the call buffer with the InstructionOperands, nodes, etc, // Initialize the call buffer with the InstructionOperands, nodes, etc,
// corresponding // corresponding
......
...@@ -119,16 +119,6 @@ bool ParallelMove::IsRedundant() const { ...@@ -119,16 +119,6 @@ bool ParallelMove::IsRedundant() const {
} }
static void SetOperand(UnallocatedOperand* loc, InstructionOperand* value) {
if (value->IsUnallocated()) {
loc[0] = *UnallocatedOperand::cast(value);
} else {
InstructionOperand* casted = static_cast<InstructionOperand*>(loc);
casted[0] = *value;
}
}
Instruction::Instruction(InstructionCode opcode) Instruction::Instruction(InstructionCode opcode)
: opcode_(opcode), : opcode_(opcode),
bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
...@@ -138,9 +128,9 @@ Instruction::Instruction(InstructionCode opcode) ...@@ -138,9 +128,9 @@ Instruction::Instruction(InstructionCode opcode)
Instruction::Instruction(InstructionCode opcode, size_t output_count, Instruction::Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count, InstructionOperand* outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count, InstructionOperand* inputs, size_t temp_count,
InstructionOperand** temps) InstructionOperand* temps)
: opcode_(opcode), : opcode_(opcode),
bit_field_(OutputCountField::encode(output_count) | bit_field_(OutputCountField::encode(output_count) |
InputCountField::encode(input_count) | InputCountField::encode(input_count) |
...@@ -149,13 +139,16 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count, ...@@ -149,13 +139,16 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count,
pointer_map_(NULL) { pointer_map_(NULL) {
size_t offset = 0; size_t offset = 0;
for (size_t i = 0; i < output_count; ++i) { for (size_t i = 0; i < output_count; ++i) {
SetOperand(&operands_[offset++], outputs[i]); DCHECK(!outputs[i].IsInvalid());
operands_[offset++] = outputs[i];
} }
for (size_t i = 0; i < input_count; ++i) { for (size_t i = 0; i < input_count; ++i) {
SetOperand(&operands_[offset++], inputs[i]); DCHECK(!inputs[i].IsInvalid());
operands_[offset++] = inputs[i];
} }
for (size_t i = 0; i < temp_count; ++i) { for (size_t i = 0; i < temp_count; ++i) {
SetOperand(&operands_[offset++], temps[i]); DCHECK(!temps[i].IsInvalid());
operands_[offset++] = temps[i];
} }
} }
......
...@@ -35,7 +35,7 @@ const InstructionCode kSourcePositionInstruction = -2; ...@@ -35,7 +35,7 @@ const InstructionCode kSourcePositionInstruction = -2;
V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
class InstructionOperand : public ZoneObject { class InstructionOperand {
public: public:
static const int kInvalidVirtualRegister = -1; static const int kInvalidVirtualRegister = -1;
...@@ -50,6 +50,10 @@ class InstructionOperand : public ZoneObject { ...@@ -50,6 +50,10 @@ class InstructionOperand : public ZoneObject {
DOUBLE_REGISTER DOUBLE_REGISTER
}; };
InstructionOperand() : virtual_register_(kInvalidVirtualRegister) {
ConvertTo(INVALID, 0);
}
InstructionOperand(Kind kind, int index) InstructionOperand(Kind kind, int index)
: virtual_register_(kInvalidVirtualRegister) { : virtual_register_(kInvalidVirtualRegister) {
DCHECK(kind != INVALID); DCHECK(kind != INVALID);
...@@ -62,6 +66,7 @@ class InstructionOperand : public ZoneObject { ...@@ -62,6 +66,7 @@ class InstructionOperand : public ZoneObject {
bool Is##name() const { return kind() == type; } bool Is##name() const { return kind() == type; }
INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID, 0)
#undef INSTRUCTION_OPERAND_PREDICATE #undef INSTRUCTION_OPERAND_PREDICATE
bool Equals(const InstructionOperand* other) const { bool Equals(const InstructionOperand* other) const {
return value_ == other->value_; return value_ == other->value_;
...@@ -79,6 +84,12 @@ class InstructionOperand : public ZoneObject { ...@@ -79,6 +84,12 @@ class InstructionOperand : public ZoneObject {
static void SetUpCaches(); static void SetUpCaches();
static void TearDownCaches(); static void TearDownCaches();
// TODO(dcarney): get rid of these
void* operator new(size_t, void* location) { return location; }
void* operator new(size_t size, Zone* zone) {
return zone->New(static_cast<int>(size));
}
protected: protected:
InstructionOperand(Kind kind, int index, int virtual_register) InstructionOperand(Kind kind, int index, int virtual_register)
: virtual_register_(virtual_register) { : virtual_register_(virtual_register) {
...@@ -91,8 +102,6 @@ class InstructionOperand : public ZoneObject { ...@@ -91,8 +102,6 @@ class InstructionOperand : public ZoneObject {
int32_t virtual_register_; int32_t virtual_register_;
}; };
typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
struct PrintableInstructionOperand { struct PrintableInstructionOperand {
const RegisterConfiguration* register_configuration_; const RegisterConfiguration* register_configuration_;
const InstructionOperand* op_; const InstructionOperand* op_;
...@@ -131,10 +140,6 @@ class UnallocatedOperand : public InstructionOperand { ...@@ -131,10 +140,6 @@ class UnallocatedOperand : public InstructionOperand {
// TODO(dcarney): remove this. // TODO(dcarney): remove this.
static const int kInvalidVirtualRegister = -1; static const int kInvalidVirtualRegister = -1;
// This is only for array initialization.
UnallocatedOperand()
: InstructionOperand(INVALID, 0, kInvalidVirtualRegister) {}
UnallocatedOperand(ExtendedPolicy policy, int virtual_register) UnallocatedOperand(ExtendedPolicy policy, int virtual_register)
: InstructionOperand(UNALLOCATED, 0, virtual_register) { : InstructionOperand(UNALLOCATED, 0, virtual_register) {
value_ |= BasicPolicyField::encode(EXTENDED_POLICY); value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
...@@ -181,6 +186,11 @@ class UnallocatedOperand : public InstructionOperand { ...@@ -181,6 +186,11 @@ class UnallocatedOperand : public InstructionOperand {
return static_cast<UnallocatedOperand*>(op); return static_cast<UnallocatedOperand*>(op);
} }
static UnallocatedOperand cast(const InstructionOperand& op) {
DCHECK(op.IsUnallocated());
return *static_cast<const UnallocatedOperand*>(&op);
}
// The encoding used for UnallocatedOperand operands depends on the policy // The encoding used for UnallocatedOperand operands depends on the policy
// that is // that is
// stored within the operand. The FIXED_SLOT policy uses a compact encoding // stored within the operand. The FIXED_SLOT policy uses a compact encoding
...@@ -341,6 +351,9 @@ std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); ...@@ -341,6 +351,9 @@ std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
class SubKindOperand FINAL : public InstructionOperand { class SubKindOperand FINAL : public InstructionOperand {
public: public:
explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {}
static SubKindOperand* Create(int index, Zone* zone) { static SubKindOperand* Create(int index, Zone* zone) {
DCHECK(index >= 0); DCHECK(index >= 0);
if (index < kNumCachedOperands) return &cache[index]; if (index < kNumCachedOperands) return &cache[index];
...@@ -357,6 +370,11 @@ class SubKindOperand FINAL : public InstructionOperand { ...@@ -357,6 +370,11 @@ class SubKindOperand FINAL : public InstructionOperand {
return reinterpret_cast<const SubKindOperand*>(op); return reinterpret_cast<const SubKindOperand*>(op);
} }
static SubKindOperand cast(const InstructionOperand& op) {
DCHECK(op.kind() == kOperandKind);
return *static_cast<const SubKindOperand*>(&op);
}
static void SetUpCache(); static void SetUpCache();
static void TearDownCache(); static void TearDownCache();
...@@ -364,8 +382,6 @@ class SubKindOperand FINAL : public InstructionOperand { ...@@ -364,8 +382,6 @@ class SubKindOperand FINAL : public InstructionOperand {
static SubKindOperand* cache; static SubKindOperand* cache;
SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches. SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches.
explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {}
}; };
...@@ -492,9 +508,9 @@ class Instruction : public ZoneObject { ...@@ -492,9 +508,9 @@ class Instruction : public ZoneObject {
} }
static Instruction* New(Zone* zone, InstructionCode opcode, static Instruction* New(Zone* zone, InstructionCode opcode,
size_t output_count, InstructionOperand** outputs, size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand** inputs, size_t input_count, InstructionOperand* inputs,
size_t temp_count, InstructionOperand** temps) { size_t temp_count, InstructionOperand* temps) {
DCHECK(opcode >= 0); DCHECK(opcode >= 0);
DCHECK(output_count == 0 || outputs != NULL); DCHECK(output_count == 0 || outputs != NULL);
DCHECK(input_count == 0 || inputs != NULL); DCHECK(input_count == 0 || inputs != NULL);
...@@ -502,8 +518,8 @@ class Instruction : public ZoneObject { ...@@ -502,8 +518,8 @@ class Instruction : public ZoneObject {
size_t total_extra_ops = output_count + input_count + temp_count; size_t total_extra_ops = output_count + input_count + temp_count;
if (total_extra_ops != 0) total_extra_ops--; if (total_extra_ops != 0) total_extra_ops--;
int size = static_cast<int>( int size = static_cast<int>(
RoundUp(sizeof(Instruction), sizeof(UnallocatedOperand)) + RoundUp(sizeof(Instruction), sizeof(InstructionOperand)) +
total_extra_ops * sizeof(UnallocatedOperand)); total_extra_ops * sizeof(InstructionOperand));
return new (zone->New(size)) Instruction( return new (zone->New(size)) Instruction(
opcode, output_count, outputs, input_count, inputs, temp_count, temps); opcode, output_count, outputs, input_count, inputs, temp_count, temps);
} }
...@@ -559,9 +575,9 @@ class Instruction : public ZoneObject { ...@@ -559,9 +575,9 @@ class Instruction : public ZoneObject {
protected: protected:
explicit Instruction(InstructionCode opcode); explicit Instruction(InstructionCode opcode);
Instruction(InstructionCode opcode, size_t output_count, Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count, InstructionOperand* outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count, InstructionOperand* inputs, size_t temp_count,
InstructionOperand** temps); InstructionOperand* temps);
protected: protected:
typedef BitField<size_t, 0, 8> OutputCountField; typedef BitField<size_t, 0, 8> OutputCountField;
...@@ -573,7 +589,7 @@ class Instruction : public ZoneObject { ...@@ -573,7 +589,7 @@ class Instruction : public ZoneObject {
InstructionCode opcode_; InstructionCode opcode_;
uint32_t bit_field_; uint32_t bit_field_;
PointerMap* pointer_map_; PointerMap* pointer_map_;
UnallocatedOperand operands_[1]; InstructionOperand operands_[1];
}; };
......
...@@ -23,7 +23,7 @@ class MipsOperandGenerator FINAL : public OperandGenerator { ...@@ -23,7 +23,7 @@ class MipsOperandGenerator FINAL : public OperandGenerator {
explicit MipsOperandGenerator(InstructionSelector* selector) explicit MipsOperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {} : OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) { if (CanBeImmediate(node, opcode)) {
return UseImmediate(node); return UseImmediate(node);
} }
...@@ -91,9 +91,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -91,9 +91,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont) { InstructionCode opcode, FlagsContinuation* cont) {
MipsOperandGenerator g(selector); MipsOperandGenerator g(selector);
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
InstructionOperand* outputs[2]; InstructionOperand outputs[2];
size_t output_count = 0; size_t output_count = 0;
inputs[input_count++] = g.UseRegister(m.left().node()); inputs[input_count++] = g.UseRegister(m.left().node());
...@@ -162,7 +162,7 @@ void InstructionSelector::VisitLoad(Node* node) { ...@@ -162,7 +162,7 @@ void InstructionSelector::VisitLoad(Node* node) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
} else { } else {
InstructionOperand* addr_reg = g.TempRegister(); InstructionOperand addr_reg = g.TempRegister();
Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base)); g.UseRegister(index), g.UseRegister(base));
// Emit desired load opcode, using temp addr_reg. // Emit desired load opcode, using temp addr_reg.
...@@ -185,8 +185,8 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -185,8 +185,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. // TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMipsStoreWriteBarrier, NULL, g.UseFixed(base, t0), Emit(kMipsStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0),
g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
return; return;
} }
...@@ -217,15 +217,15 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -217,15 +217,15 @@ void InstructionSelector::VisitStore(Node* node) {
} }
if (g.CanBeImmediate(index, opcode)) { if (g.CanBeImmediate(index, opcode)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
} else { } else {
InstructionOperand* addr_reg = g.TempRegister(); InstructionOperand addr_reg = g.TempRegister();
Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base)); g.UseRegister(index), g.UseRegister(base));
// Emit desired store opcode, using temp addr_reg. // Emit desired store opcode, using temp addr_reg.
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
g.TempImmediate(0), g.UseRegister(value)); addr_reg, g.TempImmediate(0), g.UseRegister(value));
} }
} }
...@@ -290,7 +290,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -290,7 +290,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp, Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
...@@ -299,7 +299,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -299,7 +299,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp, Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1))); g.TempImmediate(WhichPowerOf2(value + 1)));
...@@ -466,12 +466,12 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -466,12 +466,12 @@ void InstructionSelector::VisitCall(Node* node) {
// Possibly align stack here for functions. // Possibly align stack here for functions.
int push_count = buffer.pushed_nodes.size(); int push_count = buffer.pushed_nodes.size();
if (push_count > 0) { if (push_count > 0) {
Emit(kMipsStackClaim | MiscField::encode(push_count), NULL); Emit(kMipsStackClaim | MiscField::encode(push_count), g.NoOutput());
} }
int slot = buffer.pushed_nodes.size() - 1; int slot = buffer.pushed_nodes.size() - 1;
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) { ++i) {
Emit(kMipsStoreToStackSlot | MiscField::encode(slot), nullptr, Emit(kMipsStoreToStackSlot | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(*i)); g.UseRegister(*i));
slot--; slot--;
} }
...@@ -493,7 +493,7 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -493,7 +493,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags()); opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction. // Emit the call instruction.
InstructionOperand** first_output = InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr = Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output, Emit(opcode, buffer.outputs.size(), first_output,
...@@ -530,12 +530,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { ...@@ -530,12 +530,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset) ? g.UseImmediate(offset)
: g.UseRegister(offset); : g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length) ? g.UseImmediate(length)
: g.UseRegister(length) : g.UseRegister(length)
: g.UseRegister(length); : g.UseRegister(length);
...@@ -574,18 +574,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -574,18 +574,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset) ? g.UseImmediate(offset)
: g.UseRegister(offset); : g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length) ? g.UseImmediate(length)
: g.UseRegister(length) : g.UseRegister(length)
: g.UseRegister(length); : g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
length_operand, g.UseRegister(value), g.UseRegister(buffer)); offset_operand, length_operand, g.UseRegister(value),
g.UseRegister(buffer));
} }
...@@ -593,12 +594,13 @@ namespace { ...@@ -593,12 +594,13 @@ namespace {
// Shared routine for multiple compare operations. // Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right, InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) { FlagsContinuation* cont) {
MipsOperandGenerator g(selector); MipsOperandGenerator g(selector);
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
...@@ -725,9 +727,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -725,9 +727,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
// Continuation could not be combined with a compare, emit compare against 0. // Continuation could not be combined with a compare, emit compare against 0.
MipsOperandGenerator g(selector); MipsOperandGenerator g(selector);
InstructionCode const opcode = cont->Encode(kMipsCmp); InstructionCode const opcode = cont->Encode(kMipsCmp);
InstructionOperand* const value_operand = g.UseRegister(value); InstructionOperand const value_operand = g.UseRegister(value);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0), selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
g.Label(cont->true_block()), g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
......
...@@ -23,7 +23,7 @@ class Mips64OperandGenerator FINAL : public OperandGenerator { ...@@ -23,7 +23,7 @@ class Mips64OperandGenerator FINAL : public OperandGenerator {
explicit Mips64OperandGenerator(InstructionSelector* selector) explicit Mips64OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {} : OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) { if (CanBeImmediate(node, opcode)) {
return UseImmediate(node); return UseImmediate(node);
} }
...@@ -124,9 +124,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -124,9 +124,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont) { InstructionCode opcode, FlagsContinuation* cont) {
Mips64OperandGenerator g(selector); Mips64OperandGenerator g(selector);
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
InstructionOperand* outputs[2]; InstructionOperand outputs[2];
size_t output_count = 0; size_t output_count = 0;
inputs[input_count++] = g.UseRegister(m.left().node()); inputs[input_count++] = g.UseRegister(m.left().node());
...@@ -198,7 +198,7 @@ void InstructionSelector::VisitLoad(Node* node) { ...@@ -198,7 +198,7 @@ void InstructionSelector::VisitLoad(Node* node) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
} else { } else {
InstructionOperand* addr_reg = g.TempRegister(); InstructionOperand addr_reg = g.TempRegister();
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base)); g.UseRegister(index), g.UseRegister(base));
// Emit desired load opcode, using temp addr_reg. // Emit desired load opcode, using temp addr_reg.
...@@ -221,8 +221,8 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -221,8 +221,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. // TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0), Emit(kMips64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0),
g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
return; return;
} }
...@@ -256,15 +256,15 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -256,15 +256,15 @@ void InstructionSelector::VisitStore(Node* node) {
} }
if (g.CanBeImmediate(index, opcode)) { if (g.CanBeImmediate(index, opcode)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
} else { } else {
InstructionOperand* addr_reg = g.TempRegister(); InstructionOperand addr_reg = g.TempRegister();
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base)); g.UseRegister(index), g.UseRegister(base));
// Emit desired store opcode, using temp addr_reg. // Emit desired store opcode, using temp addr_reg.
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
g.TempImmediate(0), g.UseRegister(value)); addr_reg, g.TempImmediate(0), g.UseRegister(value));
} }
} }
...@@ -375,7 +375,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -375,7 +375,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
...@@ -384,7 +384,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { ...@@ -384,7 +384,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1))); g.TempImmediate(WhichPowerOf2(value + 1)));
...@@ -407,7 +407,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) { ...@@ -407,7 +407,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) {
void InstructionSelector::VisitUint32MulHigh(Node* node) { void InstructionSelector::VisitUint32MulHigh(Node* node) {
Mips64OperandGenerator g(this); Mips64OperandGenerator g(this);
InstructionOperand* const dmul_operand = g.TempRegister(); InstructionOperand const dmul_operand = g.TempRegister();
Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)), Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1))); g.UseRegister(node->InputAt(1)));
Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0), Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0),
...@@ -428,7 +428,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { ...@@ -428,7 +428,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value - 1)) { if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1))); g.TempImmediate(WhichPowerOf2(value - 1)));
...@@ -437,7 +437,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { ...@@ -437,7 +437,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return; return;
} }
if (base::bits::IsPowerOfTwo32(value + 1)) { if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister(); InstructionOperand temp = g.TempRegister();
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1))); g.TempImmediate(WhichPowerOf2(value + 1)));
...@@ -646,12 +646,12 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -646,12 +646,12 @@ void InstructionSelector::VisitCall(Node* node) {
int push_count = buffer.pushed_nodes.size(); int push_count = buffer.pushed_nodes.size();
if (push_count > 0) { if (push_count > 0) {
Emit(kMips64StackClaim | MiscField::encode(push_count), NULL); Emit(kMips64StackClaim | MiscField::encode(push_count), g.NoOutput());
} }
int slot = buffer.pushed_nodes.size() - 1; int slot = buffer.pushed_nodes.size() - 1;
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) { ++i) {
Emit(kMips64StoreToStackSlot | MiscField::encode(slot), nullptr, Emit(kMips64StoreToStackSlot | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(*i)); g.UseRegister(*i));
slot--; slot--;
} }
...@@ -709,12 +709,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { ...@@ -709,12 +709,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset) ? g.UseImmediate(offset)
: g.UseRegister(offset); : g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length) ? g.UseImmediate(length)
: g.UseRegister(length) : g.UseRegister(length)
: g.UseRegister(length); : g.UseRegister(length);
...@@ -753,18 +753,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -753,18 +753,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset) ? g.UseImmediate(offset)
: g.UseRegister(offset); : g.UseRegister(offset);
InstructionOperand* length_operand = InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length) ? g.UseImmediate(length)
: g.UseRegister(length) : g.UseRegister(length)
: g.UseRegister(length); : g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand, Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
length_operand, g.UseRegister(value), g.UseRegister(buffer)); offset_operand, length_operand, g.UseRegister(value),
g.UseRegister(buffer));
} }
...@@ -772,12 +773,13 @@ namespace { ...@@ -772,12 +773,13 @@ namespace {
// Shared routine for multiple compare operations. // Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right, InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) { FlagsContinuation* cont) {
Mips64OperandGenerator g(selector); Mips64OperandGenerator g(selector);
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
...@@ -838,9 +840,9 @@ void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode, ...@@ -838,9 +840,9 @@ void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode,
Node* value, FlagsContinuation* cont) { Node* value, FlagsContinuation* cont) {
Mips64OperandGenerator g(selector); Mips64OperandGenerator g(selector);
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
InstructionOperand* const value_operand = g.UseRegister(value); InstructionOperand const value_operand = g.UseRegister(value);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0), selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
g.Label(cont->true_block()), g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
......
...@@ -31,7 +31,7 @@ class X64OperandGenerator FINAL : public OperandGenerator { ...@@ -31,7 +31,7 @@ class X64OperandGenerator FINAL : public OperandGenerator {
AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
Node* base, Node* displacement, Node* base, Node* displacement,
InstructionOperand* inputs[], InstructionOperand inputs[],
size_t* input_count) { size_t* input_count) {
AddressingMode mode = kMode_MRI; AddressingMode mode = kMode_MRI;
if (base != NULL) { if (base != NULL) {
...@@ -80,7 +80,7 @@ class X64OperandGenerator FINAL : public OperandGenerator { ...@@ -80,7 +80,7 @@ class X64OperandGenerator FINAL : public OperandGenerator {
} }
AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
InstructionOperand* inputs[], InstructionOperand inputs[],
size_t* input_count) { size_t* input_count) {
BaseWithIndexAndDisplacement64Matcher m(operand, true); BaseWithIndexAndDisplacement64Matcher m(operand, true);
DCHECK(m.matches()); DCHECK(m.matches());
...@@ -132,9 +132,9 @@ void InstructionSelector::VisitLoad(Node* node) { ...@@ -132,9 +132,9 @@ void InstructionSelector::VisitLoad(Node* node) {
return; return;
} }
InstructionOperand* outputs[1]; InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node); outputs[0] = g.DefineAsRegister(node);
InstructionOperand* inputs[3]; InstructionOperand inputs[3];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
...@@ -156,8 +156,8 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -156,8 +156,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. // TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx), Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps), g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
temps); temps);
return; return;
...@@ -189,15 +189,15 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -189,15 +189,15 @@ void InstructionSelector::VisitStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode); InstructionCode code = opcode | AddressingModeField::encode(mode);
InstructionOperand* value_operand = InstructionOperand value_operand =
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
inputs[input_count++] = value_operand; inputs[input_count++] = value_operand;
Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
} }
...@@ -241,7 +241,7 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { ...@@ -241,7 +241,7 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
return; return;
} }
} }
InstructionOperand* length_operand = InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
g.UseRegister(offset), g.TempImmediate(0), length_operand); g.UseRegister(offset), g.TempImmediate(0), length_operand);
...@@ -276,7 +276,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -276,7 +276,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE(); UNREACHABLE();
return; return;
} }
InstructionOperand* value_operand = InstructionOperand value_operand =
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
Int32Matcher mlength(length); Int32Matcher mlength(length);
...@@ -284,16 +284,16 @@ void InstructionSelector::VisitCheckedStore(Node* node) { ...@@ -284,16 +284,16 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
if (mlength.HasValue() && moffset.right().HasValue() && if (mlength.HasValue() && moffset.right().HasValue() &&
moffset.right().Value() >= 0 && moffset.right().Value() >= 0 &&
mlength.Value() >= moffset.right().Value()) { mlength.Value() >= moffset.right().Value()) {
Emit(opcode, nullptr, g.UseRegister(buffer), Emit(opcode, g.NoOutput(), g.UseRegister(buffer),
g.UseRegister(moffset.left().node()), g.UseRegister(moffset.left().node()),
g.UseImmediate(moffset.right().node()), g.UseImmediate(length), g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
value_operand); value_operand);
return; return;
} }
} }
InstructionOperand* length_operand = InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset), Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
g.TempImmediate(0), length_operand, value_operand); g.TempImmediate(0), length_operand, value_operand);
} }
...@@ -305,9 +305,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -305,9 +305,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
Int32BinopMatcher m(node); Int32BinopMatcher m(node);
Node* left = m.left().node(); Node* left = m.left().node();
Node* right = m.right().node(); Node* right = m.right().node();
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
InstructionOperand* outputs[2]; InstructionOperand outputs[2];
size_t output_count = 0; size_t output_count = 0;
// TODO(turbofan): match complex addressing modes. // TODO(turbofan): match complex addressing modes.
...@@ -319,7 +319,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -319,7 +319,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
// mov rax, [rbp-0x10] // mov rax, [rbp-0x10]
// add rax, [rbp-0x10] // add rax, [rbp-0x10]
// jo label // jo label
InstructionOperand* const input = g.UseRegister(left); InstructionOperand const input = g.UseRegister(left);
inputs[input_count++] = input; inputs[input_count++] = input;
inputs[input_count++] = input; inputs[input_count++] = input;
} else if (g.CanBeImmediate(right)) { } else if (g.CanBeImmediate(right)) {
...@@ -456,7 +456,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode, ...@@ -456,7 +456,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode,
Node* displacement) { Node* displacement) {
X64OperandGenerator g(selector); X64OperandGenerator g(selector);
InstructionOperand* inputs[4]; InstructionOperand inputs[4];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs( AddressingMode mode = g.GenerateMemoryOperandInputs(
index, scale, base, displacement, inputs, &input_count); index, scale, base, displacement, inputs, &input_count);
...@@ -464,7 +464,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode, ...@@ -464,7 +464,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode,
DCHECK_NE(0, static_cast<int>(input_count)); DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count); DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1]; InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(result); outputs[0] = g.DefineAsRegister(result);
opcode = AddressingModeField::encode(mode) | opcode; opcode = AddressingModeField::encode(mode) | opcode;
...@@ -634,7 +634,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node, ...@@ -634,7 +634,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node,
void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
X64OperandGenerator g(selector); X64OperandGenerator g(selector);
InstructionOperand* temps[] = {g.TempRegister(rdx)}; InstructionOperand temps[] = {g.TempRegister(rdx)};
selector->Emit( selector->Emit(
opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
...@@ -870,7 +870,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) { ...@@ -870,7 +870,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) {
void InstructionSelector::VisitFloat64Mod(Node* node) { void InstructionSelector::VisitFloat64Mod(Node* node) {
X64OperandGenerator g(this); X64OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(rax)}; InstructionOperand temps[] = {g.TempRegister(rax)};
Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
temps); temps);
...@@ -937,11 +937,11 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -937,11 +937,11 @@ void InstructionSelector::VisitCall(Node* node) {
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) { ++i) {
// TODO(titzer): handle pushing double parameters. // TODO(titzer): handle pushing double parameters.
InstructionOperand* value = InstructionOperand value =
g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
? g.UseRegister(*i) ? g.UseRegister(*i)
: g.Use(*i); : g.Use(*i);
Emit(kX64Push, nullptr, value); Emit(kX64Push, g.NoOutput(), value);
} }
// Select the appropriate opcode based on the call type. // Select the appropriate opcode based on the call type.
...@@ -961,7 +961,7 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -961,7 +961,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags()); opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction. // Emit the call instruction.
InstructionOperand** first_output = InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr = Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output, Emit(opcode, buffer.outputs.size(), first_output,
...@@ -972,12 +972,13 @@ void InstructionSelector::VisitCall(Node* node) { ...@@ -972,12 +972,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Shared routine for multiple compare operations. // Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right, InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) { FlagsContinuation* cont) {
X64OperandGenerator g(selector); X64OperandGenerator g(selector);
opcode = cont->Encode(opcode); opcode = cont->Encode(opcode);
if (cont->IsBranch()) { if (cont->IsBranch()) {
selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), selector->Emit(opcode, g.NoOutput(), left, right,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl(); g.Label(cont->false_block()))->MarkAsControl();
} else { } else {
DCHECK(cont->IsSet()); DCHECK(cont->IsSet());
......
...@@ -296,34 +296,22 @@ TEST(InstructionOperands) { ...@@ -296,34 +296,22 @@ TEST(InstructionOperands) {
} }
int vreg = 15; int vreg = 15;
InstructionOperand* outputs[] = { InstructionOperand outputs[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand* inputs[] = { InstructionOperand inputs[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand* temps[] = { InstructionOperand temps[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
for (size_t i = 0; i < arraysize(outputs); i++) { for (size_t i = 0; i < arraysize(outputs); i++) {
...@@ -336,15 +324,15 @@ TEST(InstructionOperands) { ...@@ -336,15 +324,15 @@ TEST(InstructionOperands) {
CHECK(k == m->TempCount()); CHECK(k == m->TempCount());
for (size_t z = 0; z < i; z++) { for (size_t z = 0; z < i; z++) {
CHECK(outputs[z]->Equals(m->OutputAt(z))); CHECK(outputs[z].Equals(m->OutputAt(z)));
} }
for (size_t z = 0; z < j; z++) { for (size_t z = 0; z < j; z++) {
CHECK(inputs[z]->Equals(m->InputAt(z))); CHECK(inputs[z].Equals(m->InputAt(z)));
} }
for (size_t z = 0; z < k; z++) { for (size_t z = 0; z < k; z++) {
CHECK(temps[z]->Equals(m->TempAt(z))); CHECK(temps[z].Equals(m->TempAt(z)));
} }
} }
} }
......
...@@ -31,7 +31,7 @@ class TestCode : public HandleAndZoneScope { ...@@ -31,7 +31,7 @@ class TestCode : public HandleAndZoneScope {
int Jump(int target) { int Jump(int target) {
Start(); Start();
InstructionOperand* ops[] = {UseRpo(target)}; InstructionOperand ops[] = {UseRpo(target)};
sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1, sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1,
ops, 0, NULL)->MarkAsControl()); ops, 0, NULL)->MarkAsControl());
int pos = static_cast<int>(sequence_.instructions().size() - 1); int pos = static_cast<int>(sequence_.instructions().size() - 1);
...@@ -44,7 +44,7 @@ class TestCode : public HandleAndZoneScope { ...@@ -44,7 +44,7 @@ class TestCode : public HandleAndZoneScope {
} }
int Branch(int ttarget, int ftarget) { int Branch(int ttarget, int ftarget) {
Start(); Start();
InstructionOperand* ops[] = {UseRpo(ttarget), UseRpo(ftarget)}; InstructionOperand ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) | InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) |
FlagsConditionField::encode(kEqual); FlagsConditionField::encode(kEqual);
sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2, sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2,
...@@ -81,9 +81,9 @@ class TestCode : public HandleAndZoneScope { ...@@ -81,9 +81,9 @@ class TestCode : public HandleAndZoneScope {
current_ = NULL; current_ = NULL;
rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1); rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
} }
InstructionOperand* UseRpo(int num) { InstructionOperand UseRpo(int num) {
int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num))); int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
return ImmediateOperand::Create(index, main_zone()); return ImmediateOperand(index);
} }
void Start(bool deferred = false) { void Start(bool deferred = false) {
if (current_ == NULL) { if (current_ == NULL) {
......
...@@ -138,7 +138,7 @@ InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) { ...@@ -138,7 +138,7 @@ InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) {
InstructionSequenceTest::VReg InstructionSequenceTest::Define( InstructionSequenceTest::VReg InstructionSequenceTest::Define(
TestOperand output_op) { TestOperand output_op) {
VReg vreg = NewReg(); VReg vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(vreg, output_op)}; InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)};
Emit(vreg.value_, kArchNop, 1, outputs); Emit(vreg.value_, kArchNop, 1, outputs);
return vreg; return vreg;
} }
...@@ -146,7 +146,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::Define( ...@@ -146,7 +146,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::Define(
int InstructionSequenceTest::Return(TestOperand input_op_0) { int InstructionSequenceTest::Return(TestOperand input_op_0) {
block_returns_ = true; block_returns_ = true;
InstructionOperand* inputs[1]{ConvertInputOp(input_op_0)}; InstructionOperand inputs[1]{ConvertInputOp(input_op_0)};
return Emit(NewIndex(), kArchRet, 0, nullptr, 1, inputs); return Emit(NewIndex(), kArchRet, 0, nullptr, 1, inputs);
} }
...@@ -176,7 +176,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant( ...@@ -176,7 +176,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant(
int32_t imm) { int32_t imm) {
VReg vreg = NewReg(); VReg vreg = NewReg();
sequence()->AddConstant(vreg.value_, Constant(imm)); sequence()->AddConstant(vreg.value_, Constant(imm));
InstructionOperand* outputs[1]{ConstantOperand::Create(vreg.value_, zone())}; InstructionOperand outputs[1]{ConstantOperand(vreg.value_)};
Emit(vreg.value_, kArchNop, 1, outputs); Emit(vreg.value_, kArchNop, 1, outputs);
return vreg; return vreg;
} }
...@@ -196,7 +196,7 @@ static size_t CountInputs(size_t size, ...@@ -196,7 +196,7 @@ static size_t CountInputs(size_t size,
int InstructionSequenceTest::EmitI(size_t input_size, TestOperand* inputs) { int InstructionSequenceTest::EmitI(size_t input_size, TestOperand* inputs) {
InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
return Emit(NewIndex(), kArchNop, 0, nullptr, input_size, mapped_inputs); return Emit(NewIndex(), kArchNop, 0, nullptr, input_size, mapped_inputs);
} }
...@@ -213,8 +213,8 @@ int InstructionSequenceTest::EmitI(TestOperand input_op_0, ...@@ -213,8 +213,8 @@ int InstructionSequenceTest::EmitI(TestOperand input_op_0,
InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
TestOperand output_op, size_t input_size, TestOperand* inputs) { TestOperand output_op, size_t input_size, TestOperand* inputs) {
VReg output_vreg = NewReg(); VReg output_vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)}; InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
Emit(output_vreg.value_, kArchNop, 1, outputs, input_size, mapped_inputs); Emit(output_vreg.value_, kArchNop, 1, outputs, input_size, mapped_inputs);
return output_vreg; return output_vreg;
} }
...@@ -231,9 +231,9 @@ InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( ...@@ -231,9 +231,9 @@ InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
TestOperand output_op, size_t input_size, TestOperand* inputs) { TestOperand output_op, size_t input_size, TestOperand* inputs) {
VReg output_vreg = NewReg(); VReg output_vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)}; InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
CHECK(UnallocatedOperand::cast(outputs[0])->HasFixedPolicy()); CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy());
InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
Emit(output_vreg.value_, kArchCallCodeObject, 1, outputs, input_size, Emit(output_vreg.value_, kArchCallCodeObject, 1, outputs, input_size,
mapped_inputs, 0, nullptr, true); mapped_inputs, 0, nullptr, true);
return output_vreg; return output_vreg;
...@@ -257,7 +257,7 @@ const Instruction* InstructionSequenceTest::GetInstruction( ...@@ -257,7 +257,7 @@ const Instruction* InstructionSequenceTest::GetInstruction(
int InstructionSequenceTest::EmitBranch(TestOperand input_op) { int InstructionSequenceTest::EmitBranch(TestOperand input_op) {
InstructionOperand* inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()), InstructionOperand inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
ConvertInputOp(Imm()), ConvertInputOp(Imm())}; ConvertInputOp(Imm()), ConvertInputOp(Imm())};
InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) | InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) |
FlagsConditionField::encode(kEqual); FlagsConditionField::encode(kEqual);
...@@ -274,7 +274,7 @@ int InstructionSequenceTest::EmitFallThrough() { ...@@ -274,7 +274,7 @@ int InstructionSequenceTest::EmitFallThrough() {
int InstructionSequenceTest::EmitJump() { int InstructionSequenceTest::EmitJump() {
InstructionOperand* inputs[1]{ConvertInputOp(Imm())}; InstructionOperand inputs[1]{ConvertInputOp(Imm())};
auto instruction = auto instruction =
NewInstruction(kArchJmp, 0, nullptr, 1, inputs)->MarkAsControl(); NewInstruction(kArchJmp, 0, nullptr, 1, inputs)->MarkAsControl();
return AddInstruction(NewIndex(), instruction); return AddInstruction(NewIndex(), instruction);
...@@ -282,44 +282,44 @@ int InstructionSequenceTest::EmitJump() { ...@@ -282,44 +282,44 @@ int InstructionSequenceTest::EmitJump() {
Instruction* InstructionSequenceTest::NewInstruction( Instruction* InstructionSequenceTest::NewInstruction(
InstructionCode code, size_t outputs_size, InstructionOperand** outputs, InstructionCode code, size_t outputs_size, InstructionOperand* outputs,
size_t inputs_size, InstructionOperand** inputs, size_t temps_size, size_t inputs_size, InstructionOperand* inputs, size_t temps_size,
InstructionOperand** temps) { InstructionOperand* temps) {
CHECK(current_block_); CHECK(current_block_);
return Instruction::New(zone(), code, outputs_size, outputs, inputs_size, return Instruction::New(zone(), code, outputs_size, outputs, inputs_size,
inputs, temps_size, temps); inputs, temps_size, temps);
} }
InstructionOperand* InstructionSequenceTest::Unallocated( InstructionOperand InstructionSequenceTest::Unallocated(
TestOperand op, UnallocatedOperand::ExtendedPolicy policy) { TestOperand op, UnallocatedOperand::ExtendedPolicy policy) {
return new (zone()) UnallocatedOperand(policy, op.vreg_.value_); return UnallocatedOperand(policy, op.vreg_.value_);
} }
InstructionOperand* InstructionSequenceTest::Unallocated( InstructionOperand InstructionSequenceTest::Unallocated(
TestOperand op, UnallocatedOperand::ExtendedPolicy policy, TestOperand op, UnallocatedOperand::ExtendedPolicy policy,
UnallocatedOperand::Lifetime lifetime) { UnallocatedOperand::Lifetime lifetime) {
return new (zone()) UnallocatedOperand(policy, lifetime, op.vreg_.value_); return UnallocatedOperand(policy, lifetime, op.vreg_.value_);
} }
InstructionOperand* InstructionSequenceTest::Unallocated( InstructionOperand InstructionSequenceTest::Unallocated(
TestOperand op, UnallocatedOperand::ExtendedPolicy policy, int index) { TestOperand op, UnallocatedOperand::ExtendedPolicy policy, int index) {
return new (zone()) UnallocatedOperand(policy, index, op.vreg_.value_); return UnallocatedOperand(policy, index, op.vreg_.value_);
} }
InstructionOperand* InstructionSequenceTest::Unallocated( InstructionOperand InstructionSequenceTest::Unallocated(
TestOperand op, UnallocatedOperand::BasicPolicy policy, int index) { TestOperand op, UnallocatedOperand::BasicPolicy policy, int index) {
return new (zone()) UnallocatedOperand(policy, index, op.vreg_.value_); return UnallocatedOperand(policy, index, op.vreg_.value_);
} }
InstructionOperand** InstructionSequenceTest::ConvertInputs( InstructionOperand* InstructionSequenceTest::ConvertInputs(
size_t input_size, TestOperand* inputs) { size_t input_size, TestOperand* inputs) {
InstructionOperand** mapped_inputs = InstructionOperand* mapped_inputs =
zone()->NewArray<InstructionOperand*>(static_cast<int>(input_size)); zone()->NewArray<InstructionOperand>(static_cast<int>(input_size));
for (size_t i = 0; i < input_size; ++i) { for (size_t i = 0; i < input_size; ++i) {
mapped_inputs[i] = ConvertInputOp(inputs[i]); mapped_inputs[i] = ConvertInputOp(inputs[i]);
} }
...@@ -327,10 +327,10 @@ InstructionOperand** InstructionSequenceTest::ConvertInputs( ...@@ -327,10 +327,10 @@ InstructionOperand** InstructionSequenceTest::ConvertInputs(
} }
InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) { InstructionOperand InstructionSequenceTest::ConvertInputOp(TestOperand op) {
if (op.type_ == kImmediate) { if (op.type_ == kImmediate) {
CHECK_EQ(op.vreg_.value_, kNoValue); CHECK_EQ(op.vreg_.value_, kNoValue);
return ImmediateOperand::Create(op.value_, zone()); return ImmediateOperand(op.value_);
} }
CHECK_NE(op.vreg_.value_, kNoValue); CHECK_NE(op.vreg_.value_, kNoValue);
switch (op.type_) { switch (op.type_) {
...@@ -353,11 +353,11 @@ InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) { ...@@ -353,11 +353,11 @@ InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) {
break; break;
} }
CHECK(false); CHECK(false);
return NULL; return InstructionOperand();
} }
InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg, InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg,
TestOperand op) { TestOperand op) {
CHECK_EQ(op.vreg_.value_, kNoValue); CHECK_EQ(op.vreg_.value_, kNoValue);
op.vreg_ = vreg; op.vreg_ = vreg;
...@@ -375,7 +375,7 @@ InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg, ...@@ -375,7 +375,7 @@ InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg,
break; break;
} }
CHECK(false); CHECK(false);
return NULL; return InstructionOperand();
} }
...@@ -445,11 +445,10 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) { ...@@ -445,11 +445,10 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
int InstructionSequenceTest::Emit(int instruction_index, InstructionCode code, int InstructionSequenceTest::Emit(int instruction_index, InstructionCode code,
size_t outputs_size, size_t outputs_size,
InstructionOperand** outputs, InstructionOperand* outputs,
size_t inputs_size, size_t inputs_size,
InstructionOperand** inputs, InstructionOperand* inputs, size_t temps_size,
size_t temps_size, InstructionOperand** temps, InstructionOperand* temps, bool is_call) {
bool is_call) {
auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size, auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size,
inputs, temps_size, temps); inputs, temps_size, temps);
if (is_call) instruction->MarkAsCall(); if (is_call) instruction->MarkAsCall();
......
...@@ -179,32 +179,32 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { ...@@ -179,32 +179,32 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
int EmitFallThrough(); int EmitFallThrough();
int EmitJump(); int EmitJump();
Instruction* NewInstruction(InstructionCode code, size_t outputs_size, Instruction* NewInstruction(InstructionCode code, size_t outputs_size,
InstructionOperand** outputs, InstructionOperand* outputs,
size_t inputs_size = 0, size_t inputs_size = 0,
InstructionOperand* *inputs = nullptr, InstructionOperand* inputs = nullptr,
size_t temps_size = 0, size_t temps_size = 0,
InstructionOperand* *temps = nullptr); InstructionOperand* temps = nullptr);
InstructionOperand* Unallocated(TestOperand op, InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy); UnallocatedOperand::ExtendedPolicy policy);
InstructionOperand* Unallocated(TestOperand op, InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy, UnallocatedOperand::ExtendedPolicy policy,
UnallocatedOperand::Lifetime lifetime); UnallocatedOperand::Lifetime lifetime);
InstructionOperand* Unallocated(TestOperand op, InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy, UnallocatedOperand::ExtendedPolicy policy,
int index); int index);
InstructionOperand* Unallocated(TestOperand op, InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::BasicPolicy policy, UnallocatedOperand::BasicPolicy policy,
int index); int index);
InstructionOperand** ConvertInputs(size_t input_size, TestOperand* inputs); InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs);
InstructionOperand* ConvertInputOp(TestOperand op); InstructionOperand ConvertInputOp(TestOperand op);
InstructionOperand* ConvertOutputOp(VReg vreg, TestOperand op); InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op);
InstructionBlock* NewBlock(); InstructionBlock* NewBlock();
void WireBlock(size_t block_offset, int jump_offset); void WireBlock(size_t block_offset, int jump_offset);
int Emit(int instruction_index, InstructionCode code, size_t outputs_size = 0, int Emit(int instruction_index, InstructionCode code, size_t outputs_size = 0,
InstructionOperand* *outputs = nullptr, size_t inputs_size = 0, InstructionOperand* outputs = nullptr, size_t inputs_size = 0,
InstructionOperand* *inputs = nullptr, size_t temps_size = 0, InstructionOperand* inputs = nullptr, size_t temps_size = 0,
InstructionOperand* *temps = nullptr, bool is_call = false); InstructionOperand* temps = nullptr, bool is_call = false);
int AddInstruction(int instruction_index, Instruction* instruction); int AddInstruction(int instruction_index, Instruction* instruction);
......
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