summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198030-sparc.diff678
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
+
OpenPOWER on IntegriCloud