1//===-- SystemZMCTargetDesc.cpp - SystemZ 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#include "SystemZMCTargetDesc.h"
11#include "InstPrinter/SystemZInstPrinter.h"
12#include "SystemZMCAsmInfo.h"
13#include "llvm/MC/MCCodeGenInfo.h"
14#include "llvm/MC/MCInstrInfo.h"
15#include "llvm/MC/MCStreamer.h"
16#include "llvm/MC/MCSubtargetInfo.h"
17#include "llvm/Support/TargetRegistry.h"
18
19#define GET_INSTRINFO_MC_DESC
20#include "SystemZGenInstrInfo.inc"
21
22#define GET_SUBTARGETINFO_MC_DESC
23#include "SystemZGenSubtargetInfo.inc"
24
25#define GET_REGINFO_MC_DESC
26#include "SystemZGenRegisterInfo.inc"
27
28using namespace llvm;
29
30static MCAsmInfo *createSystemZMCAsmInfo(const Target &T, StringRef TT) {
31  MCAsmInfo *MAI = new SystemZMCAsmInfo(T, TT);
32  MachineLocation FPDst(MachineLocation::VirtualFP);
33  MachineLocation FPSrc(SystemZ::R15D, -SystemZMC::CFAOffsetFromInitialSP);
34  MAI->addInitialFrameState(0, FPDst, FPSrc);
35  return MAI;
36}
37
38static MCInstrInfo *createSystemZMCInstrInfo() {
39  MCInstrInfo *X = new MCInstrInfo();
40  InitSystemZMCInstrInfo(X);
41  return X;
42}
43
44static MCRegisterInfo *createSystemZMCRegisterInfo(StringRef TT) {
45  MCRegisterInfo *X = new MCRegisterInfo();
46  InitSystemZMCRegisterInfo(X, SystemZ::R14D);
47  return X;
48}
49
50static MCSubtargetInfo *createSystemZMCSubtargetInfo(StringRef TT,
51                                                     StringRef CPU,
52                                                     StringRef FS) {
53  MCSubtargetInfo *X = new MCSubtargetInfo();
54  InitSystemZMCSubtargetInfo(X, TT, CPU, FS);
55  return X;
56}
57
58static MCCodeGenInfo *createSystemZMCCodeGenInfo(StringRef TT, Reloc::Model RM,
59                                                 CodeModel::Model CM,
60                                                 CodeGenOpt::Level OL) {
61  MCCodeGenInfo *X = new MCCodeGenInfo();
62
63  // Static code is suitable for use in a dynamic executable; there is no
64  // separate DynamicNoPIC model.
65  if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC)
66    RM = Reloc::Static;
67
68  // For SystemZ we define the models as follows:
69  //
70  // Small:  BRASL can call any function and will use a stub if necessary.
71  //         Locally-binding symbols will always be in range of LARL.
72  //
73  // Medium: BRASL can call any function and will use a stub if necessary.
74  //         GOT slots and locally-defined text will always be in range
75  //         of LARL, but other symbols might not be.
76  //
77  // Large:  Equivalent to Medium for now.
78  //
79  // Kernel: Equivalent to Medium for now.
80  //
81  // This means that any PIC module smaller than 4GB meets the
82  // requirements of Small, so Small seems like the best default there.
83  //
84  // All symbols bind locally in a non-PIC module, so the choice is less
85  // obvious.  There are two cases:
86  //
87  // - When creating an executable, PLTs and copy relocations allow
88  //   us to treat external symbols as part of the executable.
89  //   Any executable smaller than 4GB meets the requirements of Small,
90  //   so that seems like the best default.
91  //
92  // - When creating JIT code, stubs will be in range of BRASL if the
93  //   image is less than 4GB in size.  GOT entries will likewise be
94  //   in range of LARL.  However, the JIT environment has no equivalent
95  //   of copy relocs, so locally-binding data symbols might not be in
96  //   the range of LARL.  We need the Medium model in that case.
97  if (CM == CodeModel::Default)
98    CM = CodeModel::Small;
99  else if (CM == CodeModel::JITDefault)
100    CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
101  X->InitMCCodeGenInfo(RM, CM, OL);
102  return X;
103}
104
105static MCInstPrinter *createSystemZMCInstPrinter(const Target &T,
106                                                 unsigned SyntaxVariant,
107                                                 const MCAsmInfo &MAI,
108                                                 const MCInstrInfo &MII,
109                                                 const MCRegisterInfo &MRI,
110                                                 const MCSubtargetInfo &STI) {
111  return new SystemZInstPrinter(MAI, MII, MRI);
112}
113
114static MCStreamer *createSystemZMCObjectStreamer(const Target &T, StringRef TT,
115                                                 MCContext &Ctx,
116                                                 MCAsmBackend &MAB,
117                                                 raw_ostream &OS,
118                                                 MCCodeEmitter *Emitter,
119                                                 bool RelaxAll,
120                                                 bool NoExecStack) {
121  return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
122}
123
124extern "C" void LLVMInitializeSystemZTargetMC() {
125  // Register the MCAsmInfo.
126  TargetRegistry::RegisterMCAsmInfo(TheSystemZTarget,
127                                    createSystemZMCAsmInfo);
128
129  // Register the MCCodeGenInfo.
130  TargetRegistry::RegisterMCCodeGenInfo(TheSystemZTarget,
131                                        createSystemZMCCodeGenInfo);
132
133  // Register the MCCodeEmitter.
134  TargetRegistry::RegisterMCCodeEmitter(TheSystemZTarget,
135					createSystemZMCCodeEmitter);
136
137  // Register the MCInstrInfo.
138  TargetRegistry::RegisterMCInstrInfo(TheSystemZTarget,
139                                      createSystemZMCInstrInfo);
140
141  // Register the MCRegisterInfo.
142  TargetRegistry::RegisterMCRegInfo(TheSystemZTarget,
143                                    createSystemZMCRegisterInfo);
144
145  // Register the MCSubtargetInfo.
146  TargetRegistry::RegisterMCSubtargetInfo(TheSystemZTarget,
147                                          createSystemZMCSubtargetInfo);
148
149  // Register the MCAsmBackend.
150  TargetRegistry::RegisterMCAsmBackend(TheSystemZTarget,
151                                       createSystemZMCAsmBackend);
152
153  // Register the MCInstPrinter.
154  TargetRegistry::RegisterMCInstPrinter(TheSystemZTarget,
155                                        createSystemZMCInstPrinter);
156
157  // Register the MCObjectStreamer;
158  TargetRegistry::RegisterMCObjectStreamer(TheSystemZTarget,
159                                           createSystemZMCObjectStreamer);
160}
161