Commit d062f73a by Jan Voung

Add a basic enum for ARM InstructionSet / cpu features.

That way, we don't have to use -mattr=sse2 for ARM in cross tests, etc. Default to NEON for now. Also put in an entry for HW divide in ARM mode. There's bunches of features that are possible though, e.g.,: https://github.com/llvm-mirror/llvm/blob/master/lib/Target/ARM/ARM.td BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1191573003.
parent 58eea4d1
......@@ -142,11 +142,17 @@ cl::opt<Ice::TargetArch> TargetArch(
clEnumValEnd));
cl::opt<Ice::TargetInstructionSet> TargetInstructionSet(
"mattr", cl::desc("Target architecture attributes"),
cl::init(Ice::X86InstructionSet_SSE2),
cl::values(clEnumValN(Ice::X86InstructionSet_SSE2, "sse2",
"Enable SSE2 instructions (default)"),
cl::init(Ice::BaseInstructionSet),
cl::values(clEnumValN(Ice::BaseInstructionSet, "base",
"Target chooses baseline instruction set (default)"),
clEnumValN(Ice::X86InstructionSet_SSE2, "sse2",
"Enable X86 SSE2 instructions"),
clEnumValN(Ice::X86InstructionSet_SSE4_1, "sse4.1",
"Enable SSE 4.1 instructions"),
"Enable X86 SSE 4.1 instructions"),
clEnumValN(Ice::ARM32InstructionSet_Neon, "neon",
"Enable ARM Neon instructions"),
clEnumValN(Ice::ARM32InstructionSet_HWDivArm, "hwdiv-arm",
"Enable ARM integer divide instructions in ARM mode"),
clEnumValEnd));
cl::opt<std::string>
TestPrefix("prefix",
......
......@@ -135,8 +135,21 @@ uint32_t applyStackAlignment(uint32_t Value) {
} // end of anonymous namespace
TargetARM32::TargetARM32(Cfg *Func)
: TargetLowering(Func), UsesFramePointer(false), NeedsStackAlignment(false),
MaybeLeafFunc(true), SpillAreaSizeBytes(0) {
: TargetLowering(Func), InstructionSet(ARM32InstructionSet::Begin),
UsesFramePointer(false), NeedsStackAlignment(false), MaybeLeafFunc(true),
SpillAreaSizeBytes(0) {
static_assert(
(ARM32InstructionSet::End - ARM32InstructionSet::Begin) ==
(TargetInstructionSet::ARM32InstructionSet_End -
TargetInstructionSet::ARM32InstructionSet_Begin),
"ARM32InstructionSet range different from TargetInstructionSet");
if (Func->getContext()->getFlags().getTargetInstructionSet() !=
TargetInstructionSet::BaseInstructionSet) {
InstructionSet = static_cast<ARM32InstructionSet>(
(Func->getContext()->getFlags().getTargetInstructionSet() -
TargetInstructionSet::ARM32InstructionSet_Begin) +
ARM32InstructionSet::Begin);
}
// TODO: Don't initialize IntegerRegisters and friends every time.
// Instead, initialize in some sort of static initializer for the
// class.
......
......@@ -75,6 +75,16 @@ public:
void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
size_t BasicFrameOffset, size_t &InArgsSizeBytes);
enum ARM32InstructionSet {
Begin,
// Neon is the PNaCl baseline instruction set.
Neon = Begin,
HWDivArm, // HW divide in ARM mode (not just Thumb mode).
End
};
ARM32InstructionSet getInstructionSet() const { return InstructionSet; }
protected:
explicit TargetARM32(Cfg *Func);
......@@ -288,6 +298,7 @@ protected:
Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred));
}
ARM32InstructionSet InstructionSet;
bool UsesFramePointer;
bool NeedsStackAlignment;
bool MaybeLeafFunc;
......
......@@ -395,16 +395,20 @@ void TargetX8632::initNodeForLowering(CfgNode *Node) {
}
TargetX8632::TargetX8632(Cfg *Func)
: TargetLowering(Func),
InstructionSet(static_cast<X86InstructionSet>(
Func->getContext()->getFlags().getTargetInstructionSet() -
TargetInstructionSet::X86InstructionSet_Begin)),
: TargetLowering(Func), InstructionSet(X86InstructionSet::Begin),
IsEbpBasedFrame(false), NeedsStackAlignment(false),
SpillAreaSizeBytes(0) {
static_assert((X86InstructionSet::End - X86InstructionSet::Begin) ==
(TargetInstructionSet::X86InstructionSet_End -
TargetInstructionSet::X86InstructionSet_Begin),
"X86InstructionSet range different from TargetInstructionSet");
if (Func->getContext()->getFlags().getTargetInstructionSet() !=
TargetInstructionSet::BaseInstructionSet) {
InstructionSet = static_cast<X86InstructionSet>(
(Func->getContext()->getFlags().getTargetInstructionSet() -
TargetInstructionSet::X86InstructionSet_Begin) +
X86InstructionSet::Begin);
}
// TODO: Don't initialize IntegerRegisters and friends every time.
// Instead, initialize in some sort of static initializer for the
// class.
......
......@@ -562,7 +562,7 @@ protected:
bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1);
const X86InstructionSet InstructionSet;
X86InstructionSet InstructionSet;
bool IsEbpBasedFrame;
bool NeedsStackAlignment;
size_t SpillAreaSizeBytes;
......
......@@ -43,11 +43,16 @@ inline Ostream &operator<<(Ostream &Stream, TargetArch Arch) {
// The list of all target instruction sets. Individual targets will
// map this to include only what is valid for the target.
enum TargetInstructionSet {
// Represents baseline that can be assumed for a target (usually "Begin").
BaseInstructionSet,
X86InstructionSet_Begin,
// SSE2 is the PNaCl baseline instruction set.
X86InstructionSet_SSE2 = X86InstructionSet_Begin,
X86InstructionSet_SSE4_1,
X86InstructionSet_End,
ARM32InstructionSet_Begin,
ARM32InstructionSet_Neon = ARM32InstructionSet_Begin,
ARM32InstructionSet_HWDivArm,
ARM32InstructionSet_End,
};
enum OptLevel { Opt_m1, Opt_0, Opt_1, Opt_2 };
......
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