1234353Sdim//===-- SparcMCTargetDesc.cpp - Sparc Target Descriptions -----------------===//
2224133Sdim//
3224133Sdim//                     The LLVM Compiler Infrastructure
4224133Sdim//
5224133Sdim// This file is distributed under the University of Illinois Open Source
6224133Sdim// License. See LICENSE.TXT for details.
7224133Sdim//
8224133Sdim//===----------------------------------------------------------------------===//
9224133Sdim//
10224133Sdim// This file provides Sparc specific target descriptions.
11224133Sdim//
12224133Sdim//===----------------------------------------------------------------------===//
13224133Sdim
14224133Sdim#include "SparcMCTargetDesc.h"
15224133Sdim#include "SparcMCAsmInfo.h"
16263763Sdim#include "SparcTargetStreamer.h"
17263763Sdim#include "InstPrinter/SparcInstPrinter.h"
18226633Sdim#include "llvm/MC/MCCodeGenInfo.h"
19224133Sdim#include "llvm/MC/MCInstrInfo.h"
20224133Sdim#include "llvm/MC/MCRegisterInfo.h"
21224133Sdim#include "llvm/MC/MCSubtargetInfo.h"
22234353Sdim#include "llvm/Support/ErrorHandling.h"
23226633Sdim#include "llvm/Support/TargetRegistry.h"
24224133Sdim
25224133Sdim#define GET_INSTRINFO_MC_DESC
26224133Sdim#include "SparcGenInstrInfo.inc"
27224133Sdim
28224133Sdim#define GET_SUBTARGETINFO_MC_DESC
29224133Sdim#include "SparcGenSubtargetInfo.inc"
30224133Sdim
31224133Sdim#define GET_REGINFO_MC_DESC
32224133Sdim#include "SparcGenRegisterInfo.inc"
33224133Sdim
34224133Sdimusing namespace llvm;
35224133Sdim
36263763Sdim
37263763Sdimstatic MCAsmInfo *createSparcMCAsmInfo(const MCRegisterInfo &MRI,
38263763Sdim                                       StringRef TT) {
39263763Sdim  MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
40263763Sdim  unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
41263763Sdim  MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0);
42263763Sdim  MAI->addInitialFrameState(Inst);
43263763Sdim  return MAI;
44263763Sdim}
45263763Sdim
46263763Sdimstatic MCAsmInfo *createSparcV9MCAsmInfo(const MCRegisterInfo &MRI,
47263763Sdim                                       StringRef TT) {
48263763Sdim  MCAsmInfo *MAI = new SparcELFMCAsmInfo(TT);
49263763Sdim  unsigned Reg = MRI.getDwarfRegNum(SP::O6, true);
50263763Sdim  MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 2047);
51263763Sdim  MAI->addInitialFrameState(Inst);
52263763Sdim  return MAI;
53263763Sdim}
54263763Sdim
55224133Sdimstatic MCInstrInfo *createSparcMCInstrInfo() {
56224133Sdim  MCInstrInfo *X = new MCInstrInfo();
57224133Sdim  InitSparcMCInstrInfo(X);
58224133Sdim  return X;
59224133Sdim}
60224133Sdim
61226633Sdimstatic MCRegisterInfo *createSparcMCRegisterInfo(StringRef TT) {
62226633Sdim  MCRegisterInfo *X = new MCRegisterInfo();
63263763Sdim  InitSparcMCRegisterInfo(X, SP::O7);
64226633Sdim  return X;
65224133Sdim}
66224133Sdim
67224133Sdimstatic MCSubtargetInfo *createSparcMCSubtargetInfo(StringRef TT, StringRef CPU,
68224133Sdim                                                   StringRef FS) {
69224133Sdim  MCSubtargetInfo *X = new MCSubtargetInfo();
70224133Sdim  InitSparcMCSubtargetInfo(X, TT, CPU, FS);
71224133Sdim  return X;
72224133Sdim}
73224133Sdim
74251662Sdim// Code models. Some only make sense for 64-bit code.
75251662Sdim//
76251662Sdim// SunCC  Reloc   CodeModel  Constraints
77251662Sdim// abs32  Static  Small      text+data+bss linked below 2^32 bytes
78251662Sdim// abs44  Static  Medium     text+data+bss linked below 2^44 bytes
79251662Sdim// abs64  Static  Large      text smaller than 2^31 bytes
80251662Sdim// pic13  PIC_    Small      GOT < 2^13 bytes
81251662Sdim// pic32  PIC_    Medium     GOT < 2^32 bytes
82251662Sdim//
83251662Sdim// All code models require that the text segment is smaller than 2GB.
84251662Sdim
85226633Sdimstatic MCCodeGenInfo *createSparcMCCodeGenInfo(StringRef TT, Reloc::Model RM,
86234353Sdim                                               CodeModel::Model CM,
87234353Sdim                                               CodeGenOpt::Level OL) {
88226633Sdim  MCCodeGenInfo *X = new MCCodeGenInfo();
89251662Sdim
90263763Sdim  // The default 32-bit code model is abs32/pic32 and the default 32-bit
91263763Sdim  // code model for JIT is abs32.
92263763Sdim  switch (CM) {
93263763Sdim  default: break;
94263763Sdim  case CodeModel::Default:
95263763Sdim  case CodeModel::JITDefault: CM = CodeModel::Small; break;
96263763Sdim  }
97251662Sdim
98234353Sdim  X->InitMCCodeGenInfo(RM, CM, OL);
99226633Sdim  return X;
100224133Sdim}
101224133Sdim
102251662Sdimstatic MCCodeGenInfo *createSparcV9MCCodeGenInfo(StringRef TT, Reloc::Model RM,
103251662Sdim                                                 CodeModel::Model CM,
104251662Sdim                                                 CodeGenOpt::Level OL) {
105251662Sdim  MCCodeGenInfo *X = new MCCodeGenInfo();
106251662Sdim
107263763Sdim  // The default 64-bit code model is abs44/pic32 and the default 64-bit
108263763Sdim  // code model for JIT is abs64.
109263763Sdim  switch (CM) {
110263763Sdim  default:  break;
111263763Sdim  case CodeModel::Default:
112263763Sdim    CM = RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
113263763Sdim    break;
114263763Sdim  case CodeModel::JITDefault:
115263763Sdim    CM = CodeModel::Large;
116263763Sdim    break;
117263763Sdim  }
118251662Sdim
119251662Sdim  X->InitMCCodeGenInfo(RM, CM, OL);
120251662Sdim  return X;
121251662Sdim}
122263763Sdim
123263763Sdimstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT,
124263763Sdim                                    MCContext &Context, MCAsmBackend &MAB,
125263763Sdim                                    raw_ostream &OS, MCCodeEmitter *Emitter,
126263763Sdim                                    bool RelaxAll, bool NoExecStack) {
127263763Sdim  SparcTargetELFStreamer *S = new SparcTargetELFStreamer();
128263763Sdim  return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
129263763Sdim}
130263763Sdim
131263763Sdimstatic MCStreamer *
132263763SdimcreateMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
133263763Sdim                    bool isVerboseAsm, bool useLoc, bool useCFI,
134263763Sdim                    bool useDwarfDirectory, MCInstPrinter *InstPrint,
135263763Sdim                    MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
136263763Sdim  SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS);
137263763Sdim
138263763Sdim  return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
139263763Sdim                                 useDwarfDirectory, InstPrint, CE, TAB,
140263763Sdim                                 ShowInst);
141263763Sdim}
142263763Sdim
143263763Sdimstatic MCInstPrinter *createSparcMCInstPrinter(const Target &T,
144263763Sdim                                              unsigned SyntaxVariant,
145263763Sdim                                              const MCAsmInfo &MAI,
146263763Sdim                                              const MCInstrInfo &MII,
147263763Sdim                                              const MCRegisterInfo &MRI,
148263763Sdim                                              const MCSubtargetInfo &STI) {
149263763Sdim  return new SparcInstPrinter(MAI, MII, MRI);
150263763Sdim}
151263763Sdim
152226633Sdimextern "C" void LLVMInitializeSparcTargetMC() {
153226633Sdim  // Register the MC asm info.
154263763Sdim  RegisterMCAsmInfoFn X(TheSparcTarget, createSparcMCAsmInfo);
155263763Sdim  RegisterMCAsmInfoFn Y(TheSparcV9Target, createSparcV9MCAsmInfo);
156226633Sdim
157226633Sdim  // Register the MC codegen info.
158226633Sdim  TargetRegistry::RegisterMCCodeGenInfo(TheSparcTarget,
159226633Sdim                                       createSparcMCCodeGenInfo);
160226633Sdim  TargetRegistry::RegisterMCCodeGenInfo(TheSparcV9Target,
161251662Sdim                                       createSparcV9MCCodeGenInfo);
162226633Sdim
163226633Sdim  // Register the MC instruction info.
164226633Sdim  TargetRegistry::RegisterMCInstrInfo(TheSparcTarget, createSparcMCInstrInfo);
165263763Sdim  TargetRegistry::RegisterMCInstrInfo(TheSparcV9Target, createSparcMCInstrInfo);
166226633Sdim
167226633Sdim  // Register the MC register info.
168226633Sdim  TargetRegistry::RegisterMCRegInfo(TheSparcTarget, createSparcMCRegisterInfo);
169263763Sdim  TargetRegistry::RegisterMCRegInfo(TheSparcV9Target,
170263763Sdim                                    createSparcMCRegisterInfo);
171226633Sdim
172226633Sdim  // Register the MC subtarget info.
173226633Sdim  TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
174226633Sdim                                          createSparcMCSubtargetInfo);
175263763Sdim  TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
176263763Sdim                                          createSparcMCSubtargetInfo);
177263763Sdim
178263763Sdim  // Register the MC Code Emitter.
179263763Sdim  TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget,
180263763Sdim                                        createSparcMCCodeEmitter);
181263763Sdim  TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target,
182263763Sdim                                        createSparcMCCodeEmitter);
183263763Sdim
184263763Sdim  //Register the asm backend.
185263763Sdim  TargetRegistry::RegisterMCAsmBackend(TheSparcTarget,
186263763Sdim                                       createSparcAsmBackend);
187263763Sdim  TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
188263763Sdim                                       createSparcAsmBackend);
189263763Sdim
190263763Sdim  // Register the object streamer.
191263763Sdim  TargetRegistry::RegisterMCObjectStreamer(TheSparcTarget,
192263763Sdim                                           createMCStreamer);
193263763Sdim  TargetRegistry::RegisterMCObjectStreamer(TheSparcV9Target,
194263763Sdim                                           createMCStreamer);
195263763Sdim
196263763Sdim  // Register the asm streamer.
197263763Sdim  TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
198263763Sdim                                      createMCAsmStreamer);
199263763Sdim  TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
200263763Sdim                                      createMCAsmStreamer);
201263763Sdim
202263763Sdim  // Register the MCInstPrinter
203263763Sdim  TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
204263763Sdim                                        createSparcMCInstPrinter);
205263763Sdim  TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
206263763Sdim                                        createSparcMCInstPrinter);
207224133Sdim}
208