1 //===-- SparcMCTargetDesc.cpp - Sparc Target Descriptions -----------------===//
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 provides Sparc specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "SparcMCTargetDesc.h"
15 #include "InstPrinter/SparcInstPrinter.h"
16 #include "SparcMCAsmInfo.h"
17 #include "SparcTargetStreamer.h"
18 #include "llvm/MC/MCCodeGenInfo.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/TargetRegistry.h"
24 
25 using namespace llvm;
26 
27 #define GET_INSTRINFO_MC_DESC
28 #include "SparcGenInstrInfo.inc"
29 
30 #define GET_SUBTARGETINFO_MC_DESC
31 #include "SparcGenSubtargetInfo.inc"
32 
33 #define GET_REGINFO_MC_DESC
34 #include "SparcGenRegisterInfo.inc"
35 
createSparcMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT)36 static MCAsmInfo *createSparcMCAsmInfo(const MCRegisterInfo &MRI,
37                                        const Triple &TT) {
38   MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
39   unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
40   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
41   MAI->addInitialFrameState(Inst);
42   return MAI;
43 }
44 
createSparcV9MCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT)45 static MCAsmInfo *createSparcV9MCAsmInfo(const MCRegisterInfo &MRI,
46                                          const Triple &TT) {
47   MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
48   unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
49   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 2047);
50   MAI->addInitialFrameState(Inst);
51   return MAI;
52 }
53 
createSparcMCInstrInfo()54 static MCInstrInfo *createSparcMCInstrInfo() {
55   MCInstrInfo *X = new MCInstrInfo();
56   InitSparcMCInstrInfo(X);
57   return X;
58 }
59 
createSparcMCRegisterInfo(const Triple & TT)60 static MCRegisterInfo *createSparcMCRegisterInfo(const Triple &TT) {
61   MCRegisterInfo *X = new MCRegisterInfo();
62   InitSparcMCRegisterInfo(X, SP::O7);
63   return X;
64 }
65 
66 static MCSubtargetInfo *
createSparcMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)67 createSparcMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
68   if (CPU.empty())
69     CPU = (TT.getArch() == Triple::sparcv9) ? "v9" : "v8";
70   return createSparcMCSubtargetInfoImpl(TT, CPU, FS);
71 }
72 
73 // Code models. Some only make sense for 64-bit code.
74 //
75 // SunCC  Reloc   CodeModel  Constraints
76 // abs32  Static  Small      text+data+bss linked below 2^32 bytes
77 // abs44  Static  Medium     text+data+bss linked below 2^44 bytes
78 // abs64  Static  Large      text smaller than 2^31 bytes
79 // pic13  PIC_    Small      GOT < 2^13 bytes
80 // pic32  PIC_    Medium     GOT < 2^32 bytes
81 //
82 // All code models require that the text segment is smaller than 2GB.
83 
createSparcMCCodeGenInfo(const Triple & TT,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)84 static MCCodeGenInfo *createSparcMCCodeGenInfo(const Triple &TT,
85                                                Reloc::Model RM,
86                                                CodeModel::Model CM,
87                                                CodeGenOpt::Level OL) {
88   MCCodeGenInfo *X = new MCCodeGenInfo();
89 
90   // The default 32-bit code model is abs32/pic32 and the default 32-bit
91   // code model for JIT is abs32.
92   switch (CM) {
93   default: break;
94   case CodeModel::Default:
95   case CodeModel::JITDefault: CM = CodeModel::Small; break;
96   }
97 
98   X->initMCCodeGenInfo(RM, CM, OL);
99   return X;
100 }
101 
createSparcV9MCCodeGenInfo(const Triple & TT,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)102 static MCCodeGenInfo *createSparcV9MCCodeGenInfo(const Triple &TT,
103                                                  Reloc::Model RM,
104                                                  CodeModel::Model CM,
105                                                  CodeGenOpt::Level OL) {
106   MCCodeGenInfo *X = new MCCodeGenInfo();
107 
108   // The default 64-bit code model is abs44/pic32 and the default 64-bit
109   // code model for JIT is abs64.
110   switch (CM) {
111   default:  break;
112   case CodeModel::Default:
113     CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
114     break;
115   case CodeModel::JITDefault:
116     CM = CodeModel::Large;
117     break;
118   }
119 
120   X->initMCCodeGenInfo(RM, CM, OL);
121   return X;
122 }
123 
124 static MCTargetStreamer *
createObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)125 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
126   return new SparcTargetELFStreamer(S);
127 }
128 
createTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)129 static MCTargetStreamer *createTargetAsmStreamer(MCStreamer &S,
130                                                  formatted_raw_ostream &OS,
131                                                  MCInstPrinter *InstPrint,
132                                                  bool isVerboseAsm) {
133   return new SparcTargetAsmStreamer(S, OS);
134 }
135 
createSparcMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)136 static MCInstPrinter *createSparcMCInstPrinter(const Triple &T,
137                                                unsigned SyntaxVariant,
138                                                const MCAsmInfo &MAI,
139                                                const MCInstrInfo &MII,
140                                                const MCRegisterInfo &MRI) {
141   return new SparcInstPrinter(MAI, MII, MRI);
142 }
143 
LLVMInitializeSparcTargetMC()144 extern "C" void LLVMInitializeSparcTargetMC() {
145   // Register the MC asm info.
146   RegisterMCAsmInfoFn X(TheSparcTarget, createSparcMCAsmInfo);
147   RegisterMCAsmInfoFn Y(TheSparcV9Target, createSparcV9MCAsmInfo);
148   RegisterMCAsmInfoFn Z(TheSparcelTarget, createSparcMCAsmInfo);
149 
150   for (Target *T : {&TheSparcTarget, &TheSparcV9Target, &TheSparcelTarget}) {
151     // Register the MC instruction info.
152     TargetRegistry::RegisterMCInstrInfo(*T, createSparcMCInstrInfo);
153 
154     // Register the MC register info.
155     TargetRegistry::RegisterMCRegInfo(*T, createSparcMCRegisterInfo);
156 
157     // Register the MC subtarget info.
158     TargetRegistry::RegisterMCSubtargetInfo(*T, createSparcMCSubtargetInfo);
159 
160     // Register the MC Code Emitter.
161     TargetRegistry::RegisterMCCodeEmitter(*T, createSparcMCCodeEmitter);
162 
163     // Register the asm backend.
164     TargetRegistry::RegisterMCAsmBackend(*T, createSparcAsmBackend);
165 
166     // Register the object target streamer.
167     TargetRegistry::RegisterObjectTargetStreamer(*T,
168                                                  createObjectTargetStreamer);
169 
170     // Register the asm streamer.
171     TargetRegistry::RegisterAsmTargetStreamer(*T, createTargetAsmStreamer);
172 
173     // Register the MCInstPrinter
174     TargetRegistry::RegisterMCInstPrinter(*T, createSparcMCInstPrinter);
175   }
176 
177   // Register the MC codegen info.
178   TargetRegistry::RegisterMCCodeGenInfo(TheSparcTarget,
179                                         createSparcMCCodeGenInfo);
180   TargetRegistry::RegisterMCCodeGenInfo(TheSparcV9Target,
181                                         createSparcV9MCCodeGenInfo);
182   TargetRegistry::RegisterMCCodeGenInfo(TheSparcelTarget,
183                                         createSparcMCCodeGenInfo);
184 }
185