679 lines
25 KiB
Diff
679 lines
25 KiB
Diff
Pull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter.
|
|
|
|
Introduced here: http://svnweb.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
|
|
|