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
......@@ -99,8 +99,8 @@ template <IrOpcode::Value kOpcode, int kImmMin, int kImmMax,
AddressingMode kImmMode, AddressingMode kRegMode>
bool TryMatchShift(InstructionSelector* selector,
InstructionCode* opcode_return, Node* node,
InstructionOperand** value_return,
InstructionOperand** shift_return) {
InstructionOperand* value_return,
InstructionOperand* shift_return) {
ArmOperandGenerator g(selector);
if (node->opcode() == kOpcode) {
Int32BinopMatcher m(node);
......@@ -119,8 +119,8 @@ bool TryMatchShift(InstructionSelector* selector,
bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return,
Node* node, InstructionOperand** value_return,
InstructionOperand** shift_return) {
Node* node, InstructionOperand* value_return,
InstructionOperand* shift_return) {
return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I,
kMode_Operand2_R_ROR_R>(selector, opcode_return, node,
value_return, shift_return);
......@@ -128,8 +128,8 @@ bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return,
bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return,
Node* node, InstructionOperand** value_return,
InstructionOperand** shift_return) {
Node* node, InstructionOperand* value_return,
InstructionOperand* shift_return) {
return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I,
kMode_Operand2_R_ASR_R>(selector, opcode_return, node,
value_return, shift_return);
......@@ -137,8 +137,8 @@ bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return,
bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return,
Node* node, InstructionOperand** value_return,
InstructionOperand** shift_return) {
Node* node, InstructionOperand* value_return,
InstructionOperand* shift_return) {
return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I,
kMode_Operand2_R_LSL_R>(selector, opcode_return, node,
value_return, shift_return);
......@@ -146,8 +146,8 @@ bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return,
bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return,
Node* node, InstructionOperand** value_return,
InstructionOperand** shift_return) {
Node* node, InstructionOperand* value_return,
InstructionOperand* shift_return) {
return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I,
kMode_Operand2_R_LSR_R>(selector, opcode_return, node,
value_return, shift_return);
......@@ -156,8 +156,8 @@ bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return,
bool TryMatchShift(InstructionSelector* selector,
InstructionCode* opcode_return, Node* node,
InstructionOperand** value_return,
InstructionOperand** shift_return) {
InstructionOperand* value_return,
InstructionOperand* shift_return) {
return (
TryMatchASR(selector, opcode_return, node, value_return, shift_return) ||
TryMatchLSL(selector, opcode_return, node, value_return, shift_return) ||
......@@ -169,7 +169,7 @@ bool TryMatchShift(InstructionSelector* selector,
bool TryMatchImmediateOrShift(InstructionSelector* selector,
InstructionCode* opcode_return, Node* node,
size_t* input_count_return,
InstructionOperand** inputs) {
InstructionOperand* inputs) {
ArmOperandGenerator g(selector);
if (g.CanBeImmediate(node, *opcode_return)) {
*opcode_return |= AddressingModeField::encode(kMode_Operand2_I);
......@@ -190,9 +190,9 @@ void VisitBinop(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[5];
InstructionOperand inputs[5];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
if (m.left().node() == m.right().node()) {
......@@ -203,7 +203,7 @@ void VisitBinop(InstructionSelector* selector, Node* node,
// mov r0, r1, asr #16
// adds r0, r0, r1, asr #16
// bvs label
InstructionOperand* const input = g.UseRegister(m.left().node());
InstructionOperand const input = g.UseRegister(m.left().node());
opcode |= AddressingModeField::encode(kMode_Operand2_R);
inputs[input_count++] = input;
inputs[input_count++] = input;
......@@ -309,10 +309,9 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)};
Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4),
g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps),
temps);
InstructionOperand temps[] = {g.TempRegister(r5), g.TempRegister(r6)};
Emit(kArmStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, r4),
g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), temps);
return;
}
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
......@@ -342,10 +341,10 @@ void InstructionSelector::VisitStore(Node* node) {
}
if (g.CanBeImmediate(index, opcode)) {
Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL,
Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(),
g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
} else {
Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL,
Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(),
g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
}
}
......@@ -379,10 +378,10 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
? g.UseImmediate(length)
: g.UseRegister(length);
InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp)
? g.UseImmediate(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_Offset_RR),
g.DefineAsRegister(node), offset_operand, length_operand,
g.UseRegister(buffer), offset_operand);
......@@ -417,11 +416,11 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
? g.UseImmediate(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), nullptr,
InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp)
? g.UseImmediate(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(),
offset_operand, length_operand, g.UseRegister(value),
g.UseRegister(buffer), offset_operand);
}
......@@ -433,8 +432,8 @@ void EmitBic(InstructionSelector* selector, Node* node, Node* left,
Node* right) {
ArmOperandGenerator g(selector);
InstructionCode opcode = kArmBic;
InstructionOperand* value_operand;
InstructionOperand* shift_operand;
InstructionOperand value_operand;
InstructionOperand shift_operand;
if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) {
selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left),
value_operand, shift_operand);
......@@ -535,8 +534,8 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
Int32BinopMatcher m(node);
if (m.right().Is(-1)) {
InstructionCode opcode = kArmMvn;
InstructionOperand* value_operand;
InstructionOperand* shift_operand;
InstructionOperand value_operand;
InstructionOperand shift_operand;
if (TryMatchShift(this, &opcode, m.left().node(), &value_operand,
&shift_operand)) {
Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand);
......@@ -557,9 +556,9 @@ void VisitShift(InstructionSelector* selector, Node* node,
TryMatchShift try_match_shift, FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
InstructionCode opcode = kArmMov;
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 2;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1]));
......@@ -809,26 +808,26 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) {
void InstructionSelector::VisitUint32MulHigh(Node* node) {
ArmOperandGenerator g(this);
InstructionOperand* outputs[] = {g.TempRegister(), g.DefineAsRegister(node)};
InstructionOperand* inputs[] = {g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1))};
InstructionOperand outputs[] = {g.TempRegister(), g.DefineAsRegister(node)};
InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1))};
Emit(kArmUmull, arraysize(outputs), outputs, arraysize(inputs), inputs);
}
static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode,
ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode,
InstructionOperand* result_operand,
InstructionOperand* left_operand,
InstructionOperand* right_operand) {
InstructionOperand result_operand,
InstructionOperand left_operand,
InstructionOperand right_operand) {
ArmOperandGenerator g(selector);
if (selector->IsSupported(SUDIV)) {
selector->Emit(div_opcode, result_operand, left_operand, right_operand);
return;
}
InstructionOperand* left_double_operand = g.TempDoubleRegister();
InstructionOperand* right_double_operand = g.TempDoubleRegister();
InstructionOperand* result_double_operand = g.TempDoubleRegister();
InstructionOperand left_double_operand = g.TempDoubleRegister();
InstructionOperand right_double_operand = g.TempDoubleRegister();
InstructionOperand result_double_operand = g.TempDoubleRegister();
selector->Emit(f64i32_opcode, left_double_operand, left_operand);
selector->Emit(f64i32_opcode, right_double_operand, right_operand);
selector->Emit(kArmVdivF64, result_double_operand, left_double_operand,
......@@ -863,10 +862,10 @@ static void VisitMod(InstructionSelector* selector, Node* node,
ArchOpcode i32f64_opcode) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* div_operand = g.TempRegister();
InstructionOperand* result_operand = g.DefineAsRegister(node);
InstructionOperand* left_operand = g.UseRegister(m.left().node());
InstructionOperand* right_operand = g.UseRegister(m.right().node());
InstructionOperand div_operand = g.TempRegister();
InstructionOperand result_operand = g.DefineAsRegister(node);
InstructionOperand left_operand = g.UseRegister(m.left().node());
InstructionOperand right_operand = g.UseRegister(m.right().node());
EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand,
left_operand, right_operand);
if (selector->IsSupported(MLS)) {
......@@ -874,7 +873,7 @@ static void VisitMod(InstructionSelector* selector, Node* node,
left_operand);
return;
}
InstructionOperand* mul_operand = g.TempRegister();
InstructionOperand mul_operand = g.TempRegister();
selector->Emit(kArmMul, mul_operand, div_operand, right_operand);
selector->Emit(kArmSub, result_operand, left_operand, mul_operand);
}
......@@ -1041,7 +1040,7 @@ void InstructionSelector::VisitCall(Node* node) {
// Push any stack arguments.
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) {
Emit(kArmPush, nullptr, g.UseRegister(*i));
Emit(kArmPush, g.NoOutput(), g.UseRegister(*i));
}
// Select the appropriate opcode based on the call type.
......@@ -1061,7 +1060,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction.
InstructionOperand** first_output =
InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output,
......@@ -1077,10 +1076,10 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
Float64BinopMatcher m(node);
InstructionOperand* rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node())
: g.UseRegister(m.right().node());
InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node())
: g.UseRegister(m.right().node());
if (cont->IsBranch()) {
selector->Emit(cont->Encode(kArmVcmpF64), nullptr,
selector->Emit(cont->Encode(kArmVcmpF64), g.NoOutput(),
g.UseRegister(m.left().node()), rhs,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl();
......@@ -1098,9 +1097,9 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont) {
ArmOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[5];
InstructionOperand inputs[5];
size_t input_count = 0;
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
size_t output_count = 0;
if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
......@@ -1234,9 +1233,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
ArmOperandGenerator g(selector);
InstructionCode const opcode =
cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
InstructionOperand* const value_operand = g.UseRegister(value);
InstructionOperand const value_operand = g.UseRegister(value);
if (cont->IsBranch()) {
selector->Emit(opcode, nullptr, value_operand, value_operand,
selector->Emit(opcode, g.NoOutput(), value_operand, value_operand,
g.Label(cont->true_block()),
g.Label(cont->false_block()))->MarkAsControl();
} else {
......
......@@ -30,7 +30,7 @@ class Arm64OperandGenerator FINAL : public OperandGenerator {
explicit Arm64OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, ImmediateMode mode) {
InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
if (CanBeImmediate(node, mode)) {
return UseImmediate(node);
}
......@@ -174,9 +174,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
Arm64OperandGenerator g(selector);
Matcher m(node);
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
bool try_ror_operand = true;
......@@ -313,8 +313,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10),
InstructionOperand temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
Emit(kArm64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, x10),
g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps),
temps);
return;
......@@ -354,10 +354,10 @@ void InstructionSelector::VisitStore(Node* node) {
return;
}
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));
} 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));
}
}
......@@ -424,7 +424,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
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));
}
......@@ -864,7 +864,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
void InstructionSelector::VisitInt32MulHigh(Node* node) {
// TODO(arm64): Can we do better here?
Arm64OperandGenerator g(this);
InstructionOperand* const smull_operand = g.TempRegister();
InstructionOperand const smull_operand = g.TempRegister();
Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)));
Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
......@@ -874,7 +874,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) {
void InstructionSelector::VisitUint32MulHigh(Node* node) {
// TODO(arm64): Can we do better here?
Arm64OperandGenerator g(this);
InstructionOperand* const smull_operand = g.TempRegister();
InstructionOperand const smull_operand = g.TempRegister();
Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)));
Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
......@@ -1107,7 +1107,7 @@ void InstructionSelector::VisitCall(Node* node) {
if (aligned_push_count > 0) {
// TODO(dcarney): it would be better to bump the csp here only
// 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.
{
......@@ -1115,12 +1115,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Emit the uneven pushes.
if (pushed_count_uneven) {
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--;
}
// Now all pushes can be done in pairs.
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 - 1]));
}
......@@ -1143,7 +1144,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction.
InstructionOperand** first_output =
InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output,
......@@ -1154,12 +1155,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right,
InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) {
Arm64OperandGenerator g(selector);
opcode = cont->Encode(opcode);
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();
} else {
DCHECK(cont->IsSet());
......@@ -1348,7 +1350,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// If the mask has only one bit set, we can use tbz/tbnz.
DCHECK((cont.condition() == kEqual) ||
(cont.condition() == kNotEqual));
Emit(cont.Encode(kArm64TestAndBranch32), NULL,
Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(),
g.UseRegister(m.left().node()),
g.TempImmediate(
base::bits::CountTrailingZeros32(m.right().Value())),
......@@ -1366,7 +1368,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// If the mask has only one bit set, we can use tbz/tbnz.
DCHECK((cont.condition() == kEqual) ||
(cont.condition() == kNotEqual));
Emit(cont.Encode(kArm64TestAndBranch), NULL,
Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(),
g.UseRegister(m.left().node()),
g.TempImmediate(
base::bits::CountTrailingZeros64(m.right().Value())),
......@@ -1383,8 +1385,8 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
}
// Branch could not be combined with a compare, compare against 0 and branch.
Emit(cont.Encode(kArm64CompareAndBranch32), NULL, g.UseRegister(value),
g.Label(cont.true_block()),
Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(),
g.UseRegister(value), g.Label(cont.true_block()),
g.Label(cont.false_block()))->MarkAsControl();
}
......
......@@ -16,7 +16,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
explicit IA32OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {}
InstructionOperand* UseByteRegister(Node* node) {
InstructionOperand UseByteRegister(Node* node) {
// TODO(dcarney): relax constraint.
return UseFixed(node, edx);
}
......@@ -41,7 +41,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
Node* displacement_node,
InstructionOperand* inputs[],
InstructionOperand inputs[],
size_t* input_count) {
AddressingMode mode = kMode_MRI;
int32_t displacement = (displacement_node == NULL)
......@@ -99,7 +99,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
}
AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
InstructionOperand* inputs[],
InstructionOperand inputs[],
size_t* input_count) {
BaseWithIndexAndDisplacement32Matcher m(node, true);
DCHECK(m.matches());
......@@ -157,9 +157,9 @@ void InstructionSelector::VisitLoad(Node* node) {
}
IA32OperandGenerator g(this);
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node);
InstructionOperand* inputs[3];
InstructionOperand inputs[3];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
......@@ -181,8 +181,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx),
InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
temps);
return;
......@@ -213,7 +213,7 @@ void InstructionSelector::VisitStore(Node* node) {
return;
}
InstructionOperand* val;
InstructionOperand val;
if (g.CanBeImmediate(value)) {
val = g.UseImmediate(value);
} else if (rep == kRepWord8 || rep == kRepBit) {
......@@ -222,13 +222,13 @@ void InstructionSelector::VisitStore(Node* node) {
val = g.UseRegister(value);
}
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode);
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) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand =
InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
if (g.CanBeImmediate(buffer)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI),
......@@ -303,20 +303,20 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* value_operand =
InstructionOperand value_operand =
g.CanBeImmediate(value)
? g.UseImmediate(value)
: ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value)
: g.UseRegister(value));
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* length_operand =
InstructionOperand offset_operand = g.UseRegister(offset);
InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
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,
g.UseImmediate(buffer));
} 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);
}
......@@ -330,9 +330,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
Int32BinopMatcher m(node);
Node* left = m.left().node();
Node* right = m.right().node();
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
// TODO(turbofan): match complex addressing modes.
......@@ -344,7 +344,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
// mov eax, [ebp-0x10]
// add eax, [ebp-0x10]
// jo label
InstructionOperand* const input = g.UseRegister(left);
InstructionOperand const input = g.UseRegister(left);
inputs[input_count++] = input;
inputs[input_count++] = input;
} else if (g.CanBeImmediate(right)) {
......@@ -440,7 +440,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node,
void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
IA32OperandGenerator g(selector);
InstructionOperand* temps[] = {g.TempRegister(edx)};
InstructionOperand temps[] = {g.TempRegister(edx)};
selector->Emit(opcode, g.DefineAsFixed(node, eax),
g.UseFixed(node->InputAt(0), eax),
g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
......@@ -457,7 +457,7 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
void EmitLea(InstructionSelector* selector, Node* result, Node* index,
int scale, Node* base, Node* displacement) {
IA32OperandGenerator g(selector);
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs(
index, scale, base, displacement, inputs, &input_count);
......@@ -465,7 +465,7 @@ void EmitLea(InstructionSelector* selector, Node* result, Node* index,
DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(result);
InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
......@@ -510,7 +510,7 @@ void InstructionSelector::VisitInt32Add(Node* node) {
BaseWithIndexAndDisplacement32Matcher m(node);
if (m.matches() &&
(m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs(
m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
......@@ -518,7 +518,7 @@ void InstructionSelector::VisitInt32Add(Node* node) {
DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node);
InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
......@@ -682,7 +682,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) {
void InstructionSelector::VisitFloat64Mod(Node* node) {
IA32OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(eax)};
InstructionOperand temps[] = {g.TempRegister(eax)};
Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
temps);
......@@ -738,11 +738,11 @@ void InstructionSelector::VisitCall(Node* node) {
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) {
// TODO(titzer): handle pushing double parameters.
InstructionOperand* value =
InstructionOperand value =
g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
? g.UseRegister(*i)
: g.Use(*i);
Emit(kIA32Push, nullptr, value);
Emit(kIA32Push, g.NoOutput(), value);
}
// Select the appropriate opcode based on the call type.
......@@ -762,7 +762,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction.
InstructionOperand** first_output =
InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output,
......@@ -775,11 +775,11 @@ namespace {
// Shared routine for multiple compare operations.
void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right,
InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) {
IA32OperandGenerator g(selector);
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->false_block()))->MarkAsControl();
} else {
......
......@@ -21,126 +21,129 @@ class OperandGenerator {
explicit OperandGenerator(InstructionSelector* selector)
: selector_(selector) {}
InstructionOperand* DefineAsRegister(Node* node) {
InstructionOperand NoOutput() {
return InstructionOperand(); // Generates an invalid operand.
}
InstructionOperand DefineAsRegister(Node* node) {
return Define(node,
new (zone()) UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node)));
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
GetVReg(node)));
}
InstructionOperand* DefineSameAsFirst(Node* node) {
InstructionOperand DefineSameAsFirst(Node* node) {
return Define(node,
new (zone()) UnallocatedOperand(
UnallocatedOperand::SAME_AS_FIRST_INPUT, GetVReg(node)));
UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT,
GetVReg(node)));
}
InstructionOperand* DefineAsFixed(Node* node, Register reg) {
return Define(node, new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg), GetVReg(node)));
InstructionOperand DefineAsFixed(Node* node, Register reg) {
return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg),
GetVReg(node)));
}
InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) {
InstructionOperand DefineAsFixed(Node* node, DoubleRegister reg) {
return Define(node,
new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_DOUBLE_REGISTER,
DoubleRegister::ToAllocationIndex(reg), GetVReg(node)));
UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
DoubleRegister::ToAllocationIndex(reg),
GetVReg(node)));
}
InstructionOperand* DefineAsConstant(Node* node) {
InstructionOperand DefineAsConstant(Node* node) {
selector()->MarkAsDefined(node);
int virtual_register = GetVReg(node);
sequence()->AddConstant(virtual_register, ToConstant(node));
return ConstantOperand::Create(virtual_register, zone());
return ConstantOperand(virtual_register);
}
InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location,
MachineType type) {
InstructionOperand DefineAsLocation(Node* node, LinkageLocation location,
MachineType type) {
return Define(node, ToUnallocatedOperand(location, type, GetVReg(node)));
}
InstructionOperand* Use(Node* node) {
return Use(node, new (zone()) UnallocatedOperand(
UnallocatedOperand::NONE,
UnallocatedOperand::USED_AT_START, GetVReg(node)));
InstructionOperand Use(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::NONE,
UnallocatedOperand::USED_AT_START,
GetVReg(node)));
}
InstructionOperand* UseRegister(Node* node) {
return Use(node, new (zone()) UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER,
UnallocatedOperand::USED_AT_START, GetVReg(node)));
InstructionOperand UseRegister(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
UnallocatedOperand::USED_AT_START,
GetVReg(node)));
}
// Use register or operand for the node. If a register is chosen, it won't
// alias any temporary or output registers.
InstructionOperand* UseUnique(Node* node) {
return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE,
GetVReg(node)));
InstructionOperand UseUnique(Node* node) {
return Use(node,
UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node)));
}
// Use a unique register for the node that does not alias any temporary or
// output registers.
InstructionOperand* UseUniqueRegister(Node* node) {
return Use(node,
new (zone()) UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node)));
InstructionOperand UseUniqueRegister(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
GetVReg(node)));
}
InstructionOperand* UseFixed(Node* node, Register reg) {
return Use(node, new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg), GetVReg(node)));
InstructionOperand UseFixed(Node* node, Register reg) {
return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg),
GetVReg(node)));
}
InstructionOperand* UseFixed(Node* node, DoubleRegister reg) {
InstructionOperand UseFixed(Node* node, DoubleRegister reg) {
return Use(node,
new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_DOUBLE_REGISTER,
DoubleRegister::ToAllocationIndex(reg), GetVReg(node)));
UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
DoubleRegister::ToAllocationIndex(reg),
GetVReg(node)));
}
InstructionOperand* UseImmediate(Node* node) {
InstructionOperand UseImmediate(Node* node) {
int index = sequence()->AddImmediate(ToConstant(node));
return ImmediateOperand::Create(index, zone());
return ImmediateOperand(index);
}
InstructionOperand* UseLocation(Node* node, LinkageLocation location,
MachineType type) {
InstructionOperand UseLocation(Node* node, LinkageLocation location,
MachineType type) {
return Use(node, ToUnallocatedOperand(location, type, GetVReg(node)));
}
InstructionOperand* TempRegister() {
return new (zone()) UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER,
UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
InstructionOperand TempRegister() {
return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
UnallocatedOperand::USED_AT_START,
sequence()->NextVirtualRegister());
}
InstructionOperand* TempDoubleRegister() {
UnallocatedOperand* op = new (zone()) UnallocatedOperand(
InstructionOperand TempDoubleRegister() {
UnallocatedOperand op = UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER,
UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
sequence()->MarkAsDouble(op->virtual_register());
sequence()->MarkAsDouble(op.virtual_register());
return op;
}
InstructionOperand* TempRegister(Register reg) {
return new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_REGISTER, Register::ToAllocationIndex(reg),
UnallocatedOperand::kInvalidVirtualRegister);
InstructionOperand TempRegister(Register reg) {
return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg),
UnallocatedOperand::kInvalidVirtualRegister);
}
InstructionOperand* TempImmediate(int32_t imm) {
InstructionOperand TempImmediate(int32_t imm) {
int index = sequence()->AddImmediate(Constant(imm));
return ImmediateOperand::Create(index, zone());
return ImmediateOperand(index);
}
InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
InstructionOperand TempLocation(LinkageLocation location, MachineType type) {
return ToUnallocatedOperand(location, type,
sequence()->NextVirtualRegister());
}
InstructionOperand* Label(BasicBlock* block) {
InstructionOperand Label(BasicBlock* block) {
int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
return ImmediateOperand::Create(index, zone());
return ImmediateOperand(index);
}
protected:
......@@ -173,51 +176,47 @@ class OperandGenerator {
return Constant(static_cast<int32_t>(0));
}
UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
UnallocatedOperand Define(Node* node, UnallocatedOperand operand) {
DCHECK_NOT_NULL(node);
DCHECK_NOT_NULL(operand);
DCHECK_EQ(operand->virtual_register(), GetVReg(node));
DCHECK_EQ(operand.virtual_register(), GetVReg(node));
selector()->MarkAsDefined(node);
return operand;
}
UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
UnallocatedOperand Use(Node* node, UnallocatedOperand operand) {
DCHECK_NOT_NULL(node);
DCHECK_NOT_NULL(operand);
DCHECK_EQ(operand->virtual_register(), GetVReg(node));
DCHECK_EQ(operand.virtual_register(), GetVReg(node));
selector()->MarkAsUsed(node);
return operand;
}
UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location,
MachineType type,
int virtual_register) {
UnallocatedOperand ToUnallocatedOperand(LinkageLocation location,
MachineType type,
int virtual_register) {
if (location.location_ == LinkageLocation::ANY_REGISTER) {
// any machine register.
return new (zone()) UnallocatedOperand(
UnallocatedOperand::MUST_HAVE_REGISTER, virtual_register);
return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
virtual_register);
}
if (location.location_ < 0) {
// a location on the caller frame.
return new (zone()) UnallocatedOperand(
UnallocatedOperand::FIXED_SLOT, location.location_, virtual_register);
return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
location.location_, virtual_register);
}
if (location.location_ > LinkageLocation::ANY_REGISTER) {
// a spill location on this (callee) frame.
return new (zone()) UnallocatedOperand(
return UnallocatedOperand(
UnallocatedOperand::FIXED_SLOT,
location.location_ - LinkageLocation::ANY_REGISTER - 1,
virtual_register);
}
// a fixed register.
if (RepresentationOf(type) == kRepFloat64) {
return new (zone())
UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
location.location_, virtual_register);
return UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
location.location_, virtual_register);
}
return new (zone())
UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
location.location_, virtual_register);
return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
location.location_, virtual_register);
}
InstructionSelector* selector_;
......
......@@ -73,30 +73,30 @@ void InstructionSelector::SelectInstructions() {
Instruction* InstructionSelector::Emit(InstructionCode opcode,
InstructionOperand* output,
InstructionOperand output,
size_t temp_count,
InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps);
}
Instruction* InstructionSelector::Emit(InstructionCode opcode,
InstructionOperand* output,
InstructionOperand* a, size_t temp_count,
InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand output,
InstructionOperand a, size_t temp_count,
InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
}
Instruction* InstructionSelector::Emit(InstructionCode opcode,
InstructionOperand* output,
InstructionOperand* a,
InstructionOperand* b, size_t temp_count,
InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* inputs[] = {a, b};
InstructionOperand output,
InstructionOperand a,
InstructionOperand b, size_t temp_count,
InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b};
size_t input_count = arraysize(inputs);
return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
temps);
......@@ -104,13 +104,13 @@ Instruction* InstructionSelector::Emit(InstructionCode opcode,
Instruction* InstructionSelector::Emit(InstructionCode opcode,
InstructionOperand* output,
InstructionOperand* a,
InstructionOperand* b,
InstructionOperand* c, size_t temp_count,
InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* inputs[] = {a, b, c};
InstructionOperand output,
InstructionOperand a,
InstructionOperand b,
InstructionOperand c, size_t temp_count,
InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b, c};
size_t input_count = arraysize(inputs);
return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
temps);
......@@ -118,11 +118,11 @@ Instruction* InstructionSelector::Emit(InstructionCode opcode,
Instruction* InstructionSelector::Emit(
InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
size_t temp_count, InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* inputs[] = {a, b, c, d};
InstructionCode opcode, InstructionOperand output, InstructionOperand a,
InstructionOperand b, InstructionOperand c, InstructionOperand d,
size_t temp_count, InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b, c, d};
size_t input_count = arraysize(inputs);
return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
temps);
......@@ -130,11 +130,11 @@ Instruction* InstructionSelector::Emit(
Instruction* InstructionSelector::Emit(
InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
InstructionOperand* e, size_t temp_count, InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* inputs[] = {a, b, c, d, e};
InstructionCode opcode, InstructionOperand output, InstructionOperand a,
InstructionOperand b, InstructionOperand c, InstructionOperand d,
InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b, c, d, e};
size_t input_count = arraysize(inputs);
return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
temps);
......@@ -142,12 +142,12 @@ Instruction* InstructionSelector::Emit(
Instruction* InstructionSelector::Emit(
InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
InstructionOperand* e, InstructionOperand* f, size_t temp_count,
InstructionOperand** temps) {
size_t output_count = output == NULL ? 0 : 1;
InstructionOperand* inputs[] = {a, b, c, d, e, f};
InstructionCode opcode, InstructionOperand output, InstructionOperand a,
InstructionOperand b, InstructionOperand c, InstructionOperand d,
InstructionOperand e, InstructionOperand f, size_t temp_count,
InstructionOperand* temps) {
size_t output_count = output.IsInvalid() ? 0 : 1;
InstructionOperand inputs[] = {a, b, c, d, e, f};
size_t input_count = arraysize(inputs);
return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
temps);
......@@ -155,9 +155,9 @@ Instruction* InstructionSelector::Emit(
Instruction* InstructionSelector::Emit(
InstructionCode opcode, size_t output_count, InstructionOperand** outputs,
size_t input_count, InstructionOperand** inputs, size_t temp_count,
InstructionOperand** temps) {
InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand* inputs, size_t temp_count,
InstructionOperand* temps) {
Instruction* instr =
Instruction::New(instruction_zone(), opcode, output_count, outputs,
input_count, inputs, temp_count, temps);
......@@ -271,15 +271,15 @@ void InstructionSelector::MarkAsReference(Node* node) {
void InstructionSelector::MarkAsRepresentation(MachineType rep,
InstructionOperand* op) {
UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
const InstructionOperand& op) {
UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
switch (RepresentationOf(rep)) {
case kRepFloat32:
case kRepFloat64:
sequence()->MarkAsDouble(unalloc->virtual_register());
sequence()->MarkAsDouble(unalloc.virtual_register());
break;
case kRepTagged:
sequence()->MarkAsReference(unalloc->virtual_register());
sequence()->MarkAsReference(unalloc.virtual_register());
break;
default:
break;
......@@ -363,7 +363,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
buffer->descriptor->GetReturnLocation(static_cast<int>(i));
Node* output = buffer->output_nodes[i];
InstructionOperand* op =
InstructionOperand op =
output == NULL ? g.TempLocation(location, type)
: g.DefineAsLocation(output, location, type);
MarkAsRepresentation(type, op);
......@@ -427,11 +427,11 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
DCHECK(iter != call->inputs().end());
DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
if (index == 0) continue; // The first argument (callee) is already done.
InstructionOperand* op =
InstructionOperand op =
g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index),
buffer->descriptor->GetInputType(index));
if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) {
int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1;
if (UnallocatedOperand::cast(op).HasFixedSlotPolicy()) {
int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
buffer->pushed_nodes.resize(stack_index + 1, NULL);
}
......@@ -1034,23 +1034,25 @@ void InstructionSelector::VisitConstant(Node* node) {
void InstructionSelector::VisitGoto(BasicBlock* target) {
// jump to the next block.
OperandGenerator g(this);
Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
Emit(kArchJmp, g.NoOutput(), g.Label(target))->MarkAsControl();
}
void InstructionSelector::VisitReturn(Node* value) {
OperandGenerator g(this);
if (value != NULL) {
Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(),
linkage()->GetReturnType()));
Emit(kArchRet, g.NoOutput(),
g.UseLocation(value, linkage()->GetReturnLocation(),
linkage()->GetReturnType()));
} else {
Emit(kArchRet, NULL);
Emit(kArchRet, g.NoOutput());
}
}
void InstructionSelector::VisitThrow(Node* value) {
Emit(kArchNop, NULL); // TODO(titzer)
OperandGenerator g(this);
Emit(kArchNop, g.NoOutput()); // TODO(titzer)
}
......@@ -1089,7 +1091,7 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
}
static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) {
static InstructionOperand UseOrImmediate(OperandGenerator* g, Node* input) {
switch (input->opcode()) {
case IrOpcode::kInt32Constant:
case IrOpcode::kNumberConstant:
......
......@@ -23,6 +23,9 @@ class FlagsContinuation;
class Linkage;
typedef ZoneVector<InstructionOperand> InstructionOperandVector;
// Instruction selection generates an InstructionSequence for a given Schedule.
class InstructionSelector FINAL {
public:
......@@ -41,36 +44,36 @@ class InstructionSelector FINAL {
// ============= Architecture-independent code emission methods. =============
// ===========================================================================
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
size_t temp_count = 0, InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, size_t temp_count = 0,
InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, InstructionOperand* b,
size_t temp_count = 0, InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, InstructionOperand* b,
InstructionOperand* c, size_t temp_count = 0,
InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, InstructionOperand* b,
InstructionOperand* c, InstructionOperand* d,
size_t temp_count = 0, InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, InstructionOperand* b,
InstructionOperand* c, InstructionOperand* d,
InstructionOperand* e, size_t temp_count = 0,
InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
InstructionOperand* a, InstructionOperand* b,
InstructionOperand* c, InstructionOperand* d,
InstructionOperand* e, InstructionOperand* f,
size_t temp_count = 0, InstructionOperand* *temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, size_t temp_count = 0,
InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b,
size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b,
InstructionOperand c, size_t temp_count = 0,
InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b,
InstructionOperand c, InstructionOperand d,
size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b,
InstructionOperand c, InstructionOperand d,
InstructionOperand e, size_t temp_count = 0,
InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, InstructionOperand output,
InstructionOperand a, InstructionOperand b,
InstructionOperand c, InstructionOperand d,
InstructionOperand e, InstructionOperand f,
size_t temp_count = 0, InstructionOperand* temps = NULL);
Instruction* Emit(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count = 0,
InstructionOperand* *temps = NULL);
InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, size_t temp_count = 0,
InstructionOperand* temps = NULL);
Instruction* Emit(Instruction* instr);
// ===========================================================================
......@@ -154,7 +157,7 @@ class InstructionSelector FINAL {
// Inform the register allocation of the representation of the unallocated
// operand {op}.
void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
void MarkAsRepresentation(MachineType rep, const InstructionOperand& op);
// Initialize the call buffer with the InstructionOperands, nodes, etc,
// corresponding
......
......@@ -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)
: opcode_(opcode),
bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
......@@ -138,9 +128,9 @@ Instruction::Instruction(InstructionCode opcode)
Instruction::Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count,
InstructionOperand** temps)
InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, size_t temp_count,
InstructionOperand* temps)
: opcode_(opcode),
bit_field_(OutputCountField::encode(output_count) |
InputCountField::encode(input_count) |
......@@ -149,13 +139,16 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count,
pointer_map_(NULL) {
size_t offset = 0;
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) {
SetOperand(&operands_[offset++], inputs[i]);
DCHECK(!inputs[i].IsInvalid());
operands_[offset++] = inputs[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;
V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
class InstructionOperand : public ZoneObject {
class InstructionOperand {
public:
static const int kInvalidVirtualRegister = -1;
......@@ -50,6 +50,10 @@ class InstructionOperand : public ZoneObject {
DOUBLE_REGISTER
};
InstructionOperand() : virtual_register_(kInvalidVirtualRegister) {
ConvertTo(INVALID, 0);
}
InstructionOperand(Kind kind, int index)
: virtual_register_(kInvalidVirtualRegister) {
DCHECK(kind != INVALID);
......@@ -62,6 +66,7 @@ class InstructionOperand : public ZoneObject {
bool Is##name() const { return kind() == type; }
INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID, 0)
#undef INSTRUCTION_OPERAND_PREDICATE
bool Equals(const InstructionOperand* other) const {
return value_ == other->value_;
......@@ -79,6 +84,12 @@ class InstructionOperand : public ZoneObject {
static void SetUpCaches();
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:
InstructionOperand(Kind kind, int index, int virtual_register)
: virtual_register_(virtual_register) {
......@@ -91,8 +102,6 @@ class InstructionOperand : public ZoneObject {
int32_t virtual_register_;
};
typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
struct PrintableInstructionOperand {
const RegisterConfiguration* register_configuration_;
const InstructionOperand* op_;
......@@ -131,10 +140,6 @@ class UnallocatedOperand : public InstructionOperand {
// TODO(dcarney): remove this.
static const int kInvalidVirtualRegister = -1;
// This is only for array initialization.
UnallocatedOperand()
: InstructionOperand(INVALID, 0, kInvalidVirtualRegister) {}
UnallocatedOperand(ExtendedPolicy policy, int virtual_register)
: InstructionOperand(UNALLOCATED, 0, virtual_register) {
value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
......@@ -181,6 +186,11 @@ class UnallocatedOperand : public InstructionOperand {
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
// that is
// 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);
template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
class SubKindOperand FINAL : public InstructionOperand {
public:
explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {}
static SubKindOperand* Create(int index, Zone* zone) {
DCHECK(index >= 0);
if (index < kNumCachedOperands) return &cache[index];
......@@ -357,6 +370,11 @@ class SubKindOperand FINAL : public InstructionOperand {
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 TearDownCache();
......@@ -364,8 +382,6 @@ class SubKindOperand FINAL : public InstructionOperand {
static SubKindOperand* cache;
SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches.
explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {}
};
......@@ -492,9 +508,9 @@ class Instruction : public ZoneObject {
}
static Instruction* New(Zone* zone, InstructionCode opcode,
size_t output_count, InstructionOperand** outputs,
size_t input_count, InstructionOperand** inputs,
size_t temp_count, InstructionOperand** temps) {
size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand* inputs,
size_t temp_count, InstructionOperand* temps) {
DCHECK(opcode >= 0);
DCHECK(output_count == 0 || outputs != NULL);
DCHECK(input_count == 0 || inputs != NULL);
......@@ -502,8 +518,8 @@ class Instruction : public ZoneObject {
size_t total_extra_ops = output_count + input_count + temp_count;
if (total_extra_ops != 0) total_extra_ops--;
int size = static_cast<int>(
RoundUp(sizeof(Instruction), sizeof(UnallocatedOperand)) +
total_extra_ops * sizeof(UnallocatedOperand));
RoundUp(sizeof(Instruction), sizeof(InstructionOperand)) +
total_extra_ops * sizeof(InstructionOperand));
return new (zone->New(size)) Instruction(
opcode, output_count, outputs, input_count, inputs, temp_count, temps);
}
......@@ -559,9 +575,9 @@ class Instruction : public ZoneObject {
protected:
explicit Instruction(InstructionCode opcode);
Instruction(InstructionCode opcode, size_t output_count,
InstructionOperand** outputs, size_t input_count,
InstructionOperand** inputs, size_t temp_count,
InstructionOperand** temps);
InstructionOperand* outputs, size_t input_count,
InstructionOperand* inputs, size_t temp_count,
InstructionOperand* temps);
protected:
typedef BitField<size_t, 0, 8> OutputCountField;
......@@ -573,7 +589,7 @@ class Instruction : public ZoneObject {
InstructionCode opcode_;
uint32_t bit_field_;
PointerMap* pointer_map_;
UnallocatedOperand operands_[1];
InstructionOperand operands_[1];
};
......
......@@ -23,7 +23,7 @@ class MipsOperandGenerator FINAL : public OperandGenerator {
explicit MipsOperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) {
return UseImmediate(node);
}
......@@ -91,9 +91,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont) {
MipsOperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
inputs[input_count++] = g.UseRegister(m.left().node());
......@@ -162,7 +162,7 @@ void InstructionSelector::VisitLoad(Node* node) {
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
} else {
InstructionOperand* addr_reg = g.TempRegister();
InstructionOperand addr_reg = g.TempRegister();
Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base));
// Emit desired load opcode, using temp addr_reg.
......@@ -185,8 +185,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMipsStoreWriteBarrier, NULL, g.UseFixed(base, t0),
InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMipsStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0),
g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
return;
}
......@@ -217,15 +217,15 @@ void InstructionSelector::VisitStore(Node* node) {
}
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));
} else {
InstructionOperand* addr_reg = g.TempRegister();
InstructionOperand addr_reg = g.TempRegister();
Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base));
// Emit desired store opcode, using temp addr_reg.
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
g.TempImmediate(0), g.UseRegister(value));
Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
addr_reg, g.TempImmediate(0), g.UseRegister(value));
}
}
......@@ -290,7 +290,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
......@@ -299,7 +299,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1)));
......@@ -466,12 +466,12 @@ void InstructionSelector::VisitCall(Node* node) {
// Possibly align stack here for functions.
int push_count = buffer.pushed_nodes.size();
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;
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) {
Emit(kMipsStoreToStackSlot | MiscField::encode(slot), nullptr,
Emit(kMipsStoreToStackSlot | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(*i));
slot--;
}
......@@ -493,7 +493,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction.
InstructionOperand** first_output =
InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output,
......@@ -530,15 +530,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), offset_operand, length_operand,
......@@ -574,18 +574,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
length_operand, g.UseRegister(value), g.UseRegister(buffer));
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
offset_operand, length_operand, g.UseRegister(value),
g.UseRegister(buffer));
}
......@@ -593,12 +594,13 @@ namespace {
// Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right,
InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) {
MipsOperandGenerator g(selector);
opcode = cont->Encode(opcode);
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();
} else {
DCHECK(cont->IsSet());
......@@ -725,9 +727,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
// Continuation could not be combined with a compare, emit compare against 0.
MipsOperandGenerator g(selector);
InstructionCode const opcode = cont->Encode(kMipsCmp);
InstructionOperand* const value_operand = g.UseRegister(value);
InstructionOperand const value_operand = g.UseRegister(value);
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->false_block()))->MarkAsControl();
} else {
......
......@@ -23,7 +23,7 @@ class Mips64OperandGenerator FINAL : public OperandGenerator {
explicit Mips64OperandGenerator(InstructionSelector* selector)
: OperandGenerator(selector) {}
InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
if (CanBeImmediate(node, opcode)) {
return UseImmediate(node);
}
......@@ -124,9 +124,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont) {
Mips64OperandGenerator g(selector);
Int32BinopMatcher m(node);
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
inputs[input_count++] = g.UseRegister(m.left().node());
......@@ -198,7 +198,7 @@ void InstructionSelector::VisitLoad(Node* node) {
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
} else {
InstructionOperand* addr_reg = g.TempRegister();
InstructionOperand addr_reg = g.TempRegister();
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base));
// Emit desired load opcode, using temp addr_reg.
......@@ -221,8 +221,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0),
InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
Emit(kMips64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0),
g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
return;
}
......@@ -256,15 +256,15 @@ void InstructionSelector::VisitStore(Node* node) {
}
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));
} else {
InstructionOperand* addr_reg = g.TempRegister();
InstructionOperand addr_reg = g.TempRegister();
Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base));
// Emit desired store opcode, using temp addr_reg.
Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
g.TempImmediate(0), g.UseRegister(value));
Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
addr_reg, g.TempImmediate(0), g.UseRegister(value));
}
}
......@@ -375,7 +375,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
......@@ -384,7 +384,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1)));
......@@ -407,7 +407,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) {
void InstructionSelector::VisitUint32MulHigh(Node* node) {
Mips64OperandGenerator g(this);
InstructionOperand* const dmul_operand = g.TempRegister();
InstructionOperand const dmul_operand = g.TempRegister();
Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)));
Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0),
......@@ -428,7 +428,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value - 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
......@@ -437,7 +437,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
return;
}
if (base::bits::IsPowerOfTwo32(value + 1)) {
InstructionOperand* temp = g.TempRegister();
InstructionOperand temp = g.TempRegister();
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value + 1)));
......@@ -646,12 +646,12 @@ void InstructionSelector::VisitCall(Node* node) {
int push_count = buffer.pushed_nodes.size();
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;
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) {
Emit(kMips64StoreToStackSlot | MiscField::encode(slot), nullptr,
Emit(kMips64StoreToStackSlot | MiscField::encode(slot), g.NoOutput(),
g.UseRegister(*i));
slot--;
}
......@@ -709,15 +709,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), offset_operand, length_operand,
......@@ -753,18 +753,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
length_operand, g.UseRegister(value), g.UseRegister(buffer));
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
offset_operand, length_operand, g.UseRegister(value),
g.UseRegister(buffer));
}
......@@ -772,12 +773,13 @@ namespace {
// Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right,
InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) {
Mips64OperandGenerator g(selector);
opcode = cont->Encode(opcode);
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();
} else {
DCHECK(cont->IsSet());
......@@ -838,9 +840,9 @@ void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode,
Node* value, FlagsContinuation* cont) {
Mips64OperandGenerator g(selector);
opcode = cont->Encode(opcode);
InstructionOperand* const value_operand = g.UseRegister(value);
InstructionOperand const value_operand = g.UseRegister(value);
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->false_block()))->MarkAsControl();
} else {
......
......@@ -31,7 +31,7 @@ class X64OperandGenerator FINAL : public OperandGenerator {
AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
Node* base, Node* displacement,
InstructionOperand* inputs[],
InstructionOperand inputs[],
size_t* input_count) {
AddressingMode mode = kMode_MRI;
if (base != NULL) {
......@@ -80,7 +80,7 @@ class X64OperandGenerator FINAL : public OperandGenerator {
}
AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
InstructionOperand* inputs[],
InstructionOperand inputs[],
size_t* input_count) {
BaseWithIndexAndDisplacement64Matcher m(operand, true);
DCHECK(m.matches());
......@@ -132,9 +132,9 @@ void InstructionSelector::VisitLoad(Node* node) {
return;
}
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(node);
InstructionOperand* inputs[3];
InstructionOperand inputs[3];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
......@@ -156,8 +156,8 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx),
InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
temps);
return;
......@@ -189,15 +189,15 @@ void InstructionSelector::VisitStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode);
InstructionOperand* value_operand =
InstructionOperand value_operand =
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
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) {
return;
}
}
InstructionOperand* length_operand =
InstructionOperand length_operand =
g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
g.UseRegister(offset), g.TempImmediate(0), length_operand);
......@@ -276,7 +276,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* value_operand =
InstructionOperand value_operand =
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
Int32Matcher mlength(length);
......@@ -284,16 +284,16 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
if (mlength.HasValue() && moffset.right().HasValue() &&
moffset.right().Value() >= 0 &&
mlength.Value() >= moffset.right().Value()) {
Emit(opcode, nullptr, g.UseRegister(buffer),
Emit(opcode, g.NoOutput(), g.UseRegister(buffer),
g.UseRegister(moffset.left().node()),
g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
value_operand);
return;
}
}
InstructionOperand* length_operand =
InstructionOperand length_operand =
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);
}
......@@ -305,9 +305,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
Int32BinopMatcher m(node);
Node* left = m.left().node();
Node* right = m.right().node();
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
InstructionOperand* outputs[2];
InstructionOperand outputs[2];
size_t output_count = 0;
// TODO(turbofan): match complex addressing modes.
......@@ -319,7 +319,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
// mov rax, [rbp-0x10]
// add rax, [rbp-0x10]
// jo label
InstructionOperand* const input = g.UseRegister(left);
InstructionOperand const input = g.UseRegister(left);
inputs[input_count++] = input;
inputs[input_count++] = input;
} else if (g.CanBeImmediate(right)) {
......@@ -456,7 +456,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode,
Node* displacement) {
X64OperandGenerator g(selector);
InstructionOperand* inputs[4];
InstructionOperand inputs[4];
size_t input_count = 0;
AddressingMode mode = g.GenerateMemoryOperandInputs(
index, scale, base, displacement, inputs, &input_count);
......@@ -464,7 +464,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode,
DCHECK_NE(0, static_cast<int>(input_count));
DCHECK_GE(arraysize(inputs), input_count);
InstructionOperand* outputs[1];
InstructionOperand outputs[1];
outputs[0] = g.DefineAsRegister(result);
opcode = AddressingModeField::encode(mode) | opcode;
......@@ -634,7 +634,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node,
void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
X64OperandGenerator g(selector);
InstructionOperand* temps[] = {g.TempRegister(rdx)};
InstructionOperand temps[] = {g.TempRegister(rdx)};
selector->Emit(
opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
......@@ -870,7 +870,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) {
void InstructionSelector::VisitFloat64Mod(Node* node) {
X64OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(rax)};
InstructionOperand temps[] = {g.TempRegister(rax)};
Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
temps);
......@@ -937,11 +937,11 @@ void InstructionSelector::VisitCall(Node* node) {
for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
++i) {
// TODO(titzer): handle pushing double parameters.
InstructionOperand* value =
InstructionOperand value =
g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
? g.UseRegister(*i)
: g.Use(*i);
Emit(kX64Push, nullptr, value);
Emit(kX64Push, g.NoOutput(), value);
}
// Select the appropriate opcode based on the call type.
......@@ -961,7 +961,7 @@ void InstructionSelector::VisitCall(Node* node) {
opcode |= MiscField::encode(descriptor->flags());
// Emit the call instruction.
InstructionOperand** first_output =
InstructionOperand* first_output =
buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
Instruction* call_instr =
Emit(opcode, buffer.outputs.size(), first_output,
......@@ -972,12 +972,13 @@ void InstructionSelector::VisitCall(Node* node) {
// Shared routine for multiple compare operations.
static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
InstructionOperand* left, InstructionOperand* right,
InstructionOperand left, InstructionOperand right,
FlagsContinuation* cont) {
X64OperandGenerator g(selector);
opcode = cont->Encode(opcode);
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();
} else {
DCHECK(cont->IsSet());
......
......@@ -296,35 +296,23 @@ TEST(InstructionOperands) {
}
int vreg = 15;
InstructionOperand* outputs[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand* inputs[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand* temps[] = {
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
new (&zone)
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand outputs[] = {
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand inputs[] = {
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
InstructionOperand temps[] = {
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg),
UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)};
for (size_t i = 0; i < arraysize(outputs); i++) {
for (size_t j = 0; j < arraysize(inputs); j++) {
......@@ -336,15 +324,15 @@ TEST(InstructionOperands) {
CHECK(k == m->TempCount());
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++) {
CHECK(inputs[z]->Equals(m->InputAt(z)));
CHECK(inputs[z].Equals(m->InputAt(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 {
int Jump(int target) {
Start();
InstructionOperand* ops[] = {UseRpo(target)};
InstructionOperand ops[] = {UseRpo(target)};
sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1,
ops, 0, NULL)->MarkAsControl());
int pos = static_cast<int>(sequence_.instructions().size() - 1);
......@@ -44,7 +44,7 @@ class TestCode : public HandleAndZoneScope {
}
int Branch(int ttarget, int ftarget) {
Start();
InstructionOperand* ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
InstructionOperand ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) |
FlagsConditionField::encode(kEqual);
sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2,
......@@ -81,9 +81,9 @@ class TestCode : public HandleAndZoneScope {
current_ = NULL;
rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
}
InstructionOperand* UseRpo(int num) {
InstructionOperand UseRpo(int num) {
int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
return ImmediateOperand::Create(index, main_zone());
return ImmediateOperand(index);
}
void Start(bool deferred = false) {
if (current_ == NULL) {
......
......@@ -138,7 +138,7 @@ InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) {
InstructionSequenceTest::VReg InstructionSequenceTest::Define(
TestOperand output_op) {
VReg vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(vreg, output_op)};
InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)};
Emit(vreg.value_, kArchNop, 1, outputs);
return vreg;
}
......@@ -146,7 +146,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::Define(
int InstructionSequenceTest::Return(TestOperand input_op_0) {
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);
}
......@@ -176,7 +176,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant(
int32_t imm) {
VReg vreg = NewReg();
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);
return vreg;
}
......@@ -196,7 +196,7 @@ static size_t CountInputs(size_t size,
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);
}
......@@ -213,8 +213,8 @@ int InstructionSequenceTest::EmitI(TestOperand input_op_0,
InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
TestOperand output_op, size_t input_size, TestOperand* inputs) {
VReg output_vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)};
InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs);
InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
Emit(output_vreg.value_, kArchNop, 1, outputs, input_size, mapped_inputs);
return output_vreg;
}
......@@ -231,9 +231,9 @@ InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
TestOperand output_op, size_t input_size, TestOperand* inputs) {
VReg output_vreg = NewReg();
InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)};
CHECK(UnallocatedOperand::cast(outputs[0])->HasFixedPolicy());
InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs);
InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy());
InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
Emit(output_vreg.value_, kArchCallCodeObject, 1, outputs, input_size,
mapped_inputs, 0, nullptr, true);
return output_vreg;
......@@ -257,8 +257,8 @@ const Instruction* InstructionSequenceTest::GetInstruction(
int InstructionSequenceTest::EmitBranch(TestOperand input_op) {
InstructionOperand* inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
ConvertInputOp(Imm()), ConvertInputOp(Imm())};
InstructionOperand inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
ConvertInputOp(Imm()), ConvertInputOp(Imm())};
InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) |
FlagsConditionField::encode(kEqual);
auto instruction =
......@@ -274,7 +274,7 @@ int InstructionSequenceTest::EmitFallThrough() {
int InstructionSequenceTest::EmitJump() {
InstructionOperand* inputs[1]{ConvertInputOp(Imm())};
InstructionOperand inputs[1]{ConvertInputOp(Imm())};
auto instruction =
NewInstruction(kArchJmp, 0, nullptr, 1, inputs)->MarkAsControl();
return AddInstruction(NewIndex(), instruction);
......@@ -282,44 +282,44 @@ int InstructionSequenceTest::EmitJump() {
Instruction* InstructionSequenceTest::NewInstruction(
InstructionCode code, size_t outputs_size, InstructionOperand** outputs,
size_t inputs_size, InstructionOperand** inputs, size_t temps_size,
InstructionOperand** temps) {
InstructionCode code, size_t outputs_size, InstructionOperand* outputs,
size_t inputs_size, InstructionOperand* inputs, size_t temps_size,
InstructionOperand* temps) {
CHECK(current_block_);
return Instruction::New(zone(), code, outputs_size, outputs, inputs_size,
inputs, temps_size, temps);
}
InstructionOperand* InstructionSequenceTest::Unallocated(
InstructionOperand InstructionSequenceTest::Unallocated(
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,
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) {
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) {
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) {
InstructionOperand** mapped_inputs =
zone()->NewArray<InstructionOperand*>(static_cast<int>(input_size));
InstructionOperand* mapped_inputs =
zone()->NewArray<InstructionOperand>(static_cast<int>(input_size));
for (size_t i = 0; i < input_size; ++i) {
mapped_inputs[i] = ConvertInputOp(inputs[i]);
}
......@@ -327,10 +327,10 @@ InstructionOperand** InstructionSequenceTest::ConvertInputs(
}
InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) {
InstructionOperand InstructionSequenceTest::ConvertInputOp(TestOperand op) {
if (op.type_ == kImmediate) {
CHECK_EQ(op.vreg_.value_, kNoValue);
return ImmediateOperand::Create(op.value_, zone());
return ImmediateOperand(op.value_);
}
CHECK_NE(op.vreg_.value_, kNoValue);
switch (op.type_) {
......@@ -353,12 +353,12 @@ InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) {
break;
}
CHECK(false);
return NULL;
return InstructionOperand();
}
InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg,
TestOperand op) {
InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg,
TestOperand op) {
CHECK_EQ(op.vreg_.value_, kNoValue);
op.vreg_ = vreg;
switch (op.type_) {
......@@ -375,7 +375,7 @@ InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg,
break;
}
CHECK(false);
return NULL;
return InstructionOperand();
}
......@@ -445,11 +445,10 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
int InstructionSequenceTest::Emit(int instruction_index, InstructionCode code,
size_t outputs_size,
InstructionOperand** outputs,
InstructionOperand* outputs,
size_t inputs_size,
InstructionOperand** inputs,
size_t temps_size, InstructionOperand** temps,
bool is_call) {
InstructionOperand* inputs, size_t temps_size,
InstructionOperand* temps, bool is_call) {
auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size,
inputs, temps_size, temps);
if (is_call) instruction->MarkAsCall();
......
......@@ -179,32 +179,32 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
int EmitFallThrough();
int EmitJump();
Instruction* NewInstruction(InstructionCode code, size_t outputs_size,
InstructionOperand** outputs,
InstructionOperand* outputs,
size_t inputs_size = 0,
InstructionOperand* *inputs = nullptr,
InstructionOperand* inputs = nullptr,
size_t temps_size = 0,
InstructionOperand* *temps = nullptr);
InstructionOperand* Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy);
InstructionOperand* Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
UnallocatedOperand::Lifetime lifetime);
InstructionOperand* Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
int index);
InstructionOperand* Unallocated(TestOperand op,
UnallocatedOperand::BasicPolicy policy,
int index);
InstructionOperand** ConvertInputs(size_t input_size, TestOperand* inputs);
InstructionOperand* ConvertInputOp(TestOperand op);
InstructionOperand* ConvertOutputOp(VReg vreg, TestOperand op);
InstructionOperand* temps = nullptr);
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy);
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
UnallocatedOperand::Lifetime lifetime);
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
int index);
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::BasicPolicy policy,
int index);
InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs);
InstructionOperand ConvertInputOp(TestOperand op);
InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op);
InstructionBlock* NewBlock();
void WireBlock(size_t block_offset, int jump_offset);
int Emit(int instruction_index, InstructionCode code, size_t outputs_size = 0,
InstructionOperand* *outputs = nullptr, size_t inputs_size = 0,
InstructionOperand* *inputs = nullptr, size_t temps_size = 0,
InstructionOperand* *temps = nullptr, bool is_call = false);
InstructionOperand* outputs = nullptr, size_t inputs_size = 0,
InstructionOperand* inputs = nullptr, size_t temps_size = 0,
InstructionOperand* temps = nullptr, bool is_call = false);
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