xref: /aosp_15_r20/external/llvm/lib/Target/Mips/MipsSubtarget.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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