diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff | 678 |
1 files changed, 678 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff new file mode 100644 index 0000000..7ab4291 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff @@ -0,0 +1,678 @@ +Pull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp +@@ -0,0 +1,40 @@ ++//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++// ++// This file provides Sparc specific target streamer methods. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "SparcTargetStreamer.h" ++#include "InstPrinter/SparcInstPrinter.h" ++#include "llvm/Support/FormattedStream.h" ++ ++using namespace llvm; ++ ++// pin vtable to this file ++void SparcTargetStreamer::anchor() {} ++ ++SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS) ++ : OS(OS) {} ++ ++void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) { ++ OS << "\t.register " ++ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower() ++ << ", #ignore\n"; ++} ++ ++void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) { ++ OS << "\t.register " ++ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower() ++ << ", #scratch\n"; ++} ++ ++MCELFStreamer &SparcTargetELFStreamer::getStreamer() { ++ return static_cast<MCELFStreamer &>(*Streamer); ++} +Index: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt ++++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt +@@ -19,5 +19,5 @@ + type = Library + name = SparcDesc + parent = Sparc +-required_libraries = MC SparcInfo Support ++required_libraries = MC SparcAsmPrinter SparcInfo Support + add_to_library_groups = Sparc +Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt ++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt +@@ -2,6 +2,7 @@ add_llvm_library(LLVMSparcDesc + SparcMCTargetDesc.cpp + SparcMCAsmInfo.cpp + SparcMCExpr.cpp ++ SparcTargetStreamer.cpp + ) + + add_dependencies(LLVMSparcDesc SparcCommonTableGen) +Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +@@ -13,6 +13,8 @@ + + #include "SparcMCTargetDesc.h" + #include "SparcMCAsmInfo.h" ++#include "SparcTargetStreamer.h" ++#include "InstPrinter/SparcInstPrinter.h" + #include "llvm/MC/MCCodeGenInfo.h" + #include "llvm/MC/MCInstrInfo.h" + #include "llvm/MC/MCRegisterInfo.h" +@@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S + X->InitMCCodeGenInfo(RM, CM, OL); + return X; + } ++ ++static MCStreamer * ++createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, ++ bool isVerboseAsm, bool useLoc, bool useCFI, ++ bool useDwarfDirectory, MCInstPrinter *InstPrint, ++ MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { ++ SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS); ++ ++ return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, ++ useDwarfDirectory, InstPrint, CE, TAB, ++ ShowInst); ++} ++ ++static MCInstPrinter *createSparcMCInstPrinter(const Target &T, ++ unsigned SyntaxVariant, ++ const MCAsmInfo &MAI, ++ const MCInstrInfo &MII, ++ const MCRegisterInfo &MRI, ++ const MCSubtargetInfo &STI) { ++ return new SparcInstPrinter(MAI, MII, MRI); ++} ++ + extern "C" void LLVMInitializeSparcTargetMC() { + // Register the MC asm info. + RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget); +@@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() { + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget, + createSparcMCSubtargetInfo); ++ ++ TargetRegistry::RegisterAsmStreamer(TheSparcTarget, ++ createMCAsmStreamer); ++ TargetRegistry::RegisterAsmStreamer(TheSparcV9Target, ++ createMCAsmStreamer); ++ ++ // Register the MCInstPrinter ++ TargetRegistry::RegisterMCInstPrinter(TheSparcTarget, ++ createSparcMCInstPrinter); ++ TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target, ++ createSparcMCInstPrinter); + } +Index: lib/Target/Sparc/SparcTargetStreamer.h +=================================================================== +--- lib/Target/Sparc/SparcTargetStreamer.h ++++ lib/Target/Sparc/SparcTargetStreamer.h +@@ -0,0 +1,47 @@ ++//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef SPARCTARGETSTREAMER_H ++#define SPARCTARGETSTREAMER_H ++ ++#include "llvm/MC/MCELFStreamer.h" ++#include "llvm/MC/MCStreamer.h" ++ ++namespace llvm { ++class SparcTargetStreamer : public MCTargetStreamer { ++ virtual void anchor(); ++ ++public: ++ /// Emit ".register <reg>, #ignore". ++ virtual void emitSparcRegisterIgnore(unsigned reg) = 0; ++ /// Emit ".register <reg>, #scratch". ++ virtual void emitSparcRegisterScratch(unsigned reg) = 0; ++}; ++ ++// This part is for ascii assembly output ++class SparcTargetAsmStreamer : public SparcTargetStreamer { ++ formatted_raw_ostream &OS; ++ ++public: ++ SparcTargetAsmStreamer(formatted_raw_ostream &OS); ++ virtual void emitSparcRegisterIgnore(unsigned reg); ++ virtual void emitSparcRegisterScratch(unsigned reg); ++ ++}; ++ ++// This part is for ELF object output ++class SparcTargetELFStreamer : public SparcTargetStreamer { ++public: ++ MCELFStreamer &getStreamer(); ++ virtual void emitSparcRegisterIgnore(unsigned reg) {} ++ virtual void emitSparcRegisterScratch(unsigned reg) {} ++}; ++} // end namespace llvm ++ ++#endif +Index: lib/Target/Sparc/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/CMakeLists.txt ++++ lib/Target/Sparc/CMakeLists.txt +@@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen + SparcSelectionDAGInfo.cpp + SparcJITInfo.cpp + SparcCodeEmitter.cpp ++ SparcMCInstLower.cpp + ) + + add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen) +Index: lib/Target/Sparc/Sparc.td +=================================================================== +--- lib/Target/Sparc/Sparc.td ++++ lib/Target/Sparc/Sparc.td +@@ -65,6 +65,10 @@ def : Proc<"ultrasparc", [FeatureV9, FeatureV + def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>; + def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>; + ++def SparcAsmWriter : AsmWriter { ++ string AsmWriterClassName = "InstPrinter"; ++ bit isMCAsmWriter = 1; ++} + + //===----------------------------------------------------------------------===// + // Declare the target which we are implementing +@@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV + def Sparc : Target { + // Pull in Instruction Info: + let InstructionSet = SparcInstrInfo; ++ ++ let AssemblyWriters = [SparcAsmWriter]; + } +Index: lib/Target/Sparc/SparcMCInstLower.cpp +=================================================================== +--- lib/Target/Sparc/SparcMCInstLower.cpp ++++ lib/Target/Sparc/SparcMCInstLower.cpp +@@ -0,0 +1,141 @@ ++//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++// ++// This file contains code to lower Sparc MachineInstrs to their corresponding ++// MCInst records. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "Sparc.h" ++#include "MCTargetDesc/SparcBaseInfo.h" ++#include "MCTargetDesc/SparcMCExpr.h" ++#include "llvm/CodeGen/AsmPrinter.h" ++#include "llvm/CodeGen/MachineFunction.h" ++#include "llvm/CodeGen/MachineInstr.h" ++#include "llvm/CodeGen/MachineOperand.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCAsmInfo.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCInst.h" ++#include "llvm/Target/Mangler.h" ++#include "llvm/ADT/SmallString.h" ++ ++using namespace llvm; ++ ++ ++static MCOperand LowerSymbolOperand(const MachineInstr *MI, ++ const MachineOperand &MO, ++ AsmPrinter &AP) { ++ ++ SparcMCExpr::VariantKind Kind; ++ const MCSymbol *Symbol = 0; ++ ++ unsigned TF = MO.getTargetFlags(); ++ ++ switch(TF) { ++ default: llvm_unreachable("Unknown target flags on operand"); ++ case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break; ++ case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break; ++ case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break; ++ case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break; ++ case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break; ++ case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break; ++ case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break; ++ case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break; ++ case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break; ++ case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break; ++ case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break; ++ case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break; ++ case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break; ++ case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break; ++ case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break; ++ case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break; ++ case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break; ++ case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break; ++ case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break; ++ case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break; ++ case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break; ++ case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break; ++ case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break; ++ case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break; ++ case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break; ++ case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break; ++ } ++ ++ switch(MO.getType()) { ++ default: llvm_unreachable("Unknown type in LowerSymbolOperand"); ++ case MachineOperand::MO_MachineBasicBlock: ++ Symbol = MO.getMBB()->getSymbol(); ++ break; ++ ++ case MachineOperand::MO_GlobalAddress: ++ Symbol = AP.getSymbol(MO.getGlobal()); ++ break; ++ ++ case MachineOperand::MO_BlockAddress: ++ Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress()); ++ break; ++ ++ case MachineOperand::MO_ExternalSymbol: ++ Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName()); ++ break; ++ ++ case MachineOperand::MO_ConstantPoolIndex: ++ Symbol = AP.GetCPISymbol(MO.getIndex()); ++ break; ++ } ++ ++ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, ++ AP.OutContext); ++ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, ++ AP.OutContext); ++ return MCOperand::CreateExpr(expr); ++} ++ ++static MCOperand LowerOperand(const MachineInstr *MI, ++ const MachineOperand &MO, ++ AsmPrinter &AP) { ++ switch(MO.getType()) { ++ default: llvm_unreachable("unknown operand type"); break; ++ case MachineOperand::MO_Register: ++ if (MO.isImplicit()) ++ break; ++ return MCOperand::CreateReg(MO.getReg()); ++ ++ case MachineOperand::MO_Immediate: ++ return MCOperand::CreateImm(MO.getImm()); ++ ++ case MachineOperand::MO_MachineBasicBlock: ++ case MachineOperand::MO_GlobalAddress: ++ case MachineOperand::MO_BlockAddress: ++ case MachineOperand::MO_ExternalSymbol: ++ case MachineOperand::MO_ConstantPoolIndex: ++ return LowerSymbolOperand(MI, MO, AP); ++ ++ case MachineOperand::MO_RegisterMask: break; ++ ++ } ++ return MCOperand(); ++} ++ ++void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI, ++ MCInst &OutMI, ++ AsmPrinter &AP) ++{ ++ ++ OutMI.setOpcode(MI->getOpcode()); ++ ++ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { ++ const MachineOperand &MO = MI->getOperand(i); ++ MCOperand MCOp = LowerOperand(MI, MO, AP); ++ ++ if (MCOp.isValid()) ++ OutMI.addOperand(MCOp); ++ } ++} +Index: lib/Target/Sparc/Sparc.h +=================================================================== +--- lib/Target/Sparc/Sparc.h ++++ lib/Target/Sparc/Sparc.h +@@ -23,6 +23,9 @@ namespace llvm { + class FunctionPass; + class SparcTargetMachine; + class formatted_raw_ostream; ++ class AsmPrinter; ++ class MCInst; ++ class MachineInstr; + + FunctionPass *createSparcISelDag(SparcTargetMachine &TM); + FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM); +@@ -29,6 +32,9 @@ namespace llvm { + FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM, + JITCodeEmitter &JCE); + ++ void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, ++ MCInst &OutMI, ++ AsmPrinter &AP); + } // end namespace llvm; + + namespace llvm { +Index: lib/Target/Sparc/SparcAsmPrinter.cpp +=================================================================== +--- lib/Target/Sparc/SparcAsmPrinter.cpp ++++ lib/Target/Sparc/SparcAsmPrinter.cpp +@@ -16,12 +16,17 @@ + #include "Sparc.h" + #include "SparcInstrInfo.h" + #include "SparcTargetMachine.h" ++#include "SparcTargetStreamer.h" ++#include "InstPrinter/SparcInstPrinter.h" + #include "MCTargetDesc/SparcBaseInfo.h" ++#include "MCTargetDesc/SparcMCExpr.h" + #include "llvm/ADT/SmallString.h" + #include "llvm/CodeGen/AsmPrinter.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/MachineRegisterInfo.h" + #include "llvm/MC/MCAsmInfo.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCInst.h" + #include "llvm/MC/MCStreamer.h" + #include "llvm/MC/MCSymbol.h" + #include "llvm/Support/TargetRegistry.h" +@@ -31,6 +36,9 @@ using namespace llvm; + + namespace { + class SparcAsmPrinter : public AsmPrinter { ++ SparcTargetStreamer &getTargetStreamer() { ++ return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer()); ++ } + public: + explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer) {} +@@ -45,14 +53,11 @@ namespace { + void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); + + virtual void EmitFunctionBodyStart(); +- virtual void EmitInstruction(const MachineInstr *MI) { +- SmallString<128> Str; +- raw_svector_ostream OS(Str); +- printInstruction(MI, OS); +- OutStreamer.EmitRawText(OS.str()); ++ virtual void EmitInstruction(const MachineInstr *MI); ++ ++ static const char *getRegisterName(unsigned RegNo) { ++ return SparcInstPrinter::getRegisterName(RegNo); + } +- void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd. +- static const char *getRegisterName(unsigned RegNo); + + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, +@@ -61,25 +66,139 @@ namespace { + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); + +- bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS); +- + virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) + const; +- void EmitGlobalRegisterDecl(unsigned reg) { +- SmallString<128> Str; +- raw_svector_ostream OS(Str); +- OS << "\t.register " +- << "%" << StringRef(getRegisterName(reg)).lower() +- << ", " +- << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch"); +- OutStreamer.EmitRawText(OS.str()); +- } + + }; + } // end of anonymous namespace + +-#include "SparcGenAsmWriter.inc" ++static MCOperand createPCXCallOP(MCSymbol *Label, ++ MCContext &OutContext) ++{ ++ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label, ++ OutContext); ++ const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None, ++ MCSym, OutContext); ++ return MCOperand::CreateExpr(expr); ++} + ++static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, ++ MCSymbol *GOTLabel, MCSymbol *StartLabel, ++ MCSymbol *CurLabel, ++ MCContext &OutContext) ++{ ++ const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext); ++ const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel, ++ OutContext); ++ const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel, ++ OutContext); ++ ++ const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext); ++ const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext); ++ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, ++ Add, OutContext); ++ return MCOperand::CreateExpr(expr); ++} ++ ++static void EmitCall(MCStreamer &OutStreamer, ++ MCOperand &Callee) ++{ ++ MCInst CallInst; ++ CallInst.setOpcode(SP::CALL); ++ CallInst.addOperand(Callee); ++ OutStreamer.EmitInstruction(CallInst); ++} ++ ++static void EmitSETHI(MCStreamer &OutStreamer, ++ MCOperand &Imm, MCOperand &RD) ++{ ++ MCInst SETHIInst; ++ SETHIInst.setOpcode(SP::SETHIi); ++ SETHIInst.addOperand(RD); ++ SETHIInst.addOperand(Imm); ++ OutStreamer.EmitInstruction(SETHIInst); ++} ++ ++static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1, ++ MCOperand &Imm, MCOperand &RD) ++{ ++ MCInst ORInst; ++ ORInst.setOpcode(SP::ORri); ++ ORInst.addOperand(RD); ++ ORInst.addOperand(RS1); ++ ORInst.addOperand(Imm); ++ OutStreamer.EmitInstruction(ORInst); ++} ++ ++void EmitADD(MCStreamer &OutStreamer, ++ MCOperand &RS1, MCOperand &RS2, MCOperand &RD) ++{ ++ MCInst ADDInst; ++ ADDInst.setOpcode(SP::ADDrr); ++ ADDInst.addOperand(RD); ++ ADDInst.addOperand(RS1); ++ ADDInst.addOperand(RS2); ++ OutStreamer.EmitInstruction(ADDInst); ++} ++ ++static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, ++ MCStreamer &OutStreamer, ++ MCContext &OutContext) ++{ ++ const MachineOperand &MO = MI->getOperand(0); ++ MCSymbol *StartLabel = OutContext.CreateTempSymbol(); ++ MCSymbol *EndLabel = OutContext.CreateTempSymbol(); ++ MCSymbol *SethiLabel = OutContext.CreateTempSymbol(); ++ MCSymbol *GOTLabel = ++ OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); ++ ++ assert(MO.getReg() != SP::O7 && ++ "%o7 is assigned as destination for getpcx!"); ++ ++ MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg()); ++ MCOperand RegO7 = MCOperand::CreateReg(SP::O7); ++ ++ // <StartLabel>: ++ // call <EndLabel> ++ // <SethiLabel>: ++ // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO> ++ // <EndLabel>: ++ // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO> ++ // add <MO>, %o7, <MO> ++ ++ OutStreamer.EmitLabel(StartLabel); ++ MCOperand Callee = createPCXCallOP(EndLabel, OutContext); ++ EmitCall(OutStreamer, Callee); ++ OutStreamer.EmitLabel(SethiLabel); ++ MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI, ++ GOTLabel, StartLabel, SethiLabel, ++ OutContext); ++ EmitSETHI(OutStreamer, hiImm, MCRegOP); ++ OutStreamer.EmitLabel(EndLabel); ++ MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO, ++ GOTLabel, StartLabel, EndLabel, ++ OutContext); ++ EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP); ++ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); ++} ++ ++void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) ++{ ++ MCInst TmpInst; ++ ++ switch (MI->getOpcode()) { ++ default: break; ++ case TargetOpcode::DBG_VALUE: ++ // FIXME: Debug Value. ++ return; ++ case SP::GETPCX: ++ LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext); ++ return; ++ } ++ LowerSparcMachineInstrToMCInst(MI, TmpInst, *this); ++ OutStreamer.EmitInstruction(TmpInst); ++} ++ + void SparcAsmPrinter::EmitFunctionBodyStart() { + if (!TM.getSubtarget<SparcSubtarget>().is64Bit()) + return; +@@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() { + unsigned reg = globalRegs[i]; + if (MRI.use_empty(reg)) + continue; +- EmitGlobalRegisterDecl(reg); ++ ++ if (reg == SP::G6 || reg == SP::G7) ++ getTargetStreamer().emitSparcRegisterIgnore(reg); ++ else ++ getTargetStreamer().emitSparcRegisterScratch(reg); + } + } + +@@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin + printOperand(MI, opNum+1, O); + } + +-bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum, +- raw_ostream &O) { +- std::string operand = ""; +- const MachineOperand &MO = MI->getOperand(opNum); +- switch (MO.getType()) { +- default: llvm_unreachable("Operand is not a register"); +- case MachineOperand::MO_Register: +- assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && +- "Operand is not a physical register "); +- assert(MO.getReg() != SP::O7 && +- "%o7 is assigned as destination for getpcx!"); +- operand = "%" + StringRef(getRegisterName(MO.getReg())).lower(); +- break; +- } +- +- unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber(); +- unsigned bbNum = MI->getParent()->getNumber(); +- +- O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n"; +- O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ; +- +- O << "\t sethi\t" +- << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum +- << ")), " << operand << '\n' ; +- +- O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ; +- O << "\tor\t" << operand +- << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum +- << ")), " << operand << '\n'; +- O << "\tadd\t" << operand << ", %o7, " << operand << '\n'; +- +- return true; +-} +- +-void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum, +- raw_ostream &O) { +- int CC = (int)MI->getOperand(opNum).getImm(); +- O << SPARCCondCodeToString((SPCC::CondCodes)CC); +-} +- + /// PrintAsmOperand - Print out an operand for an inline asm expression. + /// + bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, +Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +=================================================================== +--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp ++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +@@ -23,8 +23,7 @@ + using namespace llvm; + + #define GET_INSTRUCTION_NAME +-// Uncomment the following line once we are ready to use MCAsmWriter. +-//#include "SparcGenAsmWriter.inc" ++#include "SparcGenAsmWriter.inc" + + void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const + { +Index: test/CodeGen/SPARC/exception.ll +=================================================================== +--- test/CodeGen/SPARC/exception.ll ++++ test/CodeGen/SPARC/exception.ll +@@ -11,7 +11,7 @@ + + ; CHECK-LABEL: main: + ; CHECK: .cfi_startproc +-; CHECK: .cfi_def_cfa_register 30 ++; CHECK: .cfi_def_cfa_register {{30|%fp}} + ; CHECK: .cfi_window_save + ; CHECK: .cfi_register 15, 31 + |