[arm] Remove code duplication in instruction selector. Refactoring.
TEST=unittests R=dcarney@chromium.org Review URL: https://codereview.chromium.org/719713002 Cr-Commit-Position: refs/heads/master@{#25292} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25292 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
eacdfa0b7a
commit
2c811498a2
@ -16,13 +16,6 @@ class ArmOperandGenerator : public OperandGenerator {
|
||||
explicit ArmOperandGenerator(InstructionSelector* selector)
|
||||
: OperandGenerator(selector) {}
|
||||
|
||||
InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
|
||||
if (CanBeImmediate(node, opcode)) {
|
||||
return UseImmediate(node);
|
||||
}
|
||||
return UseRegister(node);
|
||||
}
|
||||
|
||||
bool CanBeImmediate(int32_t value) const {
|
||||
return Assembler::ImmediateFitsAddrMode1Instruction(value);
|
||||
}
|
||||
@ -74,70 +67,26 @@ class ArmOperandGenerator : public OperandGenerator {
|
||||
case kArmStrh:
|
||||
return value >= -255 && value <= 255;
|
||||
|
||||
case kArchCallCodeObject:
|
||||
case kArchCallJSFunction:
|
||||
case kArchJmp:
|
||||
case kArchNop:
|
||||
case kArchRet:
|
||||
case kArchStackPointer:
|
||||
case kArchTruncateDoubleToI:
|
||||
case kArmMul:
|
||||
case kArmMla:
|
||||
case kArmMls:
|
||||
case kArmSmmul:
|
||||
case kArmSmmla:
|
||||
case kArmUmull:
|
||||
case kArmSdiv:
|
||||
case kArmUdiv:
|
||||
case kArmBfc:
|
||||
case kArmUbfx:
|
||||
case kArmSxtb:
|
||||
case kArmSxth:
|
||||
case kArmSxtab:
|
||||
case kArmSxtah:
|
||||
case kArmUxtb:
|
||||
case kArmUxth:
|
||||
case kArmUxtab:
|
||||
case kArmUxtah:
|
||||
case kArmVcmpF64:
|
||||
case kArmVaddF64:
|
||||
case kArmVsubF64:
|
||||
case kArmVmulF64:
|
||||
case kArmVmlaF64:
|
||||
case kArmVmlsF64:
|
||||
case kArmVdivF64:
|
||||
case kArmVmodF64:
|
||||
case kArmVnegF64:
|
||||
case kArmVsqrtF64:
|
||||
case kArmVfloorF64:
|
||||
case kArmVceilF64:
|
||||
case kArmVroundTruncateF64:
|
||||
case kArmVroundTiesAwayF64:
|
||||
case kArmVcvtF32F64:
|
||||
case kArmVcvtF64F32:
|
||||
case kArmVcvtF64S32:
|
||||
case kArmVcvtF64U32:
|
||||
case kArmVcvtS32F64:
|
||||
case kArmVcvtU32F64:
|
||||
case kArmPush:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
Node* node) {
|
||||
namespace {
|
||||
|
||||
void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
Node* node) {
|
||||
ArmOperandGenerator g(selector);
|
||||
selector->Emit(opcode, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)));
|
||||
}
|
||||
|
||||
|
||||
static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
Node* node) {
|
||||
void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
Node* node) {
|
||||
ArmOperandGenerator g(selector);
|
||||
selector->Emit(opcode, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)),
|
||||
@ -145,86 +94,69 @@ static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
}
|
||||
|
||||
|
||||
static bool TryMatchROR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
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) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Ror) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(1, 31)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
if (node->opcode() == kOpcode) {
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(kImmMin, kImmMax)) {
|
||||
*opcode_return |= AddressingModeField::encode(kImmMode);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kRegMode);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchASR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Sar) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_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);
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchLSL(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Shl) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(0, 31)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_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);
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchLSR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Shr) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_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);
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchShift(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_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);
|
||||
}
|
||||
|
||||
|
||||
bool TryMatchShift(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
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) ||
|
||||
@ -233,11 +165,10 @@ static inline bool TryMatchShift(InstructionSelector* selector,
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchImmediateOrShift(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return,
|
||||
Node* node,
|
||||
size_t* input_count_return,
|
||||
InstructionOperand** inputs) {
|
||||
bool TryMatchImmediateOrShift(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
size_t* input_count_return,
|
||||
InstructionOperand** inputs) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (g.CanBeImmediate(node, *opcode_return)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_I);
|
||||
@ -253,9 +184,9 @@ static inline bool TryMatchImmediateOrShift(InstructionSelector* selector,
|
||||
}
|
||||
|
||||
|
||||
static void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
InstructionCode opcode, InstructionCode reverse_opcode,
|
||||
FlagsContinuation* cont) {
|
||||
void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
InstructionCode opcode, InstructionCode reverse_opcode,
|
||||
FlagsContinuation* cont) {
|
||||
ArmOperandGenerator g(selector);
|
||||
Int32BinopMatcher m(node);
|
||||
InstructionOperand* inputs[5];
|
||||
@ -313,13 +244,16 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
}
|
||||
|
||||
|
||||
static void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
InstructionCode opcode, InstructionCode reverse_opcode) {
|
||||
void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
InstructionCode opcode, InstructionCode reverse_opcode) {
|
||||
FlagsContinuation cont;
|
||||
VisitBinop(selector, node, opcode, reverse_opcode, &cont);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void InstructionSelector::VisitLoad(Node* node) {
|
||||
MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
|
||||
MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
|
||||
@ -416,8 +350,10 @@ void InstructionSelector::VisitStore(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
static inline void EmitBic(InstructionSelector* selector, Node* node,
|
||||
Node* left, Node* right) {
|
||||
namespace {
|
||||
|
||||
void EmitBic(InstructionSelector* selector, Node* node, Node* left,
|
||||
Node* right) {
|
||||
ArmOperandGenerator g(selector);
|
||||
InstructionCode opcode = kArmBic;
|
||||
InstructionOperand* value_operand;
|
||||
@ -432,6 +368,8 @@ static inline void EmitBic(InstructionSelector* selector, Node* node,
|
||||
g.UseRegister(right));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void InstructionSelector::VisitWord32And(Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
|
Loading…
Reference in New Issue
Block a user