2012-02-19 10:03:36 +08:00
|
|
|
//===-- X86Subtarget.h - Define Subtarget for the X86 ----------*- C++ -*--===//
|
2005-07-12 09:41:54 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-07-12 09:41:54 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2011-07-02 05:01:15 +08:00
|
|
|
// This file declares the X86 specific subclass of TargetSubtargetInfo.
|
2005-07-12 09:41:54 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:26:38 +08:00
|
|
|
#ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H
|
|
|
|
#define LLVM_LIB_TARGET_X86_X86SUBTARGET_H
|
2005-07-12 09:41:54 +08:00
|
|
|
|
2014-06-10 01:08:19 +08:00
|
|
|
#include "X86FrameLowering.h"
|
|
|
|
#include "X86ISelLowering.h"
|
|
|
|
#include "X86InstrInfo.h"
|
|
|
|
#include "X86SelectionDAGInfo.h"
|
2010-07-06 03:26:33 +08:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/CallingConv.h"
|
2011-07-02 05:01:15 +08:00
|
|
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
2005-09-02 05:38:21 +08:00
|
|
|
#include <string>
|
|
|
|
|
2011-07-02 04:45:01 +08:00
|
|
|
#define GET_SUBTARGETINFO_HEADER
|
2011-07-02 06:36:09 +08:00
|
|
|
#include "X86GenSubtargetInfo.inc"
|
2011-07-02 04:45:01 +08:00
|
|
|
|
2005-07-12 09:41:54 +08:00
|
|
|
namespace llvm {
|
2006-12-01 06:42:55 +08:00
|
|
|
class GlobalValue;
|
2011-07-07 15:07:08 +08:00
|
|
|
class StringRef;
|
2006-12-23 06:29:05 +08:00
|
|
|
class TargetMachine;
|
2010-03-01 06:54:30 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// The X86 backend supports a number of different styles of PIC.
|
2010-03-01 06:54:30 +08:00
|
|
|
///
|
2008-11-28 17:29:37 +08:00
|
|
|
namespace PICStyles {
|
2007-01-13 03:20:47 +08:00
|
|
|
enum Style {
|
2009-07-11 04:58:47 +08:00
|
|
|
StubPIC, // Used on i386-darwin in -fPIC mode.
|
|
|
|
StubDynamicNoPIC, // Used on i386-darwin in -mdynamic-no-pic mode.
|
|
|
|
GOT, // Used on many 32-bit unices in -fPIC mode.
|
|
|
|
RIPRel, // Used on X86-64 when not in -static mode.
|
|
|
|
None // Set when in -static mode (not PIC or DynamicNoPIC mode).
|
2007-01-13 03:20:47 +08:00
|
|
|
};
|
|
|
|
}
|
2005-07-12 09:41:54 +08:00
|
|
|
|
2014-03-31 14:53:13 +08:00
|
|
|
class X86Subtarget final : public X86GenSubtargetInfo {
|
2014-06-10 01:08:19 +08:00
|
|
|
|
2005-07-12 09:41:54 +08:00
|
|
|
protected:
|
2006-01-27 16:10:46 +08:00
|
|
|
enum X86SSEEnum {
|
Move the MMX subtarget feature out of the SSE set of features and into
its own variable.
This is needed so that we can explicitly turn off MMX without turning
off SSE and also so that we can diagnose feature set incompatibilities
that involve MMX without SSE.
Rationale:
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This matches the existing gcc behavior and follows the spirit of
the SSE/MMX separation in llvm where we can (and do) turn off
MMX code generation except in the presence of intrinsics.
Updated a couple of tests, but primarily tested with a couple of tests
for turning on only mmx and only sse.
This is paired with a patch to clang to take advantage of this behavior.
llvm-svn: 249731
2015-10-09 04:10:06 +08:00
|
|
|
NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
|
2006-01-27 16:10:46 +08:00
|
|
|
};
|
|
|
|
|
2006-10-06 17:17:41 +08:00
|
|
|
enum X863DNowEnum {
|
|
|
|
NoThreeDNow, ThreeDNow, ThreeDNowA
|
|
|
|
};
|
|
|
|
|
2012-02-02 07:20:51 +08:00
|
|
|
enum X86ProcFamilyEnum {
|
2013-09-14 03:23:28 +08:00
|
|
|
Others, IntelAtom, IntelSLM
|
2012-02-02 07:20:51 +08:00
|
|
|
};
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// X86 processor family: Intel Atom, and others
|
2012-02-02 07:20:51 +08:00
|
|
|
X86ProcFamilyEnum X86ProcFamily;
|
2012-08-02 02:39:17 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Which PIC style to use
|
2008-11-28 17:29:37 +08:00
|
|
|
PICStyles::Style PICStyle;
|
2010-03-01 06:54:30 +08:00
|
|
|
|
Move the MMX subtarget feature out of the SSE set of features and into
its own variable.
This is needed so that we can explicitly turn off MMX without turning
off SSE and also so that we can diagnose feature set incompatibilities
that involve MMX without SSE.
Rationale:
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This matches the existing gcc behavior and follows the spirit of
the SSE/MMX separation in llvm where we can (and do) turn off
MMX code generation except in the presence of intrinsics.
Updated a couple of tests, but primarily tested with a couple of tests
for turning on only mmx and only sse.
This is paired with a patch to clang to take advantage of this behavior.
llvm-svn: 249731
2015-10-09 04:10:06 +08:00
|
|
|
/// SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported.
|
2006-01-27 16:10:46 +08:00
|
|
|
X86SSEEnum X86SSELevel;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// 3DNow, 3DNow Athlon, or none supported.
|
2006-10-06 17:17:41 +08:00
|
|
|
X863DNowEnum X863DNowLevel;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if this processor has conditional move instructions
|
2009-09-02 13:53:04 +08:00
|
|
|
/// (generally pentium pro+).
|
|
|
|
bool HasCMov;
|
2010-03-01 06:54:30 +08:00
|
|
|
|
Move the MMX subtarget feature out of the SSE set of features and into
its own variable.
This is needed so that we can explicitly turn off MMX without turning
off SSE and also so that we can diagnose feature set incompatibilities
that involve MMX without SSE.
Rationale:
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This matches the existing gcc behavior and follows the spirit of
the SSE/MMX separation in llvm where we can (and do) turn off
MMX code generation except in the presence of intrinsics.
Updated a couple of tests, but primarily tested with a couple of tests
for turning on only mmx and only sse.
This is paired with a patch to clang to take advantage of this behavior.
llvm-svn: 249731
2015-10-09 04:10:06 +08:00
|
|
|
/// True if this processor supports MMX instructions.
|
|
|
|
bool HasMMX;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the processor supports X86-64 instructions.
|
2006-09-08 14:48:29 +08:00
|
|
|
bool HasX86_64;
|
2009-01-02 13:35:45 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the processor supports POPCNT.
|
2010-12-05 04:32:23 +08:00
|
|
|
bool HasPOPCNT;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the processor supports SSE4A instructions.
|
2009-05-27 05:04:35 +08:00
|
|
|
bool HasSSE4A;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has AES instructions
|
2010-04-03 05:54:27 +08:00
|
|
|
bool HasAES;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has carry-less multiplication
|
2012-05-31 22:34:17 +08:00
|
|
|
bool HasPCLMUL;
|
2010-07-23 09:17:51 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has 3-operand fused multiply-add
|
2012-06-04 02:58:46 +08:00
|
|
|
bool HasFMA;
|
2009-06-27 06:46:54 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has 4-operand fused multiply-add
|
2009-06-27 06:46:54 +08:00
|
|
|
bool HasFMA4;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has XOP instructions
|
2011-12-02 23:14:37 +08:00
|
|
|
bool HasXOP;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Target has TBM instructions.
|
2013-09-25 02:21:52 +08:00
|
|
|
bool HasTBM;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the processor has the MOVBE instruction.
|
2011-10-04 01:28:23 +08:00
|
|
|
bool HasMOVBE;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the processor has the RDRAND instruction.
|
2011-10-04 01:28:23 +08:00
|
|
|
bool HasRDRAND;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has 16-bit floating point conversion instructions.
|
2011-10-09 15:31:39 +08:00
|
|
|
bool HasF16C;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has FS/GS base insturctions.
|
2011-10-31 03:57:21 +08:00
|
|
|
bool HasFSGSBase;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has LZCNT instruction.
|
2011-10-11 14:44:02 +08:00
|
|
|
bool HasLZCNT;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has BMI1 instructions.
|
2011-10-14 11:21:46 +08:00
|
|
|
bool HasBMI;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has BMI2 instructions.
|
2011-10-16 15:55:05 +08:00
|
|
|
bool HasBMI2;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has RTM instructions.
|
2012-11-08 15:28:54 +08:00
|
|
|
bool HasRTM;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has HLE.
|
2013-03-27 06:46:02 +08:00
|
|
|
bool HasHLE;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has ADX instructions.
|
2013-02-15 03:08:21 +08:00
|
|
|
bool HasADX;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has SHA instructions.
|
2013-09-12 23:51:31 +08:00
|
|
|
bool HasSHA;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has PRFCHW instructions.
|
2013-03-27 01:47:11 +08:00
|
|
|
bool HasPRFCHW;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Processor has RDSEED instructions.
|
2013-03-29 07:41:26 +08:00
|
|
|
bool HasRDSEED;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if BT (bit test) of memory instructions are slow.
|
2009-06-27 06:46:54 +08:00
|
|
|
bool IsBTMemSlow;
|
2009-12-18 15:40:29 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if SHLD instructions are slow.
|
SHLD/SHRD are VectorPath (microcode) instructions known to have poor latency on certain architectures. While generating SHLD/SHRD instructions is acceptable when optimizing for size, optimizing for speed on these platforms should be implemented using alternative sequences of instructions composed of add, adc, shr, shl, or and lea which are directPath instructions. These alternative instructions not only have a lower latency but they also increase the decode bandwidth by allowing simultaneous decoding of a third directPath instruction.
AMD's processors family K7, K8, K10, K12, K15 and K16 are known to have SHLD/SHRD instructions with very poor latency. Optimization guides for these processors recommend using an alternative sequence of instructions. For these AMD's processors, I disabled folding (or (x << c) | (y >> (64 - c))) when we are not optimizing for size.
It might be beneficial to disable this folding for some of the Intel's processors. However, since I couldn't find specific recommendations regarding using SHLD/SHRD instructions on Intel's processors, I haven't disabled this peephole for Intel.
llvm-svn: 195383
2013-11-22 07:21:26 +08:00
|
|
|
bool IsSHLDSlow;
|
|
|
|
|
2015-09-02 04:51:51 +08:00
|
|
|
/// True if unaligned memory accesses of 16-bytes are slow.
|
|
|
|
bool IsUAMem16Slow;
|
2010-04-01 13:58:17 +08:00
|
|
|
|
2015-08-22 04:17:26 +08:00
|
|
|
/// True if unaligned memory accesses of 32-bytes are slow.
|
2014-11-22 01:40:04 +08:00
|
|
|
bool IsUAMem32Slow;
|
2014-12-04 13:20:33 +08:00
|
|
|
|
2015-02-04 01:13:04 +08:00
|
|
|
/// True if SSE operations can have unaligned memory operands.
|
|
|
|
/// This may require setting a configuration bit in the processor.
|
|
|
|
bool HasSSEUnalignedMem;
|
2010-01-12 00:29:42 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if this processor has the CMPXCHG16B instruction;
|
2011-08-27 05:21:21 +08:00
|
|
|
/// this is true for most x86-64 chips, but not the first AMD chips.
|
|
|
|
bool HasCmpxchg16b;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the LEA instruction should be used for adjusting
|
2012-02-08 06:50:41 +08:00
|
|
|
/// the stack pointer. This is an optimization for Intel Atom processors.
|
|
|
|
bool UseLeaForSP;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if 8-bit divisions are significantly faster than
|
2014-11-21 19:19:34 +08:00
|
|
|
/// 32-bit divisions and should be used when possible.
|
|
|
|
bool HasSlowDivide32;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if 16-bit divides are significantly faster than
|
2014-11-21 19:19:34 +08:00
|
|
|
/// 64-bit divisions and should be used when possible.
|
|
|
|
bool HasSlowDivide64;
|
2012-09-05 02:22:17 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the short functions should be padded to prevent
|
2013-01-09 02:27:24 +08:00
|
|
|
/// a stall when returning too early.
|
|
|
|
bool PadShortFunctions;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the Calls with memory reference should be converted
|
2013-03-28 03:14:02 +08:00
|
|
|
/// to a register-based indirect call.
|
|
|
|
bool CallRegIndirect;
|
2015-02-04 02:47:32 +08:00
|
|
|
|
|
|
|
/// True if the LEA instruction inputs have to be ready at address generation
|
|
|
|
/// (AG) time.
|
2013-04-26 04:29:37 +08:00
|
|
|
bool LEAUsesAG;
|
2013-03-28 03:14:02 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if the LEA instruction with certain arguments is slow
|
2014-05-20 16:55:50 +08:00
|
|
|
bool SlowLEA;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if INC and DEC instructions are slow when writing to flags
|
2014-06-09 19:40:41 +08:00
|
|
|
bool SlowIncDec;
|
|
|
|
|
2013-07-24 19:02:47 +08:00
|
|
|
/// Processor has AVX-512 PreFetch Instructions
|
|
|
|
bool HasPFI;
|
2014-07-21 22:54:21 +08:00
|
|
|
|
2013-07-24 19:02:47 +08:00
|
|
|
/// Processor has AVX-512 Exponential and Reciprocal Instructions
|
|
|
|
bool HasERI;
|
2014-07-21 22:54:21 +08:00
|
|
|
|
2013-07-24 19:02:47 +08:00
|
|
|
/// Processor has AVX-512 Conflict Detection Instructions
|
|
|
|
bool HasCDI;
|
2014-07-21 22:54:21 +08:00
|
|
|
|
|
|
|
/// Processor has AVX-512 Doubleword and Quadword instructions
|
|
|
|
bool HasDQI;
|
|
|
|
|
|
|
|
/// Processor has AVX-512 Byte and Word instructions
|
|
|
|
bool HasBWI;
|
|
|
|
|
|
|
|
/// Processor has AVX-512 Vector Length eXtenstions
|
|
|
|
bool HasVLX;
|
|
|
|
|
2015-06-03 18:30:57 +08:00
|
|
|
/// Processot supports MPX - Memory Protection Extensions
|
|
|
|
bool HasMPX;
|
|
|
|
|
2015-05-12 09:26:05 +08:00
|
|
|
/// Use software floating point for code generation.
|
|
|
|
bool UseSoftFloat;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// The minimum alignment known to hold of the stack frame on
|
2005-07-12 10:36:10 +08:00
|
|
|
/// entry to the function and which must be maintained by every function.
|
2005-07-12 09:41:54 +08:00
|
|
|
unsigned stackAlignment;
|
2005-07-27 13:53:44 +08:00
|
|
|
|
2007-10-31 19:52:06 +08:00
|
|
|
/// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops.
|
2007-08-02 07:45:51 +08:00
|
|
|
///
|
2007-10-31 19:52:06 +08:00
|
|
|
unsigned MaxInlineSizeThreshold;
|
2011-02-17 20:23:50 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// What processor and OS we're targeting.
|
2010-07-06 03:26:33 +08:00
|
|
|
Triple TargetTriple;
|
2012-08-02 02:39:17 +08:00
|
|
|
|
2012-02-02 07:20:51 +08:00
|
|
|
/// Instruction itineraries for scheduling
|
|
|
|
InstrItineraryData InstrItins;
|
2006-02-16 08:21:07 +08:00
|
|
|
|
2006-09-08 14:48:29 +08:00
|
|
|
private:
|
2014-08-09 12:38:53 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Override the stack alignment.
|
2013-02-16 06:31:27 +08:00
|
|
|
unsigned StackAlignOverride;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if compiling for 64-bit, false for 16-bit or 32-bit.
|
2011-07-08 05:06:52 +08:00
|
|
|
bool In64BitMode;
|
2006-09-08 14:48:29 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if compiling for 32-bit, false for 16-bit or 64-bit.
|
2014-01-06 12:55:54 +08:00
|
|
|
bool In32BitMode;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// True if compiling for 16-bit, false for 32-bit or 64-bit.
|
2014-01-06 12:55:54 +08:00
|
|
|
bool In16BitMode;
|
|
|
|
|
2014-06-10 01:08:19 +08:00
|
|
|
X86SelectionDAGInfo TSInfo;
|
2014-06-11 08:25:19 +08:00
|
|
|
// Ordering here is important. X86InstrInfo initializes X86RegisterInfo which
|
|
|
|
// X86TargetLowering needs.
|
|
|
|
X86InstrInfo InstrInfo;
|
|
|
|
X86TargetLowering TLInfo;
|
|
|
|
X86FrameLowering FrameLowering;
|
2014-06-10 01:08:19 +08:00
|
|
|
|
2005-07-12 09:41:54 +08:00
|
|
|
public:
|
2005-07-27 13:53:44 +08:00
|
|
|
/// This constructor initializes the data members to match that
|
2009-08-03 06:11:08 +08:00
|
|
|
/// of the specified triple.
|
2005-07-12 09:41:54 +08:00
|
|
|
///
|
2015-06-10 20:11:26 +08:00
|
|
|
X86Subtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
|
|
|
|
const X86TargetMachine &TM, unsigned StackAlignOverride);
|
2014-06-10 01:08:19 +08:00
|
|
|
|
2014-08-05 05:25:23 +08:00
|
|
|
const X86TargetLowering *getTargetLowering() const override {
|
|
|
|
return &TLInfo;
|
|
|
|
}
|
|
|
|
const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; }
|
|
|
|
const X86FrameLowering *getFrameLowering() const override {
|
|
|
|
return &FrameLowering;
|
|
|
|
}
|
|
|
|
const X86SelectionDAGInfo *getSelectionDAGInfo() const override {
|
|
|
|
return &TSInfo;
|
|
|
|
}
|
|
|
|
const X86RegisterInfo *getRegisterInfo() const override {
|
|
|
|
return &getInstrInfo()->getRegisterInfo();
|
|
|
|
}
|
2005-07-12 10:36:10 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Returns the minimum alignment known to hold of the
|
2005-07-12 10:36:10 +08:00
|
|
|
/// stack frame on entry to the function and which must be maintained by every
|
|
|
|
/// function for this subtarget.
|
2005-07-12 09:41:54 +08:00
|
|
|
unsigned getStackAlignment() const { return stackAlignment; }
|
2005-07-27 13:53:44 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Returns the maximum memset / memcpy size
|
2007-10-31 19:52:06 +08:00
|
|
|
/// that still makes it profitable to inline the call.
|
|
|
|
unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; }
|
2006-11-21 08:01:06 +08:00
|
|
|
|
|
|
|
/// ParseSubtargetFeatures - Parses features string setting specified
|
2006-10-06 17:17:41 +08:00
|
|
|
/// subtarget options. Definition of function is auto generated by tblgen.
|
2011-07-07 15:07:08 +08:00
|
|
|
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
|
2006-10-06 17:17:41 +08:00
|
|
|
|
2013-02-16 09:36:26 +08:00
|
|
|
private:
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Initialize the full set of dependencies so we can use an initializer
|
2014-06-11 08:25:19 +08:00
|
|
|
/// list for X86Subtarget.
|
|
|
|
X86Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
|
2013-02-16 09:36:26 +08:00
|
|
|
void initializeEnvironment();
|
2014-09-04 04:36:31 +08:00
|
|
|
void initSubtargetFeatures(StringRef CPU, StringRef FS);
|
2013-02-16 09:36:26 +08:00
|
|
|
public:
|
2013-01-26 06:07:43 +08:00
|
|
|
/// Is this x86_64? (disregarding specific ABI / programming model)
|
|
|
|
bool is64Bit() const {
|
|
|
|
return In64BitMode;
|
|
|
|
}
|
|
|
|
|
2014-01-06 12:55:54 +08:00
|
|
|
bool is32Bit() const {
|
|
|
|
return In32BitMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is16Bit() const {
|
|
|
|
return In16BitMode;
|
|
|
|
}
|
|
|
|
|
2013-01-26 06:07:43 +08:00
|
|
|
/// Is this x86_64 with the ILP32 programming model (x32 ABI)?
|
|
|
|
bool isTarget64BitILP32() const {
|
2013-12-19 08:44:37 +08:00
|
|
|
return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 ||
|
2014-11-23 03:12:10 +08:00
|
|
|
TargetTriple.isOSNaCl());
|
2013-01-26 06:07:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
|
|
|
|
bool isTarget64BitLP64() const {
|
2014-08-07 17:41:19 +08:00
|
|
|
return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 &&
|
2014-11-23 03:12:10 +08:00
|
|
|
!TargetTriple.isOSNaCl());
|
2013-01-26 06:07:43 +08:00
|
|
|
}
|
2006-01-26 17:53:06 +08:00
|
|
|
|
2008-11-28 17:29:37 +08:00
|
|
|
PICStyles::Style getPICStyle() const { return PICStyle; }
|
|
|
|
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
|
2007-01-13 03:20:47 +08:00
|
|
|
|
2010-03-15 02:31:44 +08:00
|
|
|
bool hasCMov() const { return HasCMov; }
|
Move the MMX subtarget feature out of the SSE set of features and into
its own variable.
This is needed so that we can explicitly turn off MMX without turning
off SSE and also so that we can diagnose feature set incompatibilities
that involve MMX without SSE.
Rationale:
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This matches the existing gcc behavior and follows the spirit of
the SSE/MMX separation in llvm where we can (and do) turn off
MMX code generation except in the presence of intrinsics.
Updated a couple of tests, but primarily tested with a couple of tests
for turning on only mmx and only sse.
This is paired with a patch to clang to take advantage of this behavior.
llvm-svn: 249731
2015-10-09 04:10:06 +08:00
|
|
|
bool hasMMX() const { return HasMMX; }
|
2012-01-10 14:30:56 +08:00
|
|
|
bool hasSSE1() const { return X86SSELevel >= SSE1; }
|
|
|
|
bool hasSSE2() const { return X86SSELevel >= SSE2; }
|
|
|
|
bool hasSSE3() const { return X86SSELevel >= SSE3; }
|
|
|
|
bool hasSSSE3() const { return X86SSELevel >= SSSE3; }
|
|
|
|
bool hasSSE41() const { return X86SSELevel >= SSE41; }
|
|
|
|
bool hasSSE42() const { return X86SSELevel >= SSE42; }
|
2012-01-10 14:54:16 +08:00
|
|
|
bool hasAVX() const { return X86SSELevel >= AVX; }
|
|
|
|
bool hasAVX2() const { return X86SSELevel >= AVX2; }
|
2013-08-21 11:57:57 +08:00
|
|
|
bool hasAVX512() const { return X86SSELevel >= AVX512F; }
|
2012-11-29 20:44:59 +08:00
|
|
|
bool hasFp256() const { return hasAVX(); }
|
|
|
|
bool hasInt256() const { return hasAVX2(); }
|
2009-05-27 05:04:35 +08:00
|
|
|
bool hasSSE4A() const { return HasSSE4A; }
|
2006-10-06 17:17:41 +08:00
|
|
|
bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
|
|
|
|
bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
|
2010-12-05 04:32:23 +08:00
|
|
|
bool hasPOPCNT() const { return HasPOPCNT; }
|
2010-04-03 05:54:27 +08:00
|
|
|
bool hasAES() const { return HasAES; }
|
2012-05-31 22:34:17 +08:00
|
|
|
bool hasPCLMUL() const { return HasPCLMUL; }
|
2012-06-04 02:58:46 +08:00
|
|
|
bool hasFMA() const { return HasFMA; }
|
2012-08-24 12:03:22 +08:00
|
|
|
// FIXME: Favor FMA when both are enabled. Is this the right thing to do?
|
2012-08-24 02:14:30 +08:00
|
|
|
bool hasFMA4() const { return HasFMA4 && !HasFMA; }
|
2011-12-02 23:14:37 +08:00
|
|
|
bool hasXOP() const { return HasXOP; }
|
2013-09-25 02:21:52 +08:00
|
|
|
bool hasTBM() const { return HasTBM; }
|
2011-10-04 01:28:23 +08:00
|
|
|
bool hasMOVBE() const { return HasMOVBE; }
|
|
|
|
bool hasRDRAND() const { return HasRDRAND; }
|
2011-10-09 15:31:39 +08:00
|
|
|
bool hasF16C() const { return HasF16C; }
|
2011-10-31 03:57:21 +08:00
|
|
|
bool hasFSGSBase() const { return HasFSGSBase; }
|
2011-10-11 14:44:02 +08:00
|
|
|
bool hasLZCNT() const { return HasLZCNT; }
|
2011-10-14 11:21:46 +08:00
|
|
|
bool hasBMI() const { return HasBMI; }
|
2011-10-16 15:55:05 +08:00
|
|
|
bool hasBMI2() const { return HasBMI2; }
|
2012-11-08 15:28:54 +08:00
|
|
|
bool hasRTM() const { return HasRTM; }
|
2013-03-27 06:46:02 +08:00
|
|
|
bool hasHLE() const { return HasHLE; }
|
2013-02-15 03:08:21 +08:00
|
|
|
bool hasADX() const { return HasADX; }
|
2013-09-12 23:51:31 +08:00
|
|
|
bool hasSHA() const { return HasSHA; }
|
2013-03-27 01:47:11 +08:00
|
|
|
bool hasPRFCHW() const { return HasPRFCHW; }
|
2013-03-29 07:41:26 +08:00
|
|
|
bool hasRDSEED() const { return HasRDSEED; }
|
2009-01-02 13:35:45 +08:00
|
|
|
bool isBTMemSlow() const { return IsBTMemSlow; }
|
SHLD/SHRD are VectorPath (microcode) instructions known to have poor latency on certain architectures. While generating SHLD/SHRD instructions is acceptable when optimizing for size, optimizing for speed on these platforms should be implemented using alternative sequences of instructions composed of add, adc, shr, shl, or and lea which are directPath instructions. These alternative instructions not only have a lower latency but they also increase the decode bandwidth by allowing simultaneous decoding of a third directPath instruction.
AMD's processors family K7, K8, K10, K12, K15 and K16 are known to have SHLD/SHRD instructions with very poor latency. Optimization guides for these processors recommend using an alternative sequence of instructions. For these AMD's processors, I disabled folding (or (x << c) | (y >> (64 - c))) when we are not optimizing for size.
It might be beneficial to disable this folding for some of the Intel's processors. However, since I couldn't find specific recommendations regarding using SHLD/SHRD instructions on Intel's processors, I haven't disabled this peephole for Intel.
llvm-svn: 195383
2013-11-22 07:21:26 +08:00
|
|
|
bool isSHLDSlow() const { return IsSHLDSlow; }
|
2015-09-02 04:51:51 +08:00
|
|
|
bool isUnalignedMem16Slow() const { return IsUAMem16Slow; }
|
2014-11-22 01:40:04 +08:00
|
|
|
bool isUnalignedMem32Slow() const { return IsUAMem32Slow; }
|
2015-02-04 01:13:04 +08:00
|
|
|
bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; }
|
2011-08-27 05:21:21 +08:00
|
|
|
bool hasCmpxchg16b() const { return HasCmpxchg16b; }
|
2012-02-08 06:50:41 +08:00
|
|
|
bool useLeaForSP() const { return UseLeaForSP; }
|
2014-11-21 19:19:34 +08:00
|
|
|
bool hasSlowDivide32() const { return HasSlowDivide32; }
|
|
|
|
bool hasSlowDivide64() const { return HasSlowDivide64; }
|
2013-01-09 02:27:24 +08:00
|
|
|
bool padShortFunctions() const { return PadShortFunctions; }
|
2013-03-28 03:14:02 +08:00
|
|
|
bool callRegIndirect() const { return CallRegIndirect; }
|
2013-04-26 04:29:37 +08:00
|
|
|
bool LEAusesAG() const { return LEAUsesAG; }
|
2014-05-20 16:55:50 +08:00
|
|
|
bool slowLEA() const { return SlowLEA; }
|
2014-06-09 19:40:41 +08:00
|
|
|
bool slowIncDec() const { return SlowIncDec; }
|
2013-07-24 19:02:47 +08:00
|
|
|
bool hasCDI() const { return HasCDI; }
|
|
|
|
bool hasPFI() const { return HasPFI; }
|
|
|
|
bool hasERI() const { return HasERI; }
|
2014-07-21 22:54:21 +08:00
|
|
|
bool hasDQI() const { return HasDQI; }
|
|
|
|
bool hasBWI() const { return HasBWI; }
|
|
|
|
bool hasVLX() const { return HasVLX; }
|
2015-06-03 18:30:57 +08:00
|
|
|
bool hasMPX() const { return HasMPX; }
|
2009-01-02 13:35:45 +08:00
|
|
|
|
2012-02-02 07:20:51 +08:00
|
|
|
bool isAtom() const { return X86ProcFamily == IntelAtom; }
|
2014-05-20 16:55:50 +08:00
|
|
|
bool isSLM() const { return X86ProcFamily == IntelSLM; }
|
2015-05-12 09:26:05 +08:00
|
|
|
bool useSoftFloat() const { return UseSoftFloat; }
|
2012-02-02 07:20:51 +08:00
|
|
|
|
2011-04-20 05:01:47 +08:00
|
|
|
const Triple &getTargetTriple() const { return TargetTriple; }
|
|
|
|
|
2011-04-20 05:14:45 +08:00
|
|
|
bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
|
2014-11-23 03:12:10 +08:00
|
|
|
bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); }
|
2014-12-29 23:47:28 +08:00
|
|
|
bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); }
|
2014-11-23 03:12:10 +08:00
|
|
|
bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); }
|
2015-01-27 03:09:27 +08:00
|
|
|
bool isTargetPS4() const { return TargetTriple.isPS4(); }
|
2013-12-11 00:57:43 +08:00
|
|
|
|
|
|
|
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
|
|
|
bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
|
2014-12-05 08:22:38 +08:00
|
|
|
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
|
2013-12-11 00:57:43 +08:00
|
|
|
|
2013-08-30 04:23:14 +08:00
|
|
|
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
|
2015-10-09 05:21:24 +08:00
|
|
|
bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
|
2013-08-30 04:23:14 +08:00
|
|
|
bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
|
2011-09-06 05:51:43 +08:00
|
|
|
bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); }
|
|
|
|
bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); }
|
2014-04-02 12:27:51 +08:00
|
|
|
|
|
|
|
bool isTargetWindowsMSVC() const {
|
|
|
|
return TargetTriple.isWindowsMSVCEnvironment();
|
|
|
|
}
|
|
|
|
|
2014-04-02 02:15:34 +08:00
|
|
|
bool isTargetKnownWindowsMSVC() const {
|
2014-03-30 12:35:00 +08:00
|
|
|
return TargetTriple.isKnownWindowsMSVCEnvironment();
|
2014-03-28 06:50:05 +08:00
|
|
|
}
|
2014-04-02 12:27:51 +08:00
|
|
|
|
2015-08-15 06:41:43 +08:00
|
|
|
bool isTargetWindowsCoreCLR() const {
|
|
|
|
return TargetTriple.isWindowsCoreCLREnvironment();
|
|
|
|
}
|
|
|
|
|
2014-04-02 12:27:51 +08:00
|
|
|
bool isTargetWindowsCygwin() const {
|
2014-03-28 06:50:05 +08:00
|
|
|
return TargetTriple.isWindowsCygwinEnvironment();
|
|
|
|
}
|
2014-04-02 12:27:51 +08:00
|
|
|
|
|
|
|
bool isTargetWindowsGNU() const {
|
|
|
|
return TargetTriple.isWindowsGNUEnvironment();
|
|
|
|
}
|
|
|
|
|
2014-11-21 02:01:26 +08:00
|
|
|
bool isTargetWindowsItanium() const {
|
|
|
|
return TargetTriple.isWindowsItaniumEnvironment();
|
|
|
|
}
|
|
|
|
|
2012-02-05 16:26:40 +08:00
|
|
|
bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); }
|
2010-03-01 06:54:30 +08:00
|
|
|
|
2013-10-24 07:37:01 +08:00
|
|
|
bool isOSWindows() const { return TargetTriple.isOSWindows(); }
|
|
|
|
|
2008-03-23 04:57:27 +08:00
|
|
|
bool isTargetWin64() const {
|
2012-02-05 16:26:40 +08:00
|
|
|
return In64BitMode && TargetTriple.isOSWindows();
|
2011-02-01 09:14:13 +08:00
|
|
|
}
|
|
|
|
|
2010-09-03 07:03:46 +08:00
|
|
|
bool isTargetWin32() const {
|
2014-04-02 02:15:34 +08:00
|
|
|
return !In64BitMode && (isTargetCygMing() || isTargetKnownWindowsMSVC());
|
2010-09-03 07:03:46 +08:00
|
|
|
}
|
|
|
|
|
2008-11-28 17:29:37 +08:00
|
|
|
bool isPICStyleSet() const { return PICStyle != PICStyles::None; }
|
|
|
|
bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; }
|
|
|
|
bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; }
|
2009-07-11 04:47:30 +08:00
|
|
|
|
2009-07-11 05:00:45 +08:00
|
|
|
bool isPICStyleStubPIC() const {
|
2009-07-11 04:58:47 +08:00
|
|
|
return PICStyle == PICStyles::StubPIC;
|
|
|
|
}
|
|
|
|
|
2009-07-11 05:00:45 +08:00
|
|
|
bool isPICStyleStubNoDynamic() const {
|
2009-07-11 04:58:47 +08:00
|
|
|
return PICStyle == PICStyles::StubDynamicNoPIC;
|
|
|
|
}
|
|
|
|
bool isPICStyleStubAny() const {
|
|
|
|
return PICStyle == PICStyles::StubDynamicNoPIC ||
|
2013-07-12 14:02:35 +08:00
|
|
|
PICStyle == PICStyles::StubPIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isCallingConvWin64(CallingConv::ID CC) const {
|
2015-07-09 05:03:47 +08:00
|
|
|
switch (CC) {
|
|
|
|
// On Win64, all these conventions just use the default convention.
|
|
|
|
case CallingConv::C:
|
|
|
|
case CallingConv::Fast:
|
|
|
|
case CallingConv::X86_FastCall:
|
|
|
|
case CallingConv::X86_StdCall:
|
|
|
|
case CallingConv::X86_ThisCall:
|
|
|
|
case CallingConv::X86_VectorCall:
|
|
|
|
case CallingConv::Intel_OCL_BI:
|
|
|
|
return isTargetWin64();
|
|
|
|
// This convention allows using the Win64 convention on other targets.
|
|
|
|
case CallingConv::X86_64_Win64:
|
|
|
|
return true;
|
|
|
|
// This convention allows using the SysV convention on Windows targets.
|
|
|
|
case CallingConv::X86_64_SysV:
|
|
|
|
return false;
|
|
|
|
// Otherwise, who knows what this is.
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2013-07-12 14:02:35 +08:00
|
|
|
}
|
2010-03-01 06:54:30 +08:00
|
|
|
|
2009-07-10 15:20:05 +08:00
|
|
|
/// ClassifyGlobalReference - Classify a global variable reference for the
|
|
|
|
/// current subtarget according to how we should reference it in a non-pcrel
|
|
|
|
/// context.
|
|
|
|
unsigned char ClassifyGlobalReference(const GlobalValue *GV,
|
|
|
|
const TargetMachine &TM)const;
|
2006-12-20 09:03:20 +08:00
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Classify a blockaddress reference for the current subtarget according to
|
|
|
|
/// how we should reference it in a non-pcrel context.
|
2009-11-21 07:18:13 +08:00
|
|
|
unsigned char ClassifyBlockAddressReference() const;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Return true if the subtarget allows calls to immediate address.
|
2009-05-20 12:53:57 +08:00
|
|
|
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;
|
|
|
|
|
2008-04-02 04:38:36 +08:00
|
|
|
/// This function returns the name of a function which has an interface
|
|
|
|
/// like the non-standard bzero function, if such a function exists on
|
|
|
|
/// the current subtarget and it is considered prefereable over
|
|
|
|
/// memset with zero passed as the second argument. Otherwise it
|
|
|
|
/// returns null.
|
2008-10-01 06:05:33 +08:00
|
|
|
const char *getBZeroEntry() const;
|
2013-10-16 07:33:07 +08:00
|
|
|
|
2013-01-29 10:32:37 +08:00
|
|
|
/// This function returns true if the target has sincos() routine in its
|
|
|
|
/// compiler runtime or math libraries.
|
|
|
|
bool hasSinCos() const;
|
2008-12-16 11:35:01 +08:00
|
|
|
|
2013-10-16 07:33:07 +08:00
|
|
|
/// Enable the MachineScheduler pass for all X86 subtargets.
|
2014-03-02 17:09:27 +08:00
|
|
|
bool enableMachineScheduler() const override { return true; }
|
2013-10-16 07:33:07 +08:00
|
|
|
|
2014-05-22 07:40:26 +08:00
|
|
|
bool enableEarlyIfConversion() const override;
|
|
|
|
|
2015-02-04 02:47:32 +08:00
|
|
|
/// Return the instruction itineraries based on the subtarget selection.
|
2014-08-05 05:25:23 +08:00
|
|
|
const InstrItineraryData *getInstrItineraryData() const override {
|
|
|
|
return &InstrItins;
|
|
|
|
}
|
2014-07-16 06:39:58 +08:00
|
|
|
|
|
|
|
AntiDepBreakMode getAntiDepBreakMode() const override {
|
|
|
|
return TargetSubtargetInfo::ANTIDEP_CRITICAL;
|
|
|
|
}
|
2009-09-03 12:37:05 +08:00
|
|
|
};
|
2006-10-17 05:00:37 +08:00
|
|
|
|
2015-06-23 17:49:53 +08:00
|
|
|
} // End llvm namespace
|
2005-07-12 09:41:54 +08:00
|
|
|
|
|
|
|
#endif
|