/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Mips/MipsSubtarget.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- MipsSubtarget.cpp - Mips Subtarget Information --------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements the Mips specific subclass of TargetSubtargetInfo. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "MipsSubtarget.h" |
15 | | #include "Mips.h" |
16 | | #include "MipsMachineFunction.h" |
17 | | #include "MipsRegisterInfo.h" |
18 | | #include "MipsTargetMachine.h" |
19 | | #include "llvm/IR/Attributes.h" |
20 | | #include "llvm/IR/Function.h" |
21 | | #include "llvm/Support/CommandLine.h" |
22 | | #include "llvm/Support/Debug.h" |
23 | | #include "llvm/Support/TargetRegistry.h" |
24 | | #include "llvm/Support/raw_ostream.h" |
25 | | |
26 | | using namespace llvm; |
27 | | |
28 | | #define DEBUG_TYPE "mips-subtarget" |
29 | | |
30 | | #define GET_SUBTARGETINFO_TARGET_DESC |
31 | | #define GET_SUBTARGETINFO_CTOR |
32 | | #include "MipsGenSubtargetInfo.inc" |
33 | | |
34 | | // FIXME: Maybe this should be on by default when Mips16 is specified |
35 | | // |
36 | | static cl::opt<bool> |
37 | | Mixed16_32("mips-mixed-16-32", cl::init(false), |
38 | | cl::desc("Allow for a mixture of Mips16 " |
39 | | "and Mips32 code in a single output file"), |
40 | | cl::Hidden); |
41 | | |
42 | | static cl::opt<bool> Mips_Os16("mips-os16", cl::init(false), |
43 | | cl::desc("Compile all functions that don't use " |
44 | | "floating point as Mips 16"), |
45 | | cl::Hidden); |
46 | | |
47 | | static cl::opt<bool> Mips16HardFloat("mips16-hard-float", cl::NotHidden, |
48 | | cl::desc("Enable mips16 hard float."), |
49 | | cl::init(false)); |
50 | | |
51 | | static cl::opt<bool> |
52 | | Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden, |
53 | | cl::desc("Enable mips16 constant islands."), |
54 | | cl::init(true)); |
55 | | |
56 | | static cl::opt<bool> |
57 | | GPOpt("mgpopt", cl::Hidden, |
58 | | cl::desc("Enable gp-relative addressing of mips small data items")); |
59 | | |
60 | 0 | void MipsSubtarget::anchor() {} |
61 | | |
62 | | MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, |
63 | | bool little, const MipsTargetMachine &TM, |
64 | | unsigned StackAlignOverride) |
65 | | : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault), |
66 | | IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false), |
67 | | NoABICalls(false), IsFP64bit(false), UseOddSPReg(true), |
68 | | IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false), |
69 | | HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false), |
70 | | HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false), |
71 | | InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), |
72 | | HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), |
73 | | Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false), |
74 | | HasEVA(false), DisableMadd4(false), HasMT(false), |
75 | | StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT), |
76 | | TSInfo(), InstrInfo(MipsInstrInfo::create( |
77 | | initializeSubtargetDependencies(CPU, FS, TM))), |
78 | | FrameLowering(MipsFrameLowering::create(*this)), |
79 | 8.96k | TLInfo(MipsTargetLowering::create(TM, *this)) { |
80 | 8.96k | |
81 | 8.96k | if (MipsArchVersion == MipsDefault) |
82 | 15 | MipsArchVersion = Mips32; |
83 | 8.96k | |
84 | 8.96k | // Don't even attempt to generate code for MIPS-I and MIPS-V. They have not |
85 | 8.96k | // been tested and currently exist for the integrated assembler only. |
86 | 8.96k | if (MipsArchVersion == Mips1) |
87 | 0 | report_fatal_error("Code generation for MIPS-I is not implemented", false); |
88 | 8.96k | if (8.96k MipsArchVersion == Mips58.96k ) |
89 | 0 | report_fatal_error("Code generation for MIPS-V is not implemented", false); |
90 | 8.96k | |
91 | 8.96k | // Check if Architecture and ABI are compatible. |
92 | 8.96k | assert(((!isGP64bit() && isABI_O32()) || |
93 | 8.96k | (isGP64bit() && (isABI_N32() || isABI_N64()))) && |
94 | 8.96k | "Invalid Arch & ABI pair."); |
95 | 8.96k | |
96 | 8.96k | if (hasMSA() && 8.96k !isFP64bit()899 ) |
97 | 1 | report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). " |
98 | 1 | "See -mattr=+fp64.", |
99 | 1 | false); |
100 | 8.96k | |
101 | 8.96k | if (8.96k !isABI_O32() && 8.96k !useOddSPReg()3.22k ) |
102 | 2 | report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false); |
103 | 8.96k | |
104 | 8.96k | if (8.96k IsFPXX && 8.96k (isABI_N32() || 62 isABI_N64()62 )) |
105 | 2 | report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false); |
106 | 8.95k | |
107 | 8.95k | if (8.95k hasMips32r6()8.95k ) { |
108 | 1.08k | StringRef ISA = hasMips64r6() ? "MIPS64r6"464 : "MIPS32r6"623 ; |
109 | 1.08k | |
110 | 1.08k | assert(isFP64bit()); |
111 | 1.08k | assert(isNaN2008()); |
112 | 1.08k | if (hasDSP()) |
113 | 2 | report_fatal_error(ISA + " is not compatible with the DSP ASE", false); |
114 | 8.95k | } |
115 | 8.95k | |
116 | 8.95k | if (8.95k NoABICalls && 8.95k TM.isPositionIndependent()89 ) |
117 | 0 | report_fatal_error("position-independent code requires '-mabicalls'"); |
118 | 8.95k | |
119 | 8.95k | if (8.95k isABI_N64() && 8.95k !TM.isPositionIndependent()2.75k && !hasSym32()1.66k ) |
120 | 1.65k | NoABICalls = true; |
121 | 8.95k | |
122 | 8.95k | // Set UseSmallSection. |
123 | 8.95k | UseSmallSection = GPOpt; |
124 | 8.95k | if (!NoABICalls && 8.95k GPOpt7.23k ) { |
125 | 0 | errs() << "warning: cannot use small-data accesses for '-mabicalls'" |
126 | 0 | << "\n"; |
127 | 0 | UseSmallSection = false; |
128 | 0 | } |
129 | 8.96k | } |
130 | | |
131 | 6.59k | bool MipsSubtarget::isPositionIndependent() const { |
132 | 6.59k | return TM.isPositionIndependent(); |
133 | 6.59k | } |
134 | | |
135 | | /// This overrides the PostRAScheduler bit in the SchedModel for any CPU. |
136 | 11.9k | bool MipsSubtarget::enablePostRAScheduler() const { return true; } |
137 | | |
138 | 11.9k | void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
139 | 11.9k | CriticalPathRCs.clear(); |
140 | 4.53k | CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass |
141 | 7.39k | : &Mips::GPR32RegClass); |
142 | 11.9k | } |
143 | | |
144 | 11.9k | CodeGenOpt::Level MipsSubtarget::getOptLevelToEnablePostRAScheduler() const { |
145 | 11.9k | return CodeGenOpt::Aggressive; |
146 | 11.9k | } |
147 | | |
148 | | MipsSubtarget & |
149 | | MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, |
150 | 8.96k | const TargetMachine &TM) { |
151 | 8.96k | std::string CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU); |
152 | 8.96k | |
153 | 8.96k | // Parse features string. |
154 | 8.96k | ParseSubtargetFeatures(CPUName, FS); |
155 | 8.96k | // Initialize scheduling itinerary for the specified CPU. |
156 | 8.96k | InstrItins = getInstrItineraryForCPU(CPUName); |
157 | 8.96k | |
158 | 8.96k | if (InMips16Mode && 8.96k !IsSoftFloat2.37k ) |
159 | 2.21k | InMips16HardFloat = true; |
160 | 8.96k | |
161 | 8.96k | if (StackAlignOverride) |
162 | 8 | stackAlignment = StackAlignOverride; |
163 | 8.95k | else if (8.95k isABI_N32() || 8.95k isABI_N64()8.49k ) |
164 | 3.21k | stackAlignment = 16; |
165 | 5.74k | else { |
166 | 5.74k | assert(isABI_O32() && "Unknown ABI for stack alignment!"); |
167 | 5.74k | stackAlignment = 8; |
168 | 5.74k | } |
169 | 8.96k | |
170 | 8.96k | return *this; |
171 | 8.96k | } |
172 | | |
173 | 754 | bool MipsSubtarget::useConstantIslands() { |
174 | 754 | DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands << "\n"); |
175 | 754 | return Mips16ConstantIslands; |
176 | 754 | } |
177 | | |
178 | 10 | Reloc::Model MipsSubtarget::getRelocationModel() const { |
179 | 10 | return TM.getRelocationModel(); |
180 | 10 | } |
181 | | |
182 | 149k | bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); } |
183 | 110k | bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); } |
184 | 74.4k | bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); } |
185 | 472k | const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); } |