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