1f4a2713aSLionel Sambuc //===-- SystemZMCTargetDesc.cpp - SystemZ target descriptions -------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "SystemZMCTargetDesc.h"
11f4a2713aSLionel Sambuc #include "InstPrinter/SystemZInstPrinter.h"
12f4a2713aSLionel Sambuc #include "SystemZMCAsmInfo.h"
13f4a2713aSLionel Sambuc #include "llvm/MC/MCCodeGenInfo.h"
14f4a2713aSLionel Sambuc #include "llvm/MC/MCInstrInfo.h"
15f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h"
16f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h"
17f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
18f4a2713aSLionel Sambuc 
19*0a6a1f1dSLionel Sambuc using namespace llvm;
20*0a6a1f1dSLionel Sambuc 
21f4a2713aSLionel Sambuc #define GET_INSTRINFO_MC_DESC
22f4a2713aSLionel Sambuc #include "SystemZGenInstrInfo.inc"
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc #define GET_SUBTARGETINFO_MC_DESC
25f4a2713aSLionel Sambuc #include "SystemZGenSubtargetInfo.inc"
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc #define GET_REGINFO_MC_DESC
28f4a2713aSLionel Sambuc #include "SystemZGenRegisterInfo.inc"
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc const unsigned SystemZMC::GR32Regs[16] = {
31f4a2713aSLionel Sambuc   SystemZ::R0L, SystemZ::R1L, SystemZ::R2L, SystemZ::R3L,
32f4a2713aSLionel Sambuc   SystemZ::R4L, SystemZ::R5L, SystemZ::R6L, SystemZ::R7L,
33f4a2713aSLionel Sambuc   SystemZ::R8L, SystemZ::R9L, SystemZ::R10L, SystemZ::R11L,
34f4a2713aSLionel Sambuc   SystemZ::R12L, SystemZ::R13L, SystemZ::R14L, SystemZ::R15L
35f4a2713aSLionel Sambuc };
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc const unsigned SystemZMC::GRH32Regs[16] = {
38f4a2713aSLionel Sambuc   SystemZ::R0H, SystemZ::R1H, SystemZ::R2H, SystemZ::R3H,
39f4a2713aSLionel Sambuc   SystemZ::R4H, SystemZ::R5H, SystemZ::R6H, SystemZ::R7H,
40f4a2713aSLionel Sambuc   SystemZ::R8H, SystemZ::R9H, SystemZ::R10H, SystemZ::R11H,
41f4a2713aSLionel Sambuc   SystemZ::R12H, SystemZ::R13H, SystemZ::R14H, SystemZ::R15H
42f4a2713aSLionel Sambuc };
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc const unsigned SystemZMC::GR64Regs[16] = {
45f4a2713aSLionel Sambuc   SystemZ::R0D, SystemZ::R1D, SystemZ::R2D, SystemZ::R3D,
46f4a2713aSLionel Sambuc   SystemZ::R4D, SystemZ::R5D, SystemZ::R6D, SystemZ::R7D,
47f4a2713aSLionel Sambuc   SystemZ::R8D, SystemZ::R9D, SystemZ::R10D, SystemZ::R11D,
48f4a2713aSLionel Sambuc   SystemZ::R12D, SystemZ::R13D, SystemZ::R14D, SystemZ::R15D
49f4a2713aSLionel Sambuc };
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc const unsigned SystemZMC::GR128Regs[16] = {
52f4a2713aSLionel Sambuc   SystemZ::R0Q, 0, SystemZ::R2Q, 0,
53f4a2713aSLionel Sambuc   SystemZ::R4Q, 0, SystemZ::R6Q, 0,
54f4a2713aSLionel Sambuc   SystemZ::R8Q, 0, SystemZ::R10Q, 0,
55f4a2713aSLionel Sambuc   SystemZ::R12Q, 0, SystemZ::R14Q, 0
56f4a2713aSLionel Sambuc };
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc const unsigned SystemZMC::FP32Regs[16] = {
59f4a2713aSLionel Sambuc   SystemZ::F0S, SystemZ::F1S, SystemZ::F2S, SystemZ::F3S,
60f4a2713aSLionel Sambuc   SystemZ::F4S, SystemZ::F5S, SystemZ::F6S, SystemZ::F7S,
61f4a2713aSLionel Sambuc   SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S,
62f4a2713aSLionel Sambuc   SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S
63f4a2713aSLionel Sambuc };
64f4a2713aSLionel Sambuc 
65f4a2713aSLionel Sambuc const unsigned SystemZMC::FP64Regs[16] = {
66f4a2713aSLionel Sambuc   SystemZ::F0D, SystemZ::F1D, SystemZ::F2D, SystemZ::F3D,
67f4a2713aSLionel Sambuc   SystemZ::F4D, SystemZ::F5D, SystemZ::F6D, SystemZ::F7D,
68f4a2713aSLionel Sambuc   SystemZ::F8D, SystemZ::F9D, SystemZ::F10D, SystemZ::F11D,
69f4a2713aSLionel Sambuc   SystemZ::F12D, SystemZ::F13D, SystemZ::F14D, SystemZ::F15D
70f4a2713aSLionel Sambuc };
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc const unsigned SystemZMC::FP128Regs[16] = {
73f4a2713aSLionel Sambuc   SystemZ::F0Q, SystemZ::F1Q, 0, 0,
74f4a2713aSLionel Sambuc   SystemZ::F4Q, SystemZ::F5Q, 0, 0,
75f4a2713aSLionel Sambuc   SystemZ::F8Q, SystemZ::F9Q, 0, 0,
76f4a2713aSLionel Sambuc   SystemZ::F12Q, SystemZ::F13Q, 0, 0
77f4a2713aSLionel Sambuc };
78f4a2713aSLionel Sambuc 
getFirstReg(unsigned Reg)79f4a2713aSLionel Sambuc unsigned SystemZMC::getFirstReg(unsigned Reg) {
80f4a2713aSLionel Sambuc   static unsigned Map[SystemZ::NUM_TARGET_REGS];
81f4a2713aSLionel Sambuc   static bool Initialized = false;
82f4a2713aSLionel Sambuc   if (!Initialized) {
83f4a2713aSLionel Sambuc     for (unsigned I = 0; I < 16; ++I) {
84f4a2713aSLionel Sambuc       Map[GR32Regs[I]] = I;
85f4a2713aSLionel Sambuc       Map[GRH32Regs[I]] = I;
86f4a2713aSLionel Sambuc       Map[GR64Regs[I]] = I;
87f4a2713aSLionel Sambuc       Map[GR128Regs[I]] = I;
88f4a2713aSLionel Sambuc       Map[FP32Regs[I]] = I;
89f4a2713aSLionel Sambuc       Map[FP64Regs[I]] = I;
90f4a2713aSLionel Sambuc       Map[FP128Regs[I]] = I;
91f4a2713aSLionel Sambuc     }
92f4a2713aSLionel Sambuc   }
93f4a2713aSLionel Sambuc   assert(Reg < SystemZ::NUM_TARGET_REGS);
94f4a2713aSLionel Sambuc   return Map[Reg];
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc 
createSystemZMCAsmInfo(const MCRegisterInfo & MRI,StringRef TT)97f4a2713aSLionel Sambuc static MCAsmInfo *createSystemZMCAsmInfo(const MCRegisterInfo &MRI,
98f4a2713aSLionel Sambuc                                          StringRef TT) {
99f4a2713aSLionel Sambuc   MCAsmInfo *MAI = new SystemZMCAsmInfo(TT);
100f4a2713aSLionel Sambuc   MCCFIInstruction Inst =
101*0a6a1f1dSLionel Sambuc       MCCFIInstruction::createDefCfa(nullptr,
102*0a6a1f1dSLionel Sambuc                                      MRI.getDwarfRegNum(SystemZ::R15D, true),
103f4a2713aSLionel Sambuc                                      SystemZMC::CFAOffsetFromInitialSP);
104f4a2713aSLionel Sambuc   MAI->addInitialFrameState(Inst);
105f4a2713aSLionel Sambuc   return MAI;
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc 
createSystemZMCInstrInfo()108f4a2713aSLionel Sambuc static MCInstrInfo *createSystemZMCInstrInfo() {
109f4a2713aSLionel Sambuc   MCInstrInfo *X = new MCInstrInfo();
110f4a2713aSLionel Sambuc   InitSystemZMCInstrInfo(X);
111f4a2713aSLionel Sambuc   return X;
112f4a2713aSLionel Sambuc }
113f4a2713aSLionel Sambuc 
createSystemZMCRegisterInfo(StringRef TT)114f4a2713aSLionel Sambuc static MCRegisterInfo *createSystemZMCRegisterInfo(StringRef TT) {
115f4a2713aSLionel Sambuc   MCRegisterInfo *X = new MCRegisterInfo();
116f4a2713aSLionel Sambuc   InitSystemZMCRegisterInfo(X, SystemZ::R14D);
117f4a2713aSLionel Sambuc   return X;
118f4a2713aSLionel Sambuc }
119f4a2713aSLionel Sambuc 
createSystemZMCSubtargetInfo(StringRef TT,StringRef CPU,StringRef FS)120f4a2713aSLionel Sambuc static MCSubtargetInfo *createSystemZMCSubtargetInfo(StringRef TT,
121f4a2713aSLionel Sambuc                                                      StringRef CPU,
122f4a2713aSLionel Sambuc                                                      StringRef FS) {
123f4a2713aSLionel Sambuc   MCSubtargetInfo *X = new MCSubtargetInfo();
124f4a2713aSLionel Sambuc   InitSystemZMCSubtargetInfo(X, TT, CPU, FS);
125f4a2713aSLionel Sambuc   return X;
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc 
createSystemZMCCodeGenInfo(StringRef TT,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)128f4a2713aSLionel Sambuc static MCCodeGenInfo *createSystemZMCCodeGenInfo(StringRef TT, Reloc::Model RM,
129f4a2713aSLionel Sambuc                                                  CodeModel::Model CM,
130f4a2713aSLionel Sambuc                                                  CodeGenOpt::Level OL) {
131f4a2713aSLionel Sambuc   MCCodeGenInfo *X = new MCCodeGenInfo();
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc   // Static code is suitable for use in a dynamic executable; there is no
134f4a2713aSLionel Sambuc   // separate DynamicNoPIC model.
135f4a2713aSLionel Sambuc   if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC)
136f4a2713aSLionel Sambuc     RM = Reloc::Static;
137f4a2713aSLionel Sambuc 
138f4a2713aSLionel Sambuc   // For SystemZ we define the models as follows:
139f4a2713aSLionel Sambuc   //
140f4a2713aSLionel Sambuc   // Small:  BRASL can call any function and will use a stub if necessary.
141f4a2713aSLionel Sambuc   //         Locally-binding symbols will always be in range of LARL.
142f4a2713aSLionel Sambuc   //
143f4a2713aSLionel Sambuc   // Medium: BRASL can call any function and will use a stub if necessary.
144f4a2713aSLionel Sambuc   //         GOT slots and locally-defined text will always be in range
145f4a2713aSLionel Sambuc   //         of LARL, but other symbols might not be.
146f4a2713aSLionel Sambuc   //
147f4a2713aSLionel Sambuc   // Large:  Equivalent to Medium for now.
148f4a2713aSLionel Sambuc   //
149f4a2713aSLionel Sambuc   // Kernel: Equivalent to Medium for now.
150f4a2713aSLionel Sambuc   //
151f4a2713aSLionel Sambuc   // This means that any PIC module smaller than 4GB meets the
152f4a2713aSLionel Sambuc   // requirements of Small, so Small seems like the best default there.
153f4a2713aSLionel Sambuc   //
154f4a2713aSLionel Sambuc   // All symbols bind locally in a non-PIC module, so the choice is less
155f4a2713aSLionel Sambuc   // obvious.  There are two cases:
156f4a2713aSLionel Sambuc   //
157f4a2713aSLionel Sambuc   // - When creating an executable, PLTs and copy relocations allow
158f4a2713aSLionel Sambuc   //   us to treat external symbols as part of the executable.
159f4a2713aSLionel Sambuc   //   Any executable smaller than 4GB meets the requirements of Small,
160f4a2713aSLionel Sambuc   //   so that seems like the best default.
161f4a2713aSLionel Sambuc   //
162f4a2713aSLionel Sambuc   // - When creating JIT code, stubs will be in range of BRASL if the
163f4a2713aSLionel Sambuc   //   image is less than 4GB in size.  GOT entries will likewise be
164f4a2713aSLionel Sambuc   //   in range of LARL.  However, the JIT environment has no equivalent
165f4a2713aSLionel Sambuc   //   of copy relocs, so locally-binding data symbols might not be in
166f4a2713aSLionel Sambuc   //   the range of LARL.  We need the Medium model in that case.
167f4a2713aSLionel Sambuc   if (CM == CodeModel::Default)
168f4a2713aSLionel Sambuc     CM = CodeModel::Small;
169f4a2713aSLionel Sambuc   else if (CM == CodeModel::JITDefault)
170f4a2713aSLionel Sambuc     CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
171f4a2713aSLionel Sambuc   X->InitMCCodeGenInfo(RM, CM, OL);
172f4a2713aSLionel Sambuc   return X;
173f4a2713aSLionel Sambuc }
174f4a2713aSLionel Sambuc 
createSystemZMCInstPrinter(const Target & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI,const MCSubtargetInfo & STI)175f4a2713aSLionel Sambuc static MCInstPrinter *createSystemZMCInstPrinter(const Target &T,
176f4a2713aSLionel Sambuc                                                  unsigned SyntaxVariant,
177f4a2713aSLionel Sambuc                                                  const MCAsmInfo &MAI,
178f4a2713aSLionel Sambuc                                                  const MCInstrInfo &MII,
179f4a2713aSLionel Sambuc                                                  const MCRegisterInfo &MRI,
180f4a2713aSLionel Sambuc                                                  const MCSubtargetInfo &STI) {
181f4a2713aSLionel Sambuc   return new SystemZInstPrinter(MAI, MII, MRI);
182f4a2713aSLionel Sambuc }
183f4a2713aSLionel Sambuc 
184*0a6a1f1dSLionel Sambuc static MCStreamer *
createSystemZMCObjectStreamer(const Target & T,StringRef TT,MCContext & Ctx,MCAsmBackend & MAB,raw_ostream & OS,MCCodeEmitter * Emitter,const MCSubtargetInfo & STI,bool RelaxAll)185*0a6a1f1dSLionel Sambuc createSystemZMCObjectStreamer(const Target &T, StringRef TT, MCContext &Ctx,
186*0a6a1f1dSLionel Sambuc                               MCAsmBackend &MAB, raw_ostream &OS,
187f4a2713aSLionel Sambuc                               MCCodeEmitter *Emitter,
188*0a6a1f1dSLionel Sambuc                               const MCSubtargetInfo &STI, bool RelaxAll) {
189*0a6a1f1dSLionel Sambuc   return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
190f4a2713aSLionel Sambuc }
191f4a2713aSLionel Sambuc 
LLVMInitializeSystemZTargetMC()192f4a2713aSLionel Sambuc extern "C" void LLVMInitializeSystemZTargetMC() {
193f4a2713aSLionel Sambuc   // Register the MCAsmInfo.
194f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCAsmInfo(TheSystemZTarget,
195f4a2713aSLionel Sambuc                                     createSystemZMCAsmInfo);
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc   // Register the MCCodeGenInfo.
198f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCCodeGenInfo(TheSystemZTarget,
199f4a2713aSLionel Sambuc                                         createSystemZMCCodeGenInfo);
200f4a2713aSLionel Sambuc 
201f4a2713aSLionel Sambuc   // Register the MCCodeEmitter.
202f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCCodeEmitter(TheSystemZTarget,
203f4a2713aSLionel Sambuc 					createSystemZMCCodeEmitter);
204f4a2713aSLionel Sambuc 
205f4a2713aSLionel Sambuc   // Register the MCInstrInfo.
206f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstrInfo(TheSystemZTarget,
207f4a2713aSLionel Sambuc                                       createSystemZMCInstrInfo);
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc   // Register the MCRegisterInfo.
210f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCRegInfo(TheSystemZTarget,
211f4a2713aSLionel Sambuc                                     createSystemZMCRegisterInfo);
212f4a2713aSLionel Sambuc 
213f4a2713aSLionel Sambuc   // Register the MCSubtargetInfo.
214f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCSubtargetInfo(TheSystemZTarget,
215f4a2713aSLionel Sambuc                                           createSystemZMCSubtargetInfo);
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc   // Register the MCAsmBackend.
218f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCAsmBackend(TheSystemZTarget,
219f4a2713aSLionel Sambuc                                        createSystemZMCAsmBackend);
220f4a2713aSLionel Sambuc 
221f4a2713aSLionel Sambuc   // Register the MCInstPrinter.
222f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstPrinter(TheSystemZTarget,
223f4a2713aSLionel Sambuc                                         createSystemZMCInstPrinter);
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc   // Register the MCObjectStreamer;
226f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCObjectStreamer(TheSystemZTarget,
227f4a2713aSLionel Sambuc                                            createSystemZMCObjectStreamer);
228f4a2713aSLionel Sambuc }
229