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

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

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26424}
parent 275e088a
......@@ -30,7 +30,7 @@ class Arm64OperandGenerator FINAL : public OperandGenerator {
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 {
......
This diff is collapsed.
This diff is collapsed.
......@@ -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,12 +530,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
......@@ -574,18 +574,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
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));
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,12 +709,12 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
......@@ -753,18 +753,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
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));
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,34 +296,22 @@ TEST(InstructionOperands) {
}
int vreg = 15;
InstructionOperand* outputs[] = {
new (&zone)
InstructionOperand outputs[] = {
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)
InstructionOperand inputs[] = {
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)
InstructionOperand temps[] = {
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)};
for (size_t i = 0; i < arraysize(outputs); i++) {
......@@ -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,7 +257,7 @@ const Instruction* InstructionSequenceTest::GetInstruction(
int InstructionSequenceTest::EmitBranch(TestOperand input_op) {
InstructionOperand* inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
InstructionOperand inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
ConvertInputOp(Imm()), ConvertInputOp(Imm())};
InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) |
FlagsConditionField::encode(kEqual);
......@@ -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,11 +353,11 @@ InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) {
break;
}
CHECK(false);
return NULL;
return InstructionOperand();
}
InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg,
InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg,
TestOperand op) {
CHECK_EQ(op.vreg_.value_, kNoValue);
op.vreg_ = vreg;
......@@ -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,
InstructionOperand* temps = nullptr);
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy);
InstructionOperand* Unallocated(TestOperand op,
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
UnallocatedOperand::Lifetime lifetime);
InstructionOperand* Unallocated(TestOperand op,
InstructionOperand Unallocated(TestOperand op,
UnallocatedOperand::ExtendedPolicy policy,
int index);
InstructionOperand* Unallocated(TestOperand op,
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* 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