Skip to content

Commit

Permalink
[X86] Introduction of FeatureX87.
Browse files Browse the repository at this point in the history
Add FeatureX87 in X86 backend to be able to define CPUs which doesn't have x87.

Differential Revision: http://reviews.llvm.org/D13979

llvm-svn: 264148
  • Loading branch information
aturetsk committed Mar 23, 2016
1 parent c45baf2 commit 6a3d561
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 69 deletions.
155 changes: 89 additions & 66 deletions llvm/lib/Target/X86/X86.td
Expand Up @@ -31,6 +31,9 @@ def Mode16Bit : SubtargetFeature<"16bit-mode", "In16BitMode", "true",
// X86 Subtarget features
//===----------------------------------------------------------------------===//

def FeatureX87 : SubtargetFeature<"x87","HasX87", "true",
"Enable X87 float instructions">;

def FeatureCMOV : SubtargetFeature<"cmov","HasCMov", "true",
"Enable conditional move instructions">;

Expand Down Expand Up @@ -259,37 +262,38 @@ def ProcIntelSLM : SubtargetFeature<"slm", "X86ProcFamily", "IntelSLM",
class Proc<string Name, list<SubtargetFeature> Features>
: ProcessorModel<Name, GenericModel, Features>;

def : Proc<"generic", [FeatureSlowUAMem16]>;
def : Proc<"i386", [FeatureSlowUAMem16]>;
def : Proc<"i486", [FeatureSlowUAMem16]>;
def : Proc<"i586", [FeatureSlowUAMem16]>;
def : Proc<"pentium", [FeatureSlowUAMem16]>;
def : Proc<"pentium-mmx", [FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"i686", [FeatureSlowUAMem16]>;
def : Proc<"pentiumpro", [FeatureSlowUAMem16, FeatureCMOV]>;
def : Proc<"pentium2", [FeatureSlowUAMem16, FeatureMMX, FeatureCMOV,
FeatureFXSR]>;
def : Proc<"pentium3", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE1,
FeatureFXSR]>;
def : Proc<"pentium3m", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE1,
FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"pentium-m", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE2,
FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"pentium4", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE2,
FeatureFXSR]>;
def : Proc<"pentium4m", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE2,
FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"generic", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"i386", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"i486", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"i586", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"pentium", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"pentium-mmx", [FeatureX87, FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"i686", [FeatureX87, FeatureSlowUAMem16]>;
def : Proc<"pentiumpro", [FeatureX87, FeatureSlowUAMem16, FeatureCMOV]>;
def : Proc<"pentium2", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureCMOV, FeatureFXSR]>;
def : Proc<"pentium3", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE1, FeatureFXSR]>;
def : Proc<"pentium3m", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE1, FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"pentium-m", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE2, FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"pentium4", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE2, FeatureFXSR]>;
def : Proc<"pentium4m", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE2, FeatureFXSR, FeatureSlowBTMem]>;

// Intel Core Duo.
def : ProcessorModel<"yonah", SandyBridgeModel,
[FeatureSlowUAMem16, FeatureMMX, FeatureSSE3, FeatureFXSR,
FeatureSlowBTMem]>;
[FeatureX87, FeatureSlowUAMem16, FeatureMMX, FeatureSSE3,
FeatureFXSR, FeatureSlowBTMem]>;

// NetBurst.
def : Proc<"prescott",
[FeatureSlowUAMem16, FeatureMMX, FeatureSSE3, FeatureFXSR,
FeatureSlowBTMem]>;
[FeatureX87, FeatureSlowUAMem16, FeatureMMX, FeatureSSE3,
FeatureFXSR, FeatureSlowBTMem]>;
def : Proc<"nocona", [
FeatureX87,
FeatureSlowUAMem16,
FeatureMMX,
FeatureSSE3,
Expand All @@ -300,6 +304,7 @@ def : Proc<"nocona", [

// Intel Core 2 Solo/Duo.
def : ProcessorModel<"core2", SandyBridgeModel, [
FeatureX87,
FeatureSlowUAMem16,
FeatureMMX,
FeatureSSSE3,
Expand All @@ -309,6 +314,7 @@ def : ProcessorModel<"core2", SandyBridgeModel, [
FeatureLAHFSAHF
]>;
def : ProcessorModel<"penryn", SandyBridgeModel, [
FeatureX87,
FeatureSlowUAMem16,
FeatureMMX,
FeatureSSE41,
Expand All @@ -321,6 +327,7 @@ def : ProcessorModel<"penryn", SandyBridgeModel, [
// Atom CPUs.
class BonnellProc<string Name> : ProcessorModel<Name, AtomModel, [
ProcIntelAtom,
FeatureX87,
FeatureSlowUAMem16,
FeatureMMX,
FeatureSSSE3,
Expand All @@ -341,6 +348,7 @@ def : BonnellProc<"atom">; // Pin the generic name to the baseline.

class SilvermontProc<string Name> : ProcessorModel<Name, SLMModel, [
ProcIntelSLM,
FeatureX87,
FeatureMMX,
FeatureSSE42,
FeatureFXSR,
Expand All @@ -362,6 +370,7 @@ def : SilvermontProc<"slm">; // Legacy alias.

// "Arrandale" along with corei3 and corei5
class NehalemProc<string Name> : ProcessorModel<Name, SandyBridgeModel, [
FeatureX87,
FeatureMMX,
FeatureSSE42,
FeatureFXSR,
Expand All @@ -376,6 +385,7 @@ def : NehalemProc<"corei7">;
// Westmere is a similar machine to nehalem with some additional features.
// Westmere is the corei3/i5/i7 path from nehalem to sandybridge
class WestmereProc<string Name> : ProcessorModel<Name, SandyBridgeModel, [
FeatureX87,
FeatureMMX,
FeatureSSE42,
FeatureFXSR,
Expand All @@ -401,6 +411,7 @@ class ProcModel<string Name, SchedMachineModel Model,
// SSE is not listed here since llvm treats AVX as a reimplementation of SSE,
// rather than a superset.
def SNBFeatures : ProcessorFeatures<[], [
FeatureX87,
FeatureMMX,
FeatureAVX,
FeatureFXSR,
Expand Down Expand Up @@ -523,49 +534,55 @@ def : CannonlakeProc<"cannonlake">;

// AMD CPUs.

def : Proc<"k6", [FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"k6-2", [FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"k6-3", [FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"athlon", [FeatureSlowUAMem16, Feature3DNowA,
def : Proc<"k6", [FeatureX87, FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"k6-2", [FeatureX87, FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"k6-3", [FeatureX87, FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"athlon", [FeatureX87, FeatureSlowUAMem16, Feature3DNowA,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon-tbird", [FeatureSlowUAMem16, Feature3DNowA,
def : Proc<"athlon-tbird", [FeatureX87, FeatureSlowUAMem16, Feature3DNowA,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon-4", [FeatureSlowUAMem16, FeatureSSE1, Feature3DNowA,
FeatureFXSR, FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon-xp", [FeatureSlowUAMem16, FeatureSSE1, Feature3DNowA,
FeatureFXSR, FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon-mp", [FeatureSlowUAMem16, FeatureSSE1, Feature3DNowA,
FeatureFXSR, FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"k8", [FeatureSlowUAMem16, FeatureSSE2, Feature3DNowA,
FeatureFXSR, Feature64Bit, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"opteron", [FeatureSlowUAMem16, FeatureSSE2, Feature3DNowA,
FeatureFXSR, Feature64Bit, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"athlon64", [FeatureSlowUAMem16, FeatureSSE2, Feature3DNowA,
FeatureFXSR, Feature64Bit, FeatureSlowBTMem,
def : Proc<"athlon-4", [FeatureX87, FeatureSlowUAMem16, FeatureSSE1,
Feature3DNowA, FeatureFXSR, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"athlon-fx", [FeatureSlowUAMem16, FeatureSSE2, Feature3DNowA,
FeatureFXSR, Feature64Bit, FeatureSlowBTMem,
def : Proc<"athlon-xp", [FeatureX87, FeatureSlowUAMem16, FeatureSSE1,
Feature3DNowA, FeatureFXSR, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"k8-sse3", [FeatureSlowUAMem16, FeatureSSE3, Feature3DNowA,
FeatureFXSR, FeatureCMPXCHG16B, FeatureSlowBTMem,
def : Proc<"athlon-mp", [FeatureX87, FeatureSlowUAMem16, FeatureSSE1,
Feature3DNowA, FeatureFXSR, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"opteron-sse3", [FeatureSlowUAMem16, FeatureSSE3, Feature3DNowA,
FeatureFXSR, FeatureCMPXCHG16B, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"athlon64-sse3", [FeatureSlowUAMem16, FeatureSSE3, Feature3DNowA,
FeatureFXSR, FeatureCMPXCHG16B, FeatureSlowBTMem,
FeatureSlowSHLD]>;
def : Proc<"amdfam10", [FeatureSSE4A, Feature3DNowA, FeatureFXSR,
FeatureCMPXCHG16B, FeatureLZCNT, FeaturePOPCNT,
FeatureSlowBTMem, FeatureSlowSHLD, FeatureLAHFSAHF]>;
def : Proc<"barcelona", [FeatureSSE4A, Feature3DNowA, FeatureFXSR,
FeatureCMPXCHG16B, FeatureLZCNT, FeaturePOPCNT,
FeatureSlowBTMem, FeatureSlowSHLD, FeatureLAHFSAHF]>;
def : Proc<"k8", [FeatureX87, FeatureSlowUAMem16, FeatureSSE2,
Feature3DNowA, FeatureFXSR, Feature64Bit,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"opteron", [FeatureX87, FeatureSlowUAMem16, FeatureSSE2,
Feature3DNowA, FeatureFXSR, Feature64Bit,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon64", [FeatureX87, FeatureSlowUAMem16, FeatureSSE2,
Feature3DNowA, FeatureFXSR, Feature64Bit,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon-fx", [FeatureX87, FeatureSlowUAMem16, FeatureSSE2,
Feature3DNowA, FeatureFXSR, Feature64Bit,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"k8-sse3", [FeatureX87, FeatureSlowUAMem16, FeatureSSE3,
Feature3DNowA, FeatureFXSR, FeatureCMPXCHG16B,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"opteron-sse3", [FeatureX87, FeatureSlowUAMem16, FeatureSSE3,
Feature3DNowA, FeatureFXSR, FeatureCMPXCHG16B,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"athlon64-sse3", [FeatureX87, FeatureSlowUAMem16, FeatureSSE3,
Feature3DNowA, FeatureFXSR, FeatureCMPXCHG16B,
FeatureSlowBTMem, FeatureSlowSHLD]>;
def : Proc<"amdfam10", [FeatureX87, FeatureSSE4A, Feature3DNowA,
FeatureFXSR, FeatureCMPXCHG16B, FeatureLZCNT,
FeaturePOPCNT, FeatureSlowBTMem, FeatureSlowSHLD,
FeatureLAHFSAHF]>;
def : Proc<"barcelona", [FeatureX87, FeatureSSE4A, Feature3DNowA,
FeatureFXSR, FeatureCMPXCHG16B, FeatureLZCNT,
FeaturePOPCNT, FeatureSlowBTMem, FeatureSlowSHLD,
FeatureLAHFSAHF]>;

// Bobcat
def : Proc<"btver1", [
FeatureX87,
FeatureMMX,
FeatureSSSE3,
FeatureSSE4A,
Expand All @@ -580,6 +597,7 @@ def : Proc<"btver1", [

// Jaguar
def : ProcessorModel<"btver2", BtVer2Model, [
FeatureX87,
FeatureMMX,
FeatureAVX,
FeatureFXSR,
Expand All @@ -602,6 +620,7 @@ def : ProcessorModel<"btver2", BtVer2Model, [

// Bulldozer
def : Proc<"bdver1", [
FeatureX87,
FeatureXOP,
FeatureFMA4,
FeatureCMPXCHG16B,
Expand All @@ -620,6 +639,7 @@ def : Proc<"bdver1", [
]>;
// Piledriver
def : Proc<"bdver2", [
FeatureX87,
FeatureXOP,
FeatureFMA4,
FeatureCMPXCHG16B,
Expand All @@ -643,6 +663,7 @@ def : Proc<"bdver2", [

// Steamroller
def : Proc<"bdver3", [
FeatureX87,
FeatureXOP,
FeatureFMA4,
FeatureCMPXCHG16B,
Expand All @@ -668,6 +689,7 @@ def : Proc<"bdver3", [

// Excavator
def : Proc<"bdver4", [
FeatureX87,
FeatureMMX,
FeatureAVX2,
FeatureFXSR,
Expand All @@ -690,12 +712,13 @@ def : Proc<"bdver4", [
FeatureLAHFSAHF
]>;

def : Proc<"geode", [FeatureSlowUAMem16, Feature3DNowA]>;
def : Proc<"geode", [FeatureX87, FeatureSlowUAMem16, Feature3DNowA]>;

def : Proc<"winchip-c6", [FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"winchip2", [FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"c3", [FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"c3-2", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE1, FeatureFXSR]>;
def : Proc<"winchip-c6", [FeatureX87, FeatureSlowUAMem16, FeatureMMX]>;
def : Proc<"winchip2", [FeatureX87, FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"c3", [FeatureX87, FeatureSlowUAMem16, Feature3DNow]>;
def : Proc<"c3-2", [FeatureX87, FeatureSlowUAMem16, FeatureMMX,
FeatureSSE1, FeatureFXSR]>;

// We also provide a generic 64-bit specific x86 processor model which tries to
// be good for modern chips without enabling instruction set encodings past the
Expand All @@ -708,8 +731,8 @@ def : Proc<"c3-2", [FeatureSlowUAMem16, FeatureMMX, FeatureSSE1, FeatureFXSR]>;
// knobs which need to be tuned differently for AMD chips, we might consider
// forming a common base for them.
def : ProcessorModel<"x86-64", SandyBridgeModel,
[FeatureMMX, FeatureSSE2, FeatureFXSR, Feature64Bit,
FeatureSlowBTMem ]>;
[FeatureX87, FeatureMMX, FeatureSSE2, FeatureFXSR,
Feature64Bit, FeatureSlowBTMem ]>;

//===----------------------------------------------------------------------===//
// Register File Description
Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -72,6 +72,7 @@ static cl::opt<bool> ExperimentalVectorWideningLegalization(
X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
const X86Subtarget &STI)
: TargetLowering(TM), Subtarget(STI) {
bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87();
X86ScalarSSEf64 = Subtarget.hasSSE2();
X86ScalarSSEf32 = Subtarget.hasSSE1();
MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize());
Expand Down Expand Up @@ -561,7 +562,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
// cases we handle.
addLegalFPImmediate(APFloat(+0.0)); // xorpd
addLegalFPImmediate(APFloat(+0.0f)); // xorps
} else if (!Subtarget.useSoftFloat() && X86ScalarSSEf32) {
} else if (UseX87 && X86ScalarSSEf32) {
// Use SSE for f32, x87 for f64.
// Set up the FP register classes.
addRegisterClass(MVT::f32, &X86::FR32RegClass);
Expand Down Expand Up @@ -596,7 +597,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FCOS , MVT::f64, Expand);
setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
}
} else if (!Subtarget.useSoftFloat()) {
} else if (UseX87) {
// f32 and f64 in x87.
// Set up the FP register classes.
addRegisterClass(MVT::f64, &X86::RFP64RegClass);
Expand Down Expand Up @@ -630,7 +631,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FMA, MVT::f32, Expand);

// Long double always uses X87, except f128 in MMX.
if (!Subtarget.useSoftFloat()) {
if (UseX87) {
if (Subtarget.is64Bit() && Subtarget.hasMMX()) {
addRegisterClass(MVT::f128, &X86::FR128RegClass);
ValueTypeActions.setTypeAction(MVT::f128, TypeSoftenFloat);
Expand Down Expand Up @@ -2433,6 +2434,8 @@ X86TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
bool RoundAfterCopy = false;
if ((VA.getLocReg() == X86::FP0 || VA.getLocReg() == X86::FP1) &&
isScalarFPTypeInSSEReg(VA.getValVT())) {
if (!Subtarget.hasX87())
report_fatal_error("X87 register return with X87 disabled");
CopyVT = MVT::f80;
RoundAfterCopy = (CopyVT != VA.getLocVT());
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/X86Subtarget.cpp
Expand Up @@ -239,6 +239,7 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
void X86Subtarget::initializeEnvironment() {
X86SSELevel = NoSSE;
X863DNowLevel = NoThreeDNow;
HasX87 = false;
HasCMov = false;
HasX86_64 = false;
HasPOPCNT = false;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.h
Expand Up @@ -70,6 +70,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// MMX, 3DNow, 3DNow Athlon, or none supported.
X863DNowEnum X863DNowLevel;

/// True if the processor supports X87 instructions.
bool HasX87;

/// True if this processor has conditional move instructions
/// (generally pentium pro+).
bool HasCMov;
Expand Down Expand Up @@ -370,6 +373,7 @@ class X86Subtarget final : public X86GenSubtargetInfo {
PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }

bool hasX87() const { return HasX87; }
bool hasCMov() const { return HasCMov; }
bool hasSSE1() const { return X86SSELevel >= SSE1; }
bool hasSSE2() const { return X86SSELevel >= SSE2; }
Expand Down

0 comments on commit 6a3d561

Please sign in to comment.