1 Pull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7 Index: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
8 ===================================================================
9 --- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
10 +++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp
12 +//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===//
14 +// The LLVM Compiler Infrastructure
16 +// This file is distributed under the University of Illinois Open Source
17 +// License. See LICENSE.TXT for details.
19 +//===----------------------------------------------------------------------===//
21 +// This file provides Sparc specific target streamer methods.
23 +//===----------------------------------------------------------------------===//
25 +#include "SparcTargetStreamer.h"
26 +#include "InstPrinter/SparcInstPrinter.h"
27 +#include "llvm/Support/FormattedStream.h"
29 +using namespace llvm;
31 +// pin vtable to this file
32 +void SparcTargetStreamer::anchor() {}
34 +SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS)
37 +void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) {
38 + OS << "\t.register "
39 + << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
43 +void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) {
44 + OS << "\t.register "
45 + << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower()
49 +MCELFStreamer &SparcTargetELFStreamer::getStreamer() {
50 + return static_cast<MCELFStreamer &>(*Streamer);
52 Index: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
53 ===================================================================
54 --- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
55 +++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt
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
71 + SparcTargetStreamer.cpp
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
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);
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);
100 + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
101 + useDwarfDirectory, InstPrint, CE, TAB,
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);
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);
122 + TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
123 + createMCAsmStreamer);
124 + TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
125 + createMCAsmStreamer);
127 + // Register the MCInstPrinter
128 + TargetRegistry::RegisterMCInstPrinter(TheSparcTarget,
129 + createSparcMCInstPrinter);
130 + TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target,
131 + createSparcMCInstPrinter);
133 Index: lib/Target/Sparc/SparcTargetStreamer.h
134 ===================================================================
135 --- lib/Target/Sparc/SparcTargetStreamer.h
136 +++ lib/Target/Sparc/SparcTargetStreamer.h
138 +//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===//
140 +// The LLVM Compiler Infrastructure
142 +// This file is distributed under the University of Illinois Open Source
143 +// License. See LICENSE.TXT for details.
145 +//===----------------------------------------------------------------------===//
147 +#ifndef SPARCTARGETSTREAMER_H
148 +#define SPARCTARGETSTREAMER_H
150 +#include "llvm/MC/MCELFStreamer.h"
151 +#include "llvm/MC/MCStreamer.h"
154 +class SparcTargetStreamer : public MCTargetStreamer {
155 + virtual void anchor();
158 + /// Emit ".register <reg>, #ignore".
159 + virtual void emitSparcRegisterIgnore(unsigned reg) = 0;
160 + /// Emit ".register <reg>, #scratch".
161 + virtual void emitSparcRegisterScratch(unsigned reg) = 0;
164 +// This part is for ascii assembly output
165 +class SparcTargetAsmStreamer : public SparcTargetStreamer {
166 + formatted_raw_ostream &OS;
169 + SparcTargetAsmStreamer(formatted_raw_ostream &OS);
170 + virtual void emitSparcRegisterIgnore(unsigned reg);
171 + virtual void emitSparcRegisterScratch(unsigned reg);
175 +// This part is for ELF object output
176 +class SparcTargetELFStreamer : public SparcTargetStreamer {
178 + MCELFStreamer &getStreamer();
179 + virtual void emitSparcRegisterIgnore(unsigned reg) {}
180 + virtual void emitSparcRegisterScratch(unsigned reg) {}
182 +} // end namespace llvm
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
193 + SparcMCInstLower.cpp
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]>;
205 +def SparcAsmWriter : AsmWriter {
206 + string AsmWriterClassName = "InstPrinter";
207 + bit isMCAsmWriter = 1;
210 //===----------------------------------------------------------------------===//
211 // Declare the target which we are implementing
212 @@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV
214 // Pull in Instruction Info:
215 let InstructionSet = SparcInstrInfo;
217 + let AssemblyWriters = [SparcAsmWriter];
219 Index: lib/Target/Sparc/SparcMCInstLower.cpp
220 ===================================================================
221 --- lib/Target/Sparc/SparcMCInstLower.cpp
222 +++ lib/Target/Sparc/SparcMCInstLower.cpp
224 +//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===//
226 +// The LLVM Compiler Infrastructure
228 +// This file is distributed under the University of Illinois Open Source
229 +// License. See LICENSE.TXT for details.
231 +//===----------------------------------------------------------------------===//
233 +// This file contains code to lower Sparc MachineInstrs to their corresponding
236 +//===----------------------------------------------------------------------===//
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"
252 +using namespace llvm;
255 +static MCOperand LowerSymbolOperand(const MachineInstr *MI,
256 + const MachineOperand &MO,
259 + SparcMCExpr::VariantKind Kind;
260 + const MCSymbol *Symbol = 0;
262 + unsigned TF = MO.getTargetFlags();
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;
294 + switch(MO.getType()) {
295 + default: llvm_unreachable("Unknown type in LowerSymbolOperand");
296 + case MachineOperand::MO_MachineBasicBlock:
297 + Symbol = MO.getMBB()->getSymbol();
300 + case MachineOperand::MO_GlobalAddress:
301 + Symbol = AP.getSymbol(MO.getGlobal());
304 + case MachineOperand::MO_BlockAddress:
305 + Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress());
308 + case MachineOperand::MO_ExternalSymbol:
309 + Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName());
312 + case MachineOperand::MO_ConstantPoolIndex:
313 + Symbol = AP.GetCPISymbol(MO.getIndex());
317 + const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol,
319 + const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym,
321 + return MCOperand::CreateExpr(expr);
324 +static MCOperand LowerOperand(const MachineInstr *MI,
325 + const MachineOperand &MO,
327 + switch(MO.getType()) {
328 + default: llvm_unreachable("unknown operand type"); break;
329 + case MachineOperand::MO_Register:
330 + if (MO.isImplicit())
332 + return MCOperand::CreateReg(MO.getReg());
334 + case MachineOperand::MO_Immediate:
335 + return MCOperand::CreateImm(MO.getImm());
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);
344 + case MachineOperand::MO_RegisterMask: break;
347 + return MCOperand();
350 +void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
355 + OutMI.setOpcode(MI->getOpcode());
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);
361 + if (MCOp.isValid())
362 + OutMI.addOperand(MCOp);
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 {
371 class SparcTargetMachine;
372 class formatted_raw_ostream;
375 + class MachineInstr;
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);
383 + void LowerSparcMachineInstrToMCInst(const MachineInstr *MI,
386 } // end namespace llvm;
389 Index: lib/Target/Sparc/SparcAsmPrinter.cpp
390 ===================================================================
391 --- lib/Target/Sparc/SparcAsmPrinter.cpp
392 +++ lib/Target/Sparc/SparcAsmPrinter.cpp
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;
414 class SparcAsmPrinter : public AsmPrinter {
415 + SparcTargetStreamer &getTargetStreamer() {
416 + return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer());
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);
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);
432 + static const char *getRegisterName(unsigned RegNo) {
433 + return SparcInstPrinter::getRegisterName(RegNo);
435 - void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
436 - static const char *getRegisterName(unsigned RegNo);
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,
444 - bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
446 virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
448 - void EmitGlobalRegisterDecl(unsigned reg) {
449 - SmallString<128> Str;
450 - raw_svector_ostream OS(Str);
451 - OS << "\t.register "
452 - << "%" << StringRef(getRegisterName(reg)).lower()
454 - << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
455 - OutStreamer.EmitRawText(OS.str());
459 } // end of anonymous namespace
461 -#include "SparcGenAsmWriter.inc"
462 +static MCOperand createPCXCallOP(MCSymbol *Label,
463 + MCContext &OutContext)
465 + const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
467 + const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
468 + MCSym, OutContext);
469 + return MCOperand::CreateExpr(expr);
472 +static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
473 + MCSymbol *GOTLabel, MCSymbol *StartLabel,
474 + MCSymbol *CurLabel,
475 + MCContext &OutContext)
477 + const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext);
478 + const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel,
480 + const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel,
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,
487 + return MCOperand::CreateExpr(expr);
490 +static void EmitCall(MCStreamer &OutStreamer,
494 + CallInst.setOpcode(SP::CALL);
495 + CallInst.addOperand(Callee);
496 + OutStreamer.EmitInstruction(CallInst);
499 +static void EmitSETHI(MCStreamer &OutStreamer,
500 + MCOperand &Imm, MCOperand &RD)
503 + SETHIInst.setOpcode(SP::SETHIi);
504 + SETHIInst.addOperand(RD);
505 + SETHIInst.addOperand(Imm);
506 + OutStreamer.EmitInstruction(SETHIInst);
509 +static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
510 + MCOperand &Imm, MCOperand &RD)
513 + ORInst.setOpcode(SP::ORri);
514 + ORInst.addOperand(RD);
515 + ORInst.addOperand(RS1);
516 + ORInst.addOperand(Imm);
517 + OutStreamer.EmitInstruction(ORInst);
520 +void EmitADD(MCStreamer &OutStreamer,
521 + MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
524 + ADDInst.setOpcode(SP::ADDrr);
525 + ADDInst.addOperand(RD);
526 + ADDInst.addOperand(RS1);
527 + ADDInst.addOperand(RS2);
528 + OutStreamer.EmitInstruction(ADDInst);
531 +static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
532 + MCStreamer &OutStreamer,
533 + MCContext &OutContext)
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_"));
542 + assert(MO.getReg() != SP::O7 &&
543 + "%o7 is assigned as destination for getpcx!");
545 + MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
546 + MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
551 + // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO>
553 + // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO>
554 + // add <MO>, %o7, <MO>
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,
563 + EmitSETHI(OutStreamer, hiImm, MCRegOP);
564 + OutStreamer.EmitLabel(EndLabel);
565 + MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
566 + GOTLabel, StartLabel, EndLabel,
568 + EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
569 + EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
572 +void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
576 + switch (MI->getOpcode()) {
578 + case TargetOpcode::DBG_VALUE:
579 + // FIXME: Debug Value.
582 + LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
585 + LowerSparcMachineInstrToMCInst(MI, TmpInst, *this);
586 + OutStreamer.EmitInstruction(TmpInst);
589 void SparcAsmPrinter::EmitFunctionBodyStart() {
590 if (!TM.getSubtarget<SparcSubtarget>().is64Bit())
592 @@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() {
593 unsigned reg = globalRegs[i];
594 if (MRI.use_empty(reg))
596 - EmitGlobalRegisterDecl(reg);
598 + if (reg == SP::G6 || reg == SP::G7)
599 + getTargetStreamer().emitSparcRegisterIgnore(reg);
601 + getTargetStreamer().emitSparcRegisterScratch(reg);
605 @@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin
606 printOperand(MI, opNum+1, O);
609 -bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
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();
624 - unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
625 - unsigned bbNum = MI->getParent()->getNumber();
627 - O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
628 - O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
631 - << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
632 - << ")), " << operand << '\n' ;
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';
643 -void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
645 - int CC = (int)MI->getOperand(opNum).getImm();
646 - O << SPARCCondCodeToString((SPCC::CondCodes)CC);
649 /// PrintAsmOperand - Print out an operand for an inline asm expression.
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
657 using namespace llvm;
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"
664 void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
666 Index: test/CodeGen/SPARC/exception.ll
667 ===================================================================
668 --- test/CodeGen/SPARC/exception.ll
669 +++ test/CodeGen/SPARC/exception.ll
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