]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198030-sparc.diff
1 Pull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
8 ===================================================================
9 --- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
10 +++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
11 @@ -0,0 +1,40 @@
12 +//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===//
13 +//
14 +//                     The LLVM Compiler Infrastructure
15 +//
16 +// This file is distributed under the University of Illinois Open Source
17 +// License. See LICENSE.TXT for details.
18 +//
19 +//===----------------------------------------------------------------------===//
20 +//
21 +// This file provides Sparc specific target streamer methods.
22 +//
23 +//===----------------------------------------------------------------------===//
24 +
25 +#include "SparcTargetStreamer.h"
26 +#include "InstPrinter/SparcInstPrinter.h"
27 +#include "llvm/Support/FormattedStream.h"
28 +
29 +using namespace llvm;
30 +
31 +// pin vtable to this file
32 +void SparcTargetStreamer::anchor() {}
33 +
34 +SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS)
35 +    : OS(OS) {}
36 +
37 +void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) {
38 +  OS << "\t.register "
39 +     << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
40 +     << ", #ignore\n";
41 +}
42 +
43 +void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) {
44 +  OS << "\t.register "
45 +     << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
46 +     << ", #scratch\n";
47 +}
48 +
49 +MCELFStreamer &SparcTargetELFStreamer::getStreamer() {
50 +  return static_cast<MCELFStreamer &>(*Streamer);
51 +}
52 Index: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
53 ===================================================================
54 --- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
55 +++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
56 @@ -19,5 +19,5 @@
57  type = Library
58  name = SparcDesc
59  parent = Sparc
60 -required_libraries = MC SparcInfo Support
61 +required_libraries = MC SparcAsmPrinter SparcInfo Support
62  add_to_library_groups = Sparc
63 Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
64 ===================================================================
65 --- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
66 +++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
67 @@ -2,6 +2,7 @@ add_llvm_library(LLVMSparcDesc
68    SparcMCTargetDesc.cpp
69    SparcMCAsmInfo.cpp
70    SparcMCExpr.cpp
71 +  SparcTargetStreamer.cpp
72    )
73  
74  add_dependencies(LLVMSparcDesc SparcCommonTableGen)
75 Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
76 ===================================================================
77 --- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
78 +++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
79 @@ -13,6 +13,8 @@
80  
81  #include "SparcMCTargetDesc.h"
82  #include "SparcMCAsmInfo.h"
83 +#include "SparcTargetStreamer.h"
84 +#include "InstPrinter/SparcInstPrinter.h"
85  #include "llvm/MC/MCCodeGenInfo.h"
86  #include "llvm/MC/MCInstrInfo.h"
87  #include "llvm/MC/MCRegisterInfo.h"
88 @@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
89    X->InitMCCodeGenInfo(RM, CM, OL);
90    return X;
91  }
92 +
93 +static MCStreamer *
94 +createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
95 +                    bool isVerboseAsm, bool useLoc, bool useCFI,
96 +                    bool useDwarfDirectory, MCInstPrinter *InstPrint,
97 +                    MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
98 +  SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS);
99 +
100 +  return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
101 +                                 useDwarfDirectory, InstPrint, CE, TAB,
102 +                                 ShowInst);
103 +}
104 +
105 +static MCInstPrinter *createSparcMCInstPrinter(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 SparcInstPrinter(MAI, MII, MRI);
112 +}
113 +
114  extern "C" void LLVMInitializeSparcTargetMC() {
115    // Register the MC asm info.
116    RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget);
117 @@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() {
118    // Register the MC subtarget info.
119    TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
120                                            createSparcMCSubtargetInfo);
121 +
122 +  TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
123 +                                      createMCAsmStreamer);
124 +  TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
125 +                                      createMCAsmStreamer);
126 +
127 +  // Register the MCInstPrinter
128 +  TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
129 +                                        createSparcMCInstPrinter);
130 +  TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
131 +                                        createSparcMCInstPrinter);
132  }
133 Index: lib/Target/Sparc/SparcTargetStreamer.h
134 ===================================================================
135 --- lib/Target/Sparc/SparcTargetStreamer.h
136 +++ lib/Target/Sparc/SparcTargetStreamer.h
137 @@ -0,0 +1,47 @@
138 +//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===//
139 +//
140 +//                     The LLVM Compiler Infrastructure
141 +//
142 +// This file is distributed under the University of Illinois Open Source
143 +// License. See LICENSE.TXT for details.
144 +//
145 +//===----------------------------------------------------------------------===//
146 +
147 +#ifndef SPARCTARGETSTREAMER_H
148 +#define SPARCTARGETSTREAMER_H
149 +
150 +#include "llvm/MC/MCELFStreamer.h"
151 +#include "llvm/MC/MCStreamer.h"
152 +
153 +namespace llvm {
154 +class SparcTargetStreamer : public MCTargetStreamer {
155 +  virtual void anchor();
156 +
157 +public:
158 +  /// Emit ".register <reg>, #ignore".
159 +  virtual void emitSparcRegisterIgnore(unsigned reg) = 0;
160 +  /// Emit ".register <reg>, #scratch".
161 +  virtual void emitSparcRegisterScratch(unsigned reg) = 0;
162 +};
163 +
164 +// This part is for ascii assembly output
165 +class SparcTargetAsmStreamer : public SparcTargetStreamer {
166 +  formatted_raw_ostream &OS;
167 +
168 +public:
169 +  SparcTargetAsmStreamer(formatted_raw_ostream &OS);
170 +  virtual void emitSparcRegisterIgnore(unsigned reg);
171 +  virtual void emitSparcRegisterScratch(unsigned reg);
172 +
173 +};
174 +
175 +// This part is for ELF object output
176 +class SparcTargetELFStreamer : public SparcTargetStreamer {
177 +public:
178 +  MCELFStreamer &getStreamer();
179 +  virtual void emitSparcRegisterIgnore(unsigned reg) {}
180 +  virtual void emitSparcRegisterScratch(unsigned reg) {}
181 +};
182 +} // end namespace llvm
183 +
184 +#endif
185 Index: lib/Target/Sparc/CMakeLists.txt
186 ===================================================================
187 --- lib/Target/Sparc/CMakeLists.txt
188 +++ lib/Target/Sparc/CMakeLists.txt
189 @@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen
190    SparcSelectionDAGInfo.cpp
191    SparcJITInfo.cpp
192    SparcCodeEmitter.cpp
193 +  SparcMCInstLower.cpp
194    )
195  
196  add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen)
197 Index: lib/Target/Sparc/Sparc.td
198 ===================================================================
199 --- lib/Target/Sparc/Sparc.td
200 +++ lib/Target/Sparc/Sparc.td
201 @@ -65,6 +65,10 @@ def : Proc<"ultrasparc",      [FeatureV9, FeatureV
202  def : Proc<"ultrasparc3",     [FeatureV9, FeatureV8Deprecated]>;
203  def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
204  
205 +def SparcAsmWriter : AsmWriter {
206 +  string AsmWriterClassName  = "InstPrinter";
207 +  bit isMCAsmWriter = 1;
208 +}
209  
210  //===----------------------------------------------------------------------===//
211  // Declare the target which we are implementing
212 @@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV
213  def Sparc : Target {
214    // Pull in Instruction Info:
215    let InstructionSet = SparcInstrInfo;
216 +
217 +  let AssemblyWriters = [SparcAsmWriter];
218  }
219 Index: lib/Target/Sparc/SparcMCInstLower.cpp
220 ===================================================================
221 --- lib/Target/Sparc/SparcMCInstLower.cpp
222 +++ lib/Target/Sparc/SparcMCInstLower.cpp
223 @@ -0,0 +1,141 @@
224 +//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
225 +//
226 +//                     The LLVM Compiler Infrastructure
227 +//
228 +// This file is distributed under the University of Illinois Open Source
229 +// License. See LICENSE.TXT for details.
230 +//
231 +//===----------------------------------------------------------------------===//
232 +//
233 +// This file contains code to lower Sparc MachineInstrs to their corresponding
234 +// MCInst records.
235 +//
236 +//===----------------------------------------------------------------------===//
237 +
238 +#include "Sparc.h"
239 +#include "MCTargetDesc/SparcBaseInfo.h"
240 +#include "MCTargetDesc/SparcMCExpr.h"
241 +#include "llvm/CodeGen/AsmPrinter.h"
242 +#include "llvm/CodeGen/MachineFunction.h"
243 +#include "llvm/CodeGen/MachineInstr.h"
244 +#include "llvm/CodeGen/MachineOperand.h"
245 +#include "llvm/MC/MCContext.h"
246 +#include "llvm/MC/MCAsmInfo.h"
247 +#include "llvm/MC/MCExpr.h"
248 +#include "llvm/MC/MCInst.h"
249 +#include "llvm/Target/Mangler.h"
250 +#include "llvm/ADT/SmallString.h"
251 +
252 +using namespace llvm;
253 +
254 +
255 +static MCOperand LowerSymbolOperand(const MachineInstr *MI,
256 +                                    const MachineOperand &MO,
257 +                                    AsmPrinter &AP) {
258 +
259 +  SparcMCExpr::VariantKind Kind;
260 +  const MCSymbol *Symbol = 0;
261 +
262 +  unsigned TF = MO.getTargetFlags();
263 +
264 +  switch(TF) {
265 +  default:      llvm_unreachable("Unknown target flags on operand");
266 +  case SPII::MO_NO_FLAG:      Kind = SparcMCExpr::VK_Sparc_None; break;
267 +  case SPII::MO_LO:           Kind = SparcMCExpr::VK_Sparc_LO; break;
268 +  case SPII::MO_HI:           Kind = SparcMCExpr::VK_Sparc_HI; break;
269 +  case SPII::MO_H44:          Kind = SparcMCExpr::VK_Sparc_H44; break;
270 +  case SPII::MO_M44:          Kind = SparcMCExpr::VK_Sparc_M44; break;
271 +  case SPII::MO_L44:          Kind = SparcMCExpr::VK_Sparc_L44; break;
272 +  case SPII::MO_HH:           Kind = SparcMCExpr::VK_Sparc_HH; break;
273 +  case SPII::MO_HM:           Kind = SparcMCExpr::VK_Sparc_HM; break;
274 +  case SPII::MO_TLS_GD_HI22:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break;
275 +  case SPII::MO_TLS_GD_LO10:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break;
276 +  case SPII::MO_TLS_GD_ADD:   Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break;
277 +  case SPII::MO_TLS_GD_CALL:  Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break;
278 +  case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break;
279 +  case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break;
280 +  case SPII::MO_TLS_LDM_ADD:  Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break;
281 +  case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break;
282 +  case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break;
283 +  case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break;
284 +  case SPII::MO_TLS_LDO_ADD:  Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break;
285 +  case SPII::MO_TLS_IE_HI22:  Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break;
286 +  case SPII::MO_TLS_IE_LO10:  Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break;
287 +  case SPII::MO_TLS_IE_LD:    Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break;
288 +  case SPII::MO_TLS_IE_LDX:   Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break;
289 +  case SPII::MO_TLS_IE_ADD:   Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break;
290 +  case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break;
291 +  case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break;
292 +  }
293 +
294 +  switch(MO.getType()) {
295 +  default: llvm_unreachable("Unknown type in LowerSymbolOperand");
296 +  case MachineOperand::MO_MachineBasicBlock:
297 +    Symbol = MO.getMBB()->getSymbol();
298 +    break;
299 +
300 +  case MachineOperand::MO_GlobalAddress:
301 +    Symbol = AP.getSymbol(MO.getGlobal());
302 +    break;
303 +
304 +  case MachineOperand::MO_BlockAddress:
305 +    Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
306 +    break;
307 +
308 +  case MachineOperand::MO_ExternalSymbol:
309 +    Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
310 +    break;
311 +
312 +  case MachineOperand::MO_ConstantPoolIndex:
313 +    Symbol = AP.GetCPISymbol(MO.getIndex());
314 +    break;
315 +  }
316 +
317 +  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
318 +                                                         AP.OutContext);
319 +  const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
320 +                                                AP.OutContext);
321 +  return MCOperand::CreateExpr(expr);
322 +}
323 +
324 +static MCOperand LowerOperand(const MachineInstr *MI,
325 +                              const MachineOperand &MO,
326 +                              AsmPrinter &AP) {
327 +  switch(MO.getType()) {
328 +  default: llvm_unreachable("unknown operand type"); break;
329 +  case MachineOperand::MO_Register:
330 +    if (MO.isImplicit())
331 +      break;
332 +    return MCOperand::CreateReg(MO.getReg());
333 +
334 +  case MachineOperand::MO_Immediate:
335 +    return MCOperand::CreateImm(MO.getImm());
336 +
337 +  case MachineOperand::MO_MachineBasicBlock:
338 +  case MachineOperand::MO_GlobalAddress:
339 +  case MachineOperand::MO_BlockAddress:
340 +  case MachineOperand::MO_ExternalSymbol:
341 +  case MachineOperand::MO_ConstantPoolIndex:
342 +    return LowerSymbolOperand(MI, MO, AP);
343 +
344 +  case MachineOperand::MO_RegisterMask:   break;
345 +
346 +  }
347 +  return MCOperand();
348 +}
349 +
350 +void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
351 +                                          MCInst &OutMI,
352 +                                          AsmPrinter &AP)
353 +{
354 +
355 +  OutMI.setOpcode(MI->getOpcode());
356 +
357 +  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
358 +    const MachineOperand &MO = MI->getOperand(i);
359 +    MCOperand MCOp = LowerOperand(MI, MO, AP);
360 +
361 +    if (MCOp.isValid())
362 +      OutMI.addOperand(MCOp);
363 +  }
364 +}
365 Index: lib/Target/Sparc/Sparc.h
366 ===================================================================
367 --- lib/Target/Sparc/Sparc.h
368 +++ lib/Target/Sparc/Sparc.h
369 @@ -23,6 +23,9 @@ namespace llvm {
370    class FunctionPass;
371    class SparcTargetMachine;
372    class formatted_raw_ostream;
373 +  class AsmPrinter;
374 +  class MCInst;
375 +  class MachineInstr;
376  
377    FunctionPass *createSparcISelDag(SparcTargetMachine &TM);
378    FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM);
379 @@ -29,6 +32,9 @@ namespace llvm {
380    FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
381                                                JITCodeEmitter &JCE);
382  
383 +  void LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
384 +                                      MCInst &OutMI,
385 +                                      AsmPrinter &AP);
386  } // end namespace llvm;
387  
388  namespace llvm {
389 Index: lib/Target/Sparc/SparcAsmPrinter.cpp
390 ===================================================================
391 --- lib/Target/Sparc/SparcAsmPrinter.cpp
392 +++ lib/Target/Sparc/SparcAsmPrinter.cpp
393 @@ -16,12 +16,17 @@
394  #include "Sparc.h"
395  #include "SparcInstrInfo.h"
396  #include "SparcTargetMachine.h"
397 +#include "SparcTargetStreamer.h"
398 +#include "InstPrinter/SparcInstPrinter.h"
399  #include "MCTargetDesc/SparcBaseInfo.h"
400 +#include "MCTargetDesc/SparcMCExpr.h"
401  #include "llvm/ADT/SmallString.h"
402  #include "llvm/CodeGen/AsmPrinter.h"
403  #include "llvm/CodeGen/MachineInstr.h"
404  #include "llvm/CodeGen/MachineRegisterInfo.h"
405  #include "llvm/MC/MCAsmInfo.h"
406 +#include "llvm/MC/MCContext.h"
407 +#include "llvm/MC/MCInst.h"
408  #include "llvm/MC/MCStreamer.h"
409  #include "llvm/MC/MCSymbol.h"
410  #include "llvm/Support/TargetRegistry.h"
411 @@ -31,6 +36,9 @@ using namespace llvm;
412  
413  namespace {
414    class SparcAsmPrinter : public AsmPrinter {
415 +    SparcTargetStreamer &getTargetStreamer() {
416 +      return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer());
417 +    }
418    public:
419      explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
420        : AsmPrinter(TM, Streamer) {}
421 @@ -45,14 +53,11 @@ namespace {
422      void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
423  
424      virtual void EmitFunctionBodyStart();
425 -    virtual void EmitInstruction(const MachineInstr *MI) {
426 -      SmallString<128> Str;
427 -      raw_svector_ostream OS(Str);
428 -      printInstruction(MI, OS);
429 -      OutStreamer.EmitRawText(OS.str());
430 +    virtual void EmitInstruction(const MachineInstr *MI);
431 +
432 +    static const char *getRegisterName(unsigned RegNo) {
433 +      return SparcInstPrinter::getRegisterName(RegNo);
434      }
435 -    void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
436 -    static const char *getRegisterName(unsigned RegNo);
437  
438      bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
439                           unsigned AsmVariant, const char *ExtraCode,
440 @@ -61,25 +66,139 @@ namespace {
441                                 unsigned AsmVariant, const char *ExtraCode,
442                                 raw_ostream &O);
443  
444 -    bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
445 -
446      virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
447                         const;
448 -    void EmitGlobalRegisterDecl(unsigned reg) {
449 -      SmallString<128> Str;
450 -      raw_svector_ostream OS(Str);
451 -      OS << "\t.register "
452 -         << "%" << StringRef(getRegisterName(reg)).lower()
453 -         << ", "
454 -         << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
455 -      OutStreamer.EmitRawText(OS.str());
456 -    }
457  
458    };
459  } // end of anonymous namespace
460  
461 -#include "SparcGenAsmWriter.inc"
462 +static MCOperand createPCXCallOP(MCSymbol *Label,
463 +                                 MCContext &OutContext)
464 +{
465 +  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
466 +                                                         OutContext);
467 +  const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
468 +                                                MCSym, OutContext);
469 +  return MCOperand::CreateExpr(expr);
470 +}
471  
472 +static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
473 +                                    MCSymbol *GOTLabel, MCSymbol *StartLabel,
474 +                                    MCSymbol *CurLabel,
475 +                                    MCContext &OutContext)
476 +{
477 +  const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext);
478 +  const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel,
479 +                                                         OutContext);
480 +  const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel,
481 +                                                       OutContext);
482 +
483 +  const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext);
484 +  const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext);
485 +  const SparcMCExpr *expr = SparcMCExpr::Create(Kind,
486 +                                                Add, OutContext);
487 +  return MCOperand::CreateExpr(expr);
488 +}
489 +
490 +static void EmitCall(MCStreamer &OutStreamer,
491 +                     MCOperand &Callee)
492 +{
493 +  MCInst CallInst;
494 +  CallInst.setOpcode(SP::CALL);
495 +  CallInst.addOperand(Callee);
496 +  OutStreamer.EmitInstruction(CallInst);
497 +}
498 +
499 +static void EmitSETHI(MCStreamer &OutStreamer,
500 +                      MCOperand &Imm, MCOperand &RD)
501 +{
502 +  MCInst SETHIInst;
503 +  SETHIInst.setOpcode(SP::SETHIi);
504 +  SETHIInst.addOperand(RD);
505 +  SETHIInst.addOperand(Imm);
506 +  OutStreamer.EmitInstruction(SETHIInst);
507 +}
508 +
509 +static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
510 +                   MCOperand &Imm, MCOperand &RD)
511 +{
512 +  MCInst ORInst;
513 +  ORInst.setOpcode(SP::ORri);
514 +  ORInst.addOperand(RD);
515 +  ORInst.addOperand(RS1);
516 +  ORInst.addOperand(Imm);
517 +  OutStreamer.EmitInstruction(ORInst);
518 +}
519 +
520 +void EmitADD(MCStreamer &OutStreamer,
521 +             MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
522 +{
523 +  MCInst ADDInst;
524 +  ADDInst.setOpcode(SP::ADDrr);
525 +  ADDInst.addOperand(RD);
526 +  ADDInst.addOperand(RS1);
527 +  ADDInst.addOperand(RS2);
528 +  OutStreamer.EmitInstruction(ADDInst);
529 +}
530 +
531 +static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
532 +                                      MCStreamer &OutStreamer,
533 +                                      MCContext &OutContext)
534 +{
535 +  const MachineOperand &MO = MI->getOperand(0);
536 +  MCSymbol *StartLabel = OutContext.CreateTempSymbol();
537 +  MCSymbol *EndLabel   = OutContext.CreateTempSymbol();
538 +  MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
539 +  MCSymbol *GOTLabel   =
540 +    OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
541 +
542 +  assert(MO.getReg() != SP::O7 &&
543 +         "%o7 is assigned as destination for getpcx!");
544 +
545 +  MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
546 +  MCOperand RegO7   = MCOperand::CreateReg(SP::O7);
547 +
548 +  // <StartLabel>:
549 +  //   call <EndLabel>
550 +  // <SethiLabel>:
551 +  //     sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
552 +  // <EndLabel>:
553 +  //   or  <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
554 +  //   add <MO>, %o7, <MO>
555 +
556 +  OutStreamer.EmitLabel(StartLabel);
557 +  MCOperand Callee =  createPCXCallOP(EndLabel, OutContext);
558 +  EmitCall(OutStreamer, Callee);
559 +  OutStreamer.EmitLabel(SethiLabel);
560 +  MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
561 +                                       GOTLabel, StartLabel, SethiLabel,
562 +                                       OutContext);
563 +  EmitSETHI(OutStreamer, hiImm, MCRegOP);
564 +  OutStreamer.EmitLabel(EndLabel);
565 +  MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
566 +                                       GOTLabel, StartLabel, EndLabel,
567 +                                       OutContext);
568 +  EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
569 +  EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
570 +}
571 +
572 +void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
573 +{
574 +  MCInst TmpInst;
575 +
576 +  switch (MI->getOpcode()) {
577 +  default: break;
578 +  case TargetOpcode::DBG_VALUE:
579 +    // FIXME: Debug Value.
580 +    return;
581 +  case SP::GETPCX:
582 +    LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
583 +    return;
584 +  }
585 +  LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
586 +  OutStreamer.EmitInstruction(TmpInst);
587 +}
588 +
589  void SparcAsmPrinter::EmitFunctionBodyStart() {
590    if (!TM.getSubtarget<SparcSubtarget>().is64Bit())
591      return;
592 @@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
593      unsigned reg = globalRegs[i];
594      if (MRI.use_empty(reg))
595        continue;
596 -    EmitGlobalRegisterDecl(reg);
597 +
598 +    if  (reg == SP::G6 || reg == SP::G7)
599 +      getTargetStreamer().emitSparcRegisterIgnore(reg);
600 +    else
601 +      getTargetStreamer().emitSparcRegisterScratch(reg);
602    }
603  }
604  
605 @@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin
606    printOperand(MI, opNum+1, O);
607  }
608  
609 -bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
610 -                                  raw_ostream &O) {
611 -  std::string operand = "";
612 -  const MachineOperand &MO = MI->getOperand(opNum);
613 -  switch (MO.getType()) {
614 -  default: llvm_unreachable("Operand is not a register");
615 -  case MachineOperand::MO_Register:
616 -    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
617 -           "Operand is not a physical register ");
618 -    assert(MO.getReg() != SP::O7 &&
619 -           "%o7 is assigned as destination for getpcx!");
620 -    operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
621 -    break;
622 -  }
623 -
624 -  unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
625 -  unsigned bbNum = MI->getParent()->getNumber();
626 -
627 -  O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
628 -  O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
629 -
630 -  O << "\t  sethi\t"
631 -    << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
632 -    << ")), "  << operand << '\n' ;
633 -
634 -  O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
635 -  O << "\tor\t" << operand
636 -    << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
637 -    << ")), " << operand << '\n';
638 -  O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
639 -
640 -  return true;
641 -}
642 -
643 -void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
644 -                                     raw_ostream &O) {
645 -  int CC = (int)MI->getOperand(opNum).getImm();
646 -  O << SPARCCondCodeToString((SPCC::CondCodes)CC);
647 -}
648 -
649  /// PrintAsmOperand - Print out an operand for an inline asm expression.
650  ///
651  bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
652 Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
653 ===================================================================
654 --- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
655 +++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
656 @@ -23,8 +23,7 @@
657  using namespace llvm;
658  
659  #define GET_INSTRUCTION_NAME
660 -// Uncomment the following line once we are ready to use MCAsmWriter.
661 -//#include "SparcGenAsmWriter.inc"
662 +#include "SparcGenAsmWriter.inc"
663  
664  void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
665  {
666 Index: test/CodeGen/SPARC/exception.ll
667 ===================================================================
668 --- test/CodeGen/SPARC/exception.ll
669 +++ test/CodeGen/SPARC/exception.ll
670 @@ -11,7 +11,7 @@
671  
672  ; CHECK-LABEL: main:
673  ; CHECK:       .cfi_startproc
674 -; CHECK:       .cfi_def_cfa_register 30
675 +; CHECK:       .cfi_def_cfa_register {{30|%fp}}
676  ; CHECK:       .cfi_window_save
677  ; CHECK:       .cfi_register 15, 31
678