1263320SdimPull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
4263320Sdim
5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
6263320Sdim
7263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
8263320Sdim===================================================================
9263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
10263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
11263320Sdim@@ -0,0 +1,40 @@
12263320Sdim+//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===//
13263320Sdim+//
14263320Sdim+//                     The LLVM Compiler Infrastructure
15263320Sdim+//
16263320Sdim+// This file is distributed under the University of Illinois Open Source
17263320Sdim+// License. See LICENSE.TXT for details.
18263320Sdim+//
19263320Sdim+//===----------------------------------------------------------------------===//
20263320Sdim+//
21263320Sdim+// This file provides Sparc specific target streamer methods.
22263320Sdim+//
23263320Sdim+//===----------------------------------------------------------------------===//
24263320Sdim+
25263320Sdim+#include "SparcTargetStreamer.h"
26263320Sdim+#include "InstPrinter/SparcInstPrinter.h"
27263320Sdim+#include "llvm/Support/FormattedStream.h"
28263320Sdim+
29263320Sdim+using namespace llvm;
30263320Sdim+
31263320Sdim+// pin vtable to this file
32263320Sdim+void SparcTargetStreamer::anchor() {}
33263320Sdim+
34263320Sdim+SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS)
35263320Sdim+    : OS(OS) {}
36263320Sdim+
37263320Sdim+void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) {
38263320Sdim+  OS << "\t.register "
39263320Sdim+     << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
40263320Sdim+     << ", #ignore\n";
41263320Sdim+}
42263320Sdim+
43263320Sdim+void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) {
44263320Sdim+  OS << "\t.register "
45263320Sdim+     << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
46263320Sdim+     << ", #scratch\n";
47263320Sdim+}
48263320Sdim+
49263320Sdim+MCELFStreamer &SparcTargetELFStreamer::getStreamer() {
50263320Sdim+  return static_cast<MCELFStreamer &>(*Streamer);
51263320Sdim+}
52263320SdimIndex: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
53263320Sdim===================================================================
54263320Sdim--- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
55263320Sdim+++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
56263320Sdim@@ -19,5 +19,5 @@
57263320Sdim type = Library
58263320Sdim name = SparcDesc
59263320Sdim parent = Sparc
60263320Sdim-required_libraries = MC SparcInfo Support
61263320Sdim+required_libraries = MC SparcAsmPrinter SparcInfo Support
62263320Sdim add_to_library_groups = Sparc
63263320SdimIndex: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
64263320Sdim===================================================================
65263320Sdim--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
66263320Sdim+++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
67263320Sdim@@ -2,6 +2,7 @@ add_llvm_library(LLVMSparcDesc
68263320Sdim   SparcMCTargetDesc.cpp
69263320Sdim   SparcMCAsmInfo.cpp
70263320Sdim   SparcMCExpr.cpp
71263320Sdim+  SparcTargetStreamer.cpp
72263320Sdim   )
73263320Sdim 
74263320Sdim add_dependencies(LLVMSparcDesc SparcCommonTableGen)
75263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
76263320Sdim===================================================================
77263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
78263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
79263320Sdim@@ -13,6 +13,8 @@
80263320Sdim 
81263320Sdim #include "SparcMCTargetDesc.h"
82263320Sdim #include "SparcMCAsmInfo.h"
83263320Sdim+#include "SparcTargetStreamer.h"
84263320Sdim+#include "InstPrinter/SparcInstPrinter.h"
85263320Sdim #include "llvm/MC/MCCodeGenInfo.h"
86263320Sdim #include "llvm/MC/MCInstrInfo.h"
87263320Sdim #include "llvm/MC/MCRegisterInfo.h"
88263320Sdim@@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
89263320Sdim   X->InitMCCodeGenInfo(RM, CM, OL);
90263320Sdim   return X;
91263320Sdim }
92263320Sdim+
93263320Sdim+static MCStreamer *
94263320Sdim+createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
95263320Sdim+                    bool isVerboseAsm, bool useLoc, bool useCFI,
96263320Sdim+                    bool useDwarfDirectory, MCInstPrinter *InstPrint,
97263320Sdim+                    MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
98263320Sdim+  SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS);
99263320Sdim+
100263320Sdim+  return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
101263320Sdim+                                 useDwarfDirectory, InstPrint, CE, TAB,
102263320Sdim+                                 ShowInst);
103263320Sdim+}
104263320Sdim+
105263320Sdim+static MCInstPrinter *createSparcMCInstPrinter(const Target &T,
106263320Sdim+                                              unsigned SyntaxVariant,
107263320Sdim+                                              const MCAsmInfo &MAI,
108263320Sdim+                                              const MCInstrInfo &MII,
109263320Sdim+                                              const MCRegisterInfo &MRI,
110263320Sdim+                                              const MCSubtargetInfo &STI) {
111263320Sdim+  return new SparcInstPrinter(MAI, MII, MRI);
112263320Sdim+}
113263320Sdim+
114263320Sdim extern "C" void LLVMInitializeSparcTargetMC() {
115263320Sdim   // Register the MC asm info.
116263320Sdim   RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget);
117263320Sdim@@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() {
118263320Sdim   // Register the MC subtarget info.
119263320Sdim   TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
120263320Sdim                                           createSparcMCSubtargetInfo);
121263320Sdim+
122263320Sdim+  TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
123263320Sdim+                                      createMCAsmStreamer);
124263320Sdim+  TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
125263320Sdim+                                      createMCAsmStreamer);
126263320Sdim+
127263320Sdim+  // Register the MCInstPrinter
128263320Sdim+  TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
129263320Sdim+                                        createSparcMCInstPrinter);
130263320Sdim+  TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
131263320Sdim+                                        createSparcMCInstPrinter);
132263320Sdim }
133263320SdimIndex: lib/Target/Sparc/SparcTargetStreamer.h
134263320Sdim===================================================================
135263320Sdim--- lib/Target/Sparc/SparcTargetStreamer.h
136263320Sdim+++ lib/Target/Sparc/SparcTargetStreamer.h
137263320Sdim@@ -0,0 +1,47 @@
138263320Sdim+//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===//
139263320Sdim+//
140263320Sdim+//                     The LLVM Compiler Infrastructure
141263320Sdim+//
142263320Sdim+// This file is distributed under the University of Illinois Open Source
143263320Sdim+// License. See LICENSE.TXT for details.
144263320Sdim+//
145263320Sdim+//===----------------------------------------------------------------------===//
146263320Sdim+
147263320Sdim+#ifndef SPARCTARGETSTREAMER_H
148263320Sdim+#define SPARCTARGETSTREAMER_H
149263320Sdim+
150263320Sdim+#include "llvm/MC/MCELFStreamer.h"
151263320Sdim+#include "llvm/MC/MCStreamer.h"
152263320Sdim+
153263320Sdim+namespace llvm {
154263320Sdim+class SparcTargetStreamer : public MCTargetStreamer {
155263320Sdim+  virtual void anchor();
156263320Sdim+
157263320Sdim+public:
158263320Sdim+  /// Emit ".register <reg>, #ignore".
159263320Sdim+  virtual void emitSparcRegisterIgnore(unsigned reg) = 0;
160263320Sdim+  /// Emit ".register <reg>, #scratch".
161263320Sdim+  virtual void emitSparcRegisterScratch(unsigned reg) = 0;
162263320Sdim+};
163263320Sdim+
164263320Sdim+// This part is for ascii assembly output
165263320Sdim+class SparcTargetAsmStreamer : public SparcTargetStreamer {
166263320Sdim+  formatted_raw_ostream &OS;
167263320Sdim+
168263320Sdim+public:
169263320Sdim+  SparcTargetAsmStreamer(formatted_raw_ostream &OS);
170263320Sdim+  virtual void emitSparcRegisterIgnore(unsigned reg);
171263320Sdim+  virtual void emitSparcRegisterScratch(unsigned reg);
172263320Sdim+
173263320Sdim+};
174263320Sdim+
175263320Sdim+// This part is for ELF object output
176263320Sdim+class SparcTargetELFStreamer : public SparcTargetStreamer {
177263320Sdim+public:
178263320Sdim+  MCELFStreamer &getStreamer();
179263320Sdim+  virtual void emitSparcRegisterIgnore(unsigned reg) {}
180263320Sdim+  virtual void emitSparcRegisterScratch(unsigned reg) {}
181263320Sdim+};
182263320Sdim+} // end namespace llvm
183263320Sdim+
184263320Sdim+#endif
185263320SdimIndex: lib/Target/Sparc/CMakeLists.txt
186263320Sdim===================================================================
187263320Sdim--- lib/Target/Sparc/CMakeLists.txt
188263320Sdim+++ lib/Target/Sparc/CMakeLists.txt
189263320Sdim@@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen
190263320Sdim   SparcSelectionDAGInfo.cpp
191263320Sdim   SparcJITInfo.cpp
192263320Sdim   SparcCodeEmitter.cpp
193263320Sdim+  SparcMCInstLower.cpp
194263320Sdim   )
195263320Sdim 
196263320Sdim add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen)
197263320SdimIndex: lib/Target/Sparc/Sparc.td
198263320Sdim===================================================================
199263320Sdim--- lib/Target/Sparc/Sparc.td
200263320Sdim+++ lib/Target/Sparc/Sparc.td
201263320Sdim@@ -65,6 +65,10 @@ def : Proc<"ultrasparc",      [FeatureV9, FeatureV
202263320Sdim def : Proc<"ultrasparc3",     [FeatureV9, FeatureV8Deprecated]>;
203263320Sdim def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
204263320Sdim 
205263320Sdim+def SparcAsmWriter : AsmWriter {
206263320Sdim+  string AsmWriterClassName  = "InstPrinter";
207263320Sdim+  bit isMCAsmWriter = 1;
208263320Sdim+}
209263320Sdim 
210263320Sdim //===----------------------------------------------------------------------===//
211263320Sdim // Declare the target which we are implementing
212263320Sdim@@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV
213263320Sdim def Sparc : Target {
214263320Sdim   // Pull in Instruction Info:
215263320Sdim   let InstructionSet = SparcInstrInfo;
216263320Sdim+
217263320Sdim+  let AssemblyWriters = [SparcAsmWriter];
218263320Sdim }
219263320SdimIndex: lib/Target/Sparc/SparcMCInstLower.cpp
220263320Sdim===================================================================
221263320Sdim--- lib/Target/Sparc/SparcMCInstLower.cpp
222263320Sdim+++ lib/Target/Sparc/SparcMCInstLower.cpp
223263320Sdim@@ -0,0 +1,141 @@
224263320Sdim+//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
225263320Sdim+//
226263320Sdim+//                     The LLVM Compiler Infrastructure
227263320Sdim+//
228263320Sdim+// This file is distributed under the University of Illinois Open Source
229263320Sdim+// License. See LICENSE.TXT for details.
230263320Sdim+//
231263320Sdim+//===----------------------------------------------------------------------===//
232263320Sdim+//
233263320Sdim+// This file contains code to lower Sparc MachineInstrs to their corresponding
234263320Sdim+// MCInst records.
235263320Sdim+//
236263320Sdim+//===----------------------------------------------------------------------===//
237263320Sdim+
238263320Sdim+#include "Sparc.h"
239263320Sdim+#include "MCTargetDesc/SparcBaseInfo.h"
240263320Sdim+#include "MCTargetDesc/SparcMCExpr.h"
241263320Sdim+#include "llvm/CodeGen/AsmPrinter.h"
242263320Sdim+#include "llvm/CodeGen/MachineFunction.h"
243263320Sdim+#include "llvm/CodeGen/MachineInstr.h"
244263320Sdim+#include "llvm/CodeGen/MachineOperand.h"
245263320Sdim+#include "llvm/MC/MCContext.h"
246263320Sdim+#include "llvm/MC/MCAsmInfo.h"
247263320Sdim+#include "llvm/MC/MCExpr.h"
248263320Sdim+#include "llvm/MC/MCInst.h"
249263320Sdim+#include "llvm/Target/Mangler.h"
250263320Sdim+#include "llvm/ADT/SmallString.h"
251263320Sdim+
252263320Sdim+using namespace llvm;
253263320Sdim+
254263320Sdim+
255263320Sdim+static MCOperand LowerSymbolOperand(const MachineInstr *MI,
256263320Sdim+                                    const MachineOperand &MO,
257263320Sdim+                                    AsmPrinter &AP) {
258263320Sdim+
259263320Sdim+  SparcMCExpr::VariantKind Kind;
260263320Sdim+  const MCSymbol *Symbol = 0;
261263320Sdim+
262263320Sdim+  unsigned TF = MO.getTargetFlags();
263263320Sdim+
264263320Sdim+  switch(TF) {
265263320Sdim+  default:      llvm_unreachable("Unknown target flags on operand");
266263320Sdim+  case SPII::MO_NO_FLAG:      Kind = SparcMCExpr::VK_Sparc_None; break;
267263320Sdim+  case SPII::MO_LO:           Kind = SparcMCExpr::VK_Sparc_LO; break;
268263320Sdim+  case SPII::MO_HI:           Kind = SparcMCExpr::VK_Sparc_HI; break;
269263320Sdim+  case SPII::MO_H44:          Kind = SparcMCExpr::VK_Sparc_H44; break;
270263320Sdim+  case SPII::MO_M44:          Kind = SparcMCExpr::VK_Sparc_M44; break;
271263320Sdim+  case SPII::MO_L44:          Kind = SparcMCExpr::VK_Sparc_L44; break;
272263320Sdim+  case SPII::MO_HH:           Kind = SparcMCExpr::VK_Sparc_HH; break;
273263320Sdim+  case SPII::MO_HM:           Kind = SparcMCExpr::VK_Sparc_HM; break;
274263320Sdim+  case SPII::MO_TLS_GD_HI22:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break;
275263320Sdim+  case SPII::MO_TLS_GD_LO10:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break;
276263320Sdim+  case SPII::MO_TLS_GD_ADD:   Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break;
277263320Sdim+  case SPII::MO_TLS_GD_CALL:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break;
278263320Sdim+  case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break;
279263320Sdim+  case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break;
280263320Sdim+  case SPII::MO_TLS_LDM_ADD:  Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break;
281263320Sdim+  case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break;
282263320Sdim+  case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break;
283263320Sdim+  case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break;
284263320Sdim+  case SPII::MO_TLS_LDO_ADD:  Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break;
285263320Sdim+  case SPII::MO_TLS_IE_HI22:  Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break;
286263320Sdim+  case SPII::MO_TLS_IE_LO10:  Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break;
287263320Sdim+  case SPII::MO_TLS_IE_LD:    Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break;
288263320Sdim+  case SPII::MO_TLS_IE_LDX:   Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break;
289263320Sdim+  case SPII::MO_TLS_IE_ADD:   Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break;
290263320Sdim+  case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break;
291263320Sdim+  case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break;
292263320Sdim+  }
293263320Sdim+
294263320Sdim+  switch(MO.getType()) {
295263320Sdim+  default: llvm_unreachable("Unknown type in LowerSymbolOperand");
296263320Sdim+  case MachineOperand::MO_MachineBasicBlock:
297263320Sdim+    Symbol = MO.getMBB()->getSymbol();
298263320Sdim+    break;
299263320Sdim+
300263320Sdim+  case MachineOperand::MO_GlobalAddress:
301263320Sdim+    Symbol = AP.getSymbol(MO.getGlobal());
302263320Sdim+    break;
303263320Sdim+
304263320Sdim+  case MachineOperand::MO_BlockAddress:
305263320Sdim+    Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
306263320Sdim+    break;
307263320Sdim+
308263320Sdim+  case MachineOperand::MO_ExternalSymbol:
309263320Sdim+    Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
310263320Sdim+    break;
311263320Sdim+
312263320Sdim+  case MachineOperand::MO_ConstantPoolIndex:
313263320Sdim+    Symbol = AP.GetCPISymbol(MO.getIndex());
314263320Sdim+    break;
315263320Sdim+  }
316263320Sdim+
317263320Sdim+  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
318263320Sdim+                                                         AP.OutContext);
319263320Sdim+  const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
320263320Sdim+                                                AP.OutContext);
321263320Sdim+  return MCOperand::CreateExpr(expr);
322263320Sdim+}
323263320Sdim+
324263320Sdim+static MCOperand LowerOperand(const MachineInstr *MI,
325263320Sdim+                              const MachineOperand &MO,
326263320Sdim+                              AsmPrinter &AP) {
327263320Sdim+  switch(MO.getType()) {
328263320Sdim+  default: llvm_unreachable("unknown operand type"); break;
329263320Sdim+  case MachineOperand::MO_Register:
330263320Sdim+    if (MO.isImplicit())
331263320Sdim+      break;
332263320Sdim+    return MCOperand::CreateReg(MO.getReg());
333263320Sdim+
334263320Sdim+  case MachineOperand::MO_Immediate:
335263320Sdim+    return MCOperand::CreateImm(MO.getImm());
336263320Sdim+
337263320Sdim+  case MachineOperand::MO_MachineBasicBlock:
338263320Sdim+  case MachineOperand::MO_GlobalAddress:
339263320Sdim+  case MachineOperand::MO_BlockAddress:
340263320Sdim+  case MachineOperand::MO_ExternalSymbol:
341263320Sdim+  case MachineOperand::MO_ConstantPoolIndex:
342263320Sdim+    return LowerSymbolOperand(MI, MO, AP);
343263320Sdim+
344263320Sdim+  case MachineOperand::MO_RegisterMask:   break;
345263320Sdim+
346263320Sdim+  }
347263320Sdim+  return MCOperand();
348263320Sdim+}
349263320Sdim+
350263320Sdim+void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
351263320Sdim+                                          MCInst &OutMI,
352263320Sdim+                                          AsmPrinter &AP)
353263320Sdim+{
354263320Sdim+
355263320Sdim+  OutMI.setOpcode(MI->getOpcode());
356263320Sdim+
357263320Sdim+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
358263320Sdim+    const MachineOperand &MO = MI->getOperand(i);
359263320Sdim+    MCOperand MCOp = LowerOperand(MI, MO, AP);
360263320Sdim+
361263320Sdim+    if (MCOp.isValid())
362263320Sdim+      OutMI.addOperand(MCOp);
363263320Sdim+  }
364263320Sdim+}
365263320SdimIndex: lib/Target/Sparc/Sparc.h
366263320Sdim===================================================================
367263320Sdim--- lib/Target/Sparc/Sparc.h
368263320Sdim+++ lib/Target/Sparc/Sparc.h
369263320Sdim@@ -23,6 +23,9 @@ namespace llvm {
370263320Sdim   class FunctionPass;
371263320Sdim   class SparcTargetMachine;
372263320Sdim   class formatted_raw_ostream;
373263320Sdim+  class AsmPrinter;
374263320Sdim+  class MCInst;
375263320Sdim+  class MachineInstr;
376263320Sdim 
377263320Sdim   FunctionPass *createSparcISelDag(SparcTargetMachine &TM);
378263320Sdim   FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM);
379263320Sdim@@ -29,6 +32,9 @@ namespace llvm {
380263320Sdim   FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
381263320Sdim                                               JITCodeEmitter &JCE);
382263320Sdim 
383263320Sdim+  void LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
384263320Sdim+                                      MCInst &OutMI,
385263320Sdim+                                      AsmPrinter &AP);
386263320Sdim } // end namespace llvm;
387263320Sdim 
388263320Sdim namespace llvm {
389263320SdimIndex: lib/Target/Sparc/SparcAsmPrinter.cpp
390263320Sdim===================================================================
391263320Sdim--- lib/Target/Sparc/SparcAsmPrinter.cpp
392263320Sdim+++ lib/Target/Sparc/SparcAsmPrinter.cpp
393263320Sdim@@ -16,12 +16,17 @@
394263320Sdim #include "Sparc.h"
395263320Sdim #include "SparcInstrInfo.h"
396263320Sdim #include "SparcTargetMachine.h"
397263320Sdim+#include "SparcTargetStreamer.h"
398263320Sdim+#include "InstPrinter/SparcInstPrinter.h"
399263320Sdim #include "MCTargetDesc/SparcBaseInfo.h"
400263320Sdim+#include "MCTargetDesc/SparcMCExpr.h"
401263320Sdim #include "llvm/ADT/SmallString.h"
402263320Sdim #include "llvm/CodeGen/AsmPrinter.h"
403263320Sdim #include "llvm/CodeGen/MachineInstr.h"
404263320Sdim #include "llvm/CodeGen/MachineRegisterInfo.h"
405263320Sdim #include "llvm/MC/MCAsmInfo.h"
406263320Sdim+#include "llvm/MC/MCContext.h"
407263320Sdim+#include "llvm/MC/MCInst.h"
408263320Sdim #include "llvm/MC/MCStreamer.h"
409263320Sdim #include "llvm/MC/MCSymbol.h"
410263320Sdim #include "llvm/Support/TargetRegistry.h"
411263320Sdim@@ -31,6 +36,9 @@ using namespace llvm;
412263320Sdim 
413263320Sdim namespace {
414263320Sdim   class SparcAsmPrinter : public AsmPrinter {
415263320Sdim+    SparcTargetStreamer &getTargetStreamer() {
416263320Sdim+      return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer());
417263320Sdim+    }
418263320Sdim   public:
419263320Sdim     explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
420263320Sdim       : AsmPrinter(TM, Streamer) {}
421263320Sdim@@ -45,14 +53,11 @@ namespace {
422263320Sdim     void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
423263320Sdim 
424263320Sdim     virtual void EmitFunctionBodyStart();
425263320Sdim-    virtual void EmitInstruction(const MachineInstr *MI) {
426263320Sdim-      SmallString<128> Str;
427263320Sdim-      raw_svector_ostream OS(Str);
428263320Sdim-      printInstruction(MI, OS);
429263320Sdim-      OutStreamer.EmitRawText(OS.str());
430263320Sdim+    virtual void EmitInstruction(const MachineInstr *MI);
431263320Sdim+
432263320Sdim+    static const char *getRegisterName(unsigned RegNo) {
433263320Sdim+      return SparcInstPrinter::getRegisterName(RegNo);
434263320Sdim     }
435263320Sdim-    void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
436263320Sdim-    static const char *getRegisterName(unsigned RegNo);
437263320Sdim 
438263320Sdim     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
439263320Sdim                          unsigned AsmVariant, const char *ExtraCode,
440263320Sdim@@ -61,25 +66,139 @@ namespace {
441263320Sdim                                unsigned AsmVariant, const char *ExtraCode,
442263320Sdim                                raw_ostream &O);
443263320Sdim 
444263320Sdim-    bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
445263320Sdim-
446263320Sdim     virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
447263320Sdim                        const;
448263320Sdim-    void EmitGlobalRegisterDecl(unsigned reg) {
449263320Sdim-      SmallString<128> Str;
450263320Sdim-      raw_svector_ostream OS(Str);
451263320Sdim-      OS << "\t.register "
452263320Sdim-         << "%" << StringRef(getRegisterName(reg)).lower()
453263320Sdim-         << ", "
454263320Sdim-         << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
455263320Sdim-      OutStreamer.EmitRawText(OS.str());
456263320Sdim-    }
457263320Sdim 
458263320Sdim   };
459263320Sdim } // end of anonymous namespace
460263320Sdim 
461263320Sdim-#include "SparcGenAsmWriter.inc"
462263320Sdim+static MCOperand createPCXCallOP(MCSymbol *Label,
463263320Sdim+                                 MCContext &OutContext)
464263320Sdim+{
465263320Sdim+  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
466263320Sdim+                                                         OutContext);
467263320Sdim+  const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
468263320Sdim+                                                MCSym, OutContext);
469263320Sdim+  return MCOperand::CreateExpr(expr);
470263320Sdim+}
471263320Sdim 
472263320Sdim+static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
473263320Sdim+                                    MCSymbol *GOTLabel, MCSymbol *StartLabel,
474263320Sdim+                                    MCSymbol *CurLabel,
475263320Sdim+                                    MCContext &OutContext)
476263320Sdim+{
477263320Sdim+  const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext);
478263320Sdim+  const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel,
479263320Sdim+                                                         OutContext);
480263320Sdim+  const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel,
481263320Sdim+                                                       OutContext);
482263320Sdim+
483263320Sdim+  const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext);
484263320Sdim+  const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext);
485263320Sdim+  const SparcMCExpr *expr = SparcMCExpr::Create(Kind,
486263320Sdim+                                                Add, OutContext);
487263320Sdim+  return MCOperand::CreateExpr(expr);
488263320Sdim+}
489263320Sdim+
490263320Sdim+static void EmitCall(MCStreamer &OutStreamer,
491263320Sdim+                     MCOperand &Callee)
492263320Sdim+{
493263320Sdim+  MCInst CallInst;
494263320Sdim+  CallInst.setOpcode(SP::CALL);
495263320Sdim+  CallInst.addOperand(Callee);
496263320Sdim+  OutStreamer.EmitInstruction(CallInst);
497263320Sdim+}
498263320Sdim+
499263320Sdim+static void EmitSETHI(MCStreamer &OutStreamer,
500263320Sdim+                      MCOperand &Imm, MCOperand &RD)
501263320Sdim+{
502263320Sdim+  MCInst SETHIInst;
503263320Sdim+  SETHIInst.setOpcode(SP::SETHIi);
504263320Sdim+  SETHIInst.addOperand(RD);
505263320Sdim+  SETHIInst.addOperand(Imm);
506263320Sdim+  OutStreamer.EmitInstruction(SETHIInst);
507263320Sdim+}
508263320Sdim+
509263320Sdim+static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
510263320Sdim+                   MCOperand &Imm, MCOperand &RD)
511263320Sdim+{
512263320Sdim+  MCInst ORInst;
513263320Sdim+  ORInst.setOpcode(SP::ORri);
514263320Sdim+  ORInst.addOperand(RD);
515263320Sdim+  ORInst.addOperand(RS1);
516263320Sdim+  ORInst.addOperand(Imm);
517263320Sdim+  OutStreamer.EmitInstruction(ORInst);
518263320Sdim+}
519263320Sdim+
520263320Sdim+void EmitADD(MCStreamer &OutStreamer,
521263320Sdim+             MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
522263320Sdim+{
523263320Sdim+  MCInst ADDInst;
524263320Sdim+  ADDInst.setOpcode(SP::ADDrr);
525263320Sdim+  ADDInst.addOperand(RD);
526263320Sdim+  ADDInst.addOperand(RS1);
527263320Sdim+  ADDInst.addOperand(RS2);
528263320Sdim+  OutStreamer.EmitInstruction(ADDInst);
529263320Sdim+}
530263320Sdim+
531263320Sdim+static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
532263320Sdim+                                      MCStreamer &OutStreamer,
533263320Sdim+                                      MCContext &OutContext)
534263320Sdim+{
535263320Sdim+  const MachineOperand &MO = MI->getOperand(0);
536263320Sdim+  MCSymbol *StartLabel = OutContext.CreateTempSymbol();
537263320Sdim+  MCSymbol *EndLabel   = OutContext.CreateTempSymbol();
538263320Sdim+  MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
539263320Sdim+  MCSymbol *GOTLabel   =
540263320Sdim+    OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
541263320Sdim+
542263320Sdim+  assert(MO.getReg() != SP::O7 &&
543263320Sdim+         "%o7 is assigned as destination for getpcx!");
544263320Sdim+
545263320Sdim+  MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
546263320Sdim+  MCOperand RegO7   = MCOperand::CreateReg(SP::O7);
547263320Sdim+
548263320Sdim+  // <StartLabel>:
549263320Sdim+  //   call <EndLabel>
550263320Sdim+  // <SethiLabel>:
551263320Sdim+  //     sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
552263320Sdim+  // <EndLabel>:
553263320Sdim+  //   or  <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
554263320Sdim+  //   add <MO>, %o7, <MO>
555263320Sdim+
556263320Sdim+  OutStreamer.EmitLabel(StartLabel);
557263320Sdim+  MCOperand Callee =  createPCXCallOP(EndLabel, OutContext);
558263320Sdim+  EmitCall(OutStreamer, Callee);
559263320Sdim+  OutStreamer.EmitLabel(SethiLabel);
560263320Sdim+  MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
561263320Sdim+                                       GOTLabel, StartLabel, SethiLabel,
562263320Sdim+                                       OutContext);
563263320Sdim+  EmitSETHI(OutStreamer, hiImm, MCRegOP);
564263320Sdim+  OutStreamer.EmitLabel(EndLabel);
565263320Sdim+  MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
566263320Sdim+                                       GOTLabel, StartLabel, EndLabel,
567263320Sdim+                                       OutContext);
568263320Sdim+  EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
569263320Sdim+  EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
570263320Sdim+}
571263320Sdim+
572263320Sdim+void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
573263320Sdim+{
574263320Sdim+  MCInst TmpInst;
575263320Sdim+
576263320Sdim+  switch (MI->getOpcode()) {
577263320Sdim+  default: break;
578263320Sdim+  case TargetOpcode::DBG_VALUE:
579263320Sdim+    // FIXME: Debug Value.
580263320Sdim+    return;
581263320Sdim+  case SP::GETPCX:
582263320Sdim+    LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
583263320Sdim+    return;
584263320Sdim+  }
585263320Sdim+  LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
586263320Sdim+  OutStreamer.EmitInstruction(TmpInst);
587263320Sdim+}
588263320Sdim+
589263320Sdim void SparcAsmPrinter::EmitFunctionBodyStart() {
590263320Sdim   if (!TM.getSubtarget<SparcSubtarget>().is64Bit())
591263320Sdim     return;
592263320Sdim@@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
593263320Sdim     unsigned reg = globalRegs[i];
594263320Sdim     if (MRI.use_empty(reg))
595263320Sdim       continue;
596263320Sdim-    EmitGlobalRegisterDecl(reg);
597263320Sdim+
598263320Sdim+    if  (reg == SP::G6 || reg == SP::G7)
599263320Sdim+      getTargetStreamer().emitSparcRegisterIgnore(reg);
600263320Sdim+    else
601263320Sdim+      getTargetStreamer().emitSparcRegisterScratch(reg);
602263320Sdim   }
603263320Sdim }
604263320Sdim 
605263320Sdim@@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin
606263320Sdim   printOperand(MI, opNum+1, O);
607263320Sdim }
608263320Sdim 
609263320Sdim-bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
610263320Sdim-                                  raw_ostream &O) {
611263320Sdim-  std::string operand = "";
612263320Sdim-  const MachineOperand &MO = MI->getOperand(opNum);
613263320Sdim-  switch (MO.getType()) {
614263320Sdim-  default: llvm_unreachable("Operand is not a register");
615263320Sdim-  case MachineOperand::MO_Register:
616263320Sdim-    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
617263320Sdim-           "Operand is not a physical register ");
618263320Sdim-    assert(MO.getReg() != SP::O7 &&
619263320Sdim-           "%o7 is assigned as destination for getpcx!");
620263320Sdim-    operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
621263320Sdim-    break;
622263320Sdim-  }
623263320Sdim-
624263320Sdim-  unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
625263320Sdim-  unsigned bbNum = MI->getParent()->getNumber();
626263320Sdim-
627263320Sdim-  O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
628263320Sdim-  O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
629263320Sdim-
630263320Sdim-  O << "\t  sethi\t"
631263320Sdim-    << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
632263320Sdim-    << ")), "  << operand << '\n' ;
633263320Sdim-
634263320Sdim-  O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
635263320Sdim-  O << "\tor\t" << operand
636263320Sdim-    << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
637263320Sdim-    << ")), " << operand << '\n';
638263320Sdim-  O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
639263320Sdim-
640263320Sdim-  return true;
641263320Sdim-}
642263320Sdim-
643263320Sdim-void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
644263320Sdim-                                     raw_ostream &O) {
645263320Sdim-  int CC = (int)MI->getOperand(opNum).getImm();
646263320Sdim-  O << SPARCCondCodeToString((SPCC::CondCodes)CC);
647263320Sdim-}
648263320Sdim-
649263320Sdim /// PrintAsmOperand - Print out an operand for an inline asm expression.
650263320Sdim ///
651263320Sdim bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
652263320SdimIndex: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
653263320Sdim===================================================================
654263320Sdim--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
655263320Sdim+++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
656263320Sdim@@ -23,8 +23,7 @@
657263320Sdim using namespace llvm;
658263320Sdim 
659263320Sdim #define GET_INSTRUCTION_NAME
660263320Sdim-// Uncomment the following line once we are ready to use MCAsmWriter.
661263320Sdim-//#include "SparcGenAsmWriter.inc"
662263320Sdim+#include "SparcGenAsmWriter.inc"
663263320Sdim 
664263320Sdim void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
665263320Sdim {
666263320SdimIndex: test/CodeGen/SPARC/exception.ll
667263320Sdim===================================================================
668263320Sdim--- test/CodeGen/SPARC/exception.ll
669263320Sdim+++ test/CodeGen/SPARC/exception.ll
670263320Sdim@@ -11,7 +11,7 @@
671263320Sdim 
672263320Sdim ; CHECK-LABEL: main:
673263320Sdim ; CHECK:       .cfi_startproc
674263320Sdim-; CHECK:       .cfi_def_cfa_register 30
675263320Sdim+; CHECK:       .cfi_def_cfa_register {{30|%fp}}
676263320Sdim ; CHECK:       .cfi_window_save
677263320Sdim ; CHECK:       .cfi_register 15, 31
678263320Sdim 
679