1263320SdimPull in r198030 from upstream llvm trunk (by Venkatraman Govindaraju): 2263320Sdim 3263320Sdim [Sparc] Lower and MachineInstr to MC and print assembly using MCInstPrinter. 4263320Sdim 5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261 6263320Sdim 7263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp 8263320Sdim=================================================================== 9263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp 10263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp 11263320Sdim@@ -0,0 +1,40 @@ 12263320Sdim+//===-- SparcTargetStreamer.cpp - Sparc Target Streamer Methods -----------===// 13263320Sdim+// 14263320Sdim+// The LLVM Compiler Infrastructure 15263320Sdim+// 16263320Sdim+// This file is distributed under the University of Illinois Open Source 17263320Sdim+// License. See LICENSE.TXT for details. 18263320Sdim+// 19263320Sdim+//===----------------------------------------------------------------------===// 20263320Sdim+// 21263320Sdim+// This file provides Sparc specific target streamer methods. 22263320Sdim+// 23263320Sdim+//===----------------------------------------------------------------------===// 24263320Sdim+ 25263320Sdim+#include "SparcTargetStreamer.h" 26263320Sdim+#include "InstPrinter/SparcInstPrinter.h" 27263320Sdim+#include "llvm/Support/FormattedStream.h" 28263320Sdim+ 29263320Sdim+using namespace llvm; 30263320Sdim+ 31263320Sdim+// pin vtable to this file 32263320Sdim+void SparcTargetStreamer::anchor() {} 33263320Sdim+ 34263320Sdim+SparcTargetAsmStreamer::SparcTargetAsmStreamer(formatted_raw_ostream &OS) 35263320Sdim+ : OS(OS) {} 36263320Sdim+ 37263320Sdim+void SparcTargetAsmStreamer::emitSparcRegisterIgnore(unsigned reg) { 38263320Sdim+ OS << "\t.register " 39263320Sdim+ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower() 40263320Sdim+ << ", #ignore\n"; 41263320Sdim+} 42263320Sdim+ 43263320Sdim+void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) { 44263320Sdim+ OS << "\t.register " 45263320Sdim+ << "%" << StringRef(SparcInstPrinter::getRegisterName(reg)).lower() 46263320Sdim+ << ", #scratch\n"; 47263320Sdim+} 48263320Sdim+ 49263320Sdim+MCELFStreamer &SparcTargetELFStreamer::getStreamer() { 50263320Sdim+ return static_cast<MCELFStreamer &>(*Streamer); 51263320Sdim+} 52263320SdimIndex: lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt 53263320Sdim=================================================================== 54263320Sdim--- lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt 55263320Sdim+++ lib/Target/Sparc/MCTargetDesc/LLVMBuild.txt 56263320Sdim@@ -19,5 +19,5 @@ 57263320Sdim type = Library 58263320Sdim name = SparcDesc 59263320Sdim parent = Sparc 60263320Sdim-required_libraries = MC SparcInfo Support 61263320Sdim+required_libraries = MC SparcAsmPrinter SparcInfo Support 62263320Sdim add_to_library_groups = Sparc 63263320SdimIndex: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 64263320Sdim=================================================================== 65263320Sdim--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 66263320Sdim+++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt 67263320Sdim@@ -2,6 +2,7 @@ add_llvm_library(LLVMSparcDesc 68263320Sdim SparcMCTargetDesc.cpp 69263320Sdim SparcMCAsmInfo.cpp 70263320Sdim SparcMCExpr.cpp 71263320Sdim+ SparcTargetStreamer.cpp 72263320Sdim ) 73263320Sdim 74263320Sdim add_dependencies(LLVMSparcDesc SparcCommonTableGen) 75263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 76263320Sdim=================================================================== 77263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 78263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp 79263320Sdim@@ -13,6 +13,8 @@ 80263320Sdim 81263320Sdim #include "SparcMCTargetDesc.h" 82263320Sdim #include "SparcMCAsmInfo.h" 83263320Sdim+#include "SparcTargetStreamer.h" 84263320Sdim+#include "InstPrinter/SparcInstPrinter.h" 85263320Sdim #include "llvm/MC/MCCodeGenInfo.h" 86263320Sdim #include "llvm/MC/MCInstrInfo.h" 87263320Sdim #include "llvm/MC/MCRegisterInfo.h" 88263320Sdim@@ -86,6 +88,28 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S 89263320Sdim X->InitMCCodeGenInfo(RM, CM, OL); 90263320Sdim return X; 91263320Sdim } 92263320Sdim+ 93263320Sdim+static MCStreamer * 94263320Sdim+createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, 95263320Sdim+ bool isVerboseAsm, bool useLoc, bool useCFI, 96263320Sdim+ bool useDwarfDirectory, MCInstPrinter *InstPrint, 97263320Sdim+ MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { 98263320Sdim+ SparcTargetAsmStreamer *S = new SparcTargetAsmStreamer(OS); 99263320Sdim+ 100263320Sdim+ return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, 101263320Sdim+ useDwarfDirectory, InstPrint, CE, TAB, 102263320Sdim+ ShowInst); 103263320Sdim+} 104263320Sdim+ 105263320Sdim+static MCInstPrinter *createSparcMCInstPrinter(const Target &T, 106263320Sdim+ unsigned SyntaxVariant, 107263320Sdim+ const MCAsmInfo &MAI, 108263320Sdim+ const MCInstrInfo &MII, 109263320Sdim+ const MCRegisterInfo &MRI, 110263320Sdim+ const MCSubtargetInfo &STI) { 111263320Sdim+ return new SparcInstPrinter(MAI, MII, MRI); 112263320Sdim+} 113263320Sdim+ 114263320Sdim extern "C" void LLVMInitializeSparcTargetMC() { 115263320Sdim // Register the MC asm info. 116263320Sdim RegisterMCAsmInfo<SparcELFMCAsmInfo> X(TheSparcTarget); 117263320Sdim@@ -106,4 +130,15 @@ extern "C" void LLVMInitializeSparcTargetMC() { 118263320Sdim // Register the MC subtarget info. 119263320Sdim TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget, 120263320Sdim createSparcMCSubtargetInfo); 121263320Sdim+ 122263320Sdim+ TargetRegistry::RegisterAsmStreamer(TheSparcTarget, 123263320Sdim+ createMCAsmStreamer); 124263320Sdim+ TargetRegistry::RegisterAsmStreamer(TheSparcV9Target, 125263320Sdim+ createMCAsmStreamer); 126263320Sdim+ 127263320Sdim+ // Register the MCInstPrinter 128263320Sdim+ TargetRegistry::RegisterMCInstPrinter(TheSparcTarget, 129263320Sdim+ createSparcMCInstPrinter); 130263320Sdim+ TargetRegistry::RegisterMCInstPrinter(TheSparcV9Target, 131263320Sdim+ createSparcMCInstPrinter); 132263320Sdim } 133263320SdimIndex: lib/Target/Sparc/SparcTargetStreamer.h 134263320Sdim=================================================================== 135263320Sdim--- lib/Target/Sparc/SparcTargetStreamer.h 136263320Sdim+++ lib/Target/Sparc/SparcTargetStreamer.h 137263320Sdim@@ -0,0 +1,47 @@ 138263320Sdim+//===-- SparcTargetStreamer.h - Sparc Target Streamer ----------*- C++ -*--===// 139263320Sdim+// 140263320Sdim+// The LLVM Compiler Infrastructure 141263320Sdim+// 142263320Sdim+// This file is distributed under the University of Illinois Open Source 143263320Sdim+// License. See LICENSE.TXT for details. 144263320Sdim+// 145263320Sdim+//===----------------------------------------------------------------------===// 146263320Sdim+ 147263320Sdim+#ifndef SPARCTARGETSTREAMER_H 148263320Sdim+#define SPARCTARGETSTREAMER_H 149263320Sdim+ 150263320Sdim+#include "llvm/MC/MCELFStreamer.h" 151263320Sdim+#include "llvm/MC/MCStreamer.h" 152263320Sdim+ 153263320Sdim+namespace llvm { 154263320Sdim+class SparcTargetStreamer : public MCTargetStreamer { 155263320Sdim+ virtual void anchor(); 156263320Sdim+ 157263320Sdim+public: 158263320Sdim+ /// Emit ".register <reg>, #ignore". 159263320Sdim+ virtual void emitSparcRegisterIgnore(unsigned reg) = 0; 160263320Sdim+ /// Emit ".register <reg>, #scratch". 161263320Sdim+ virtual void emitSparcRegisterScratch(unsigned reg) = 0; 162263320Sdim+}; 163263320Sdim+ 164263320Sdim+// This part is for ascii assembly output 165263320Sdim+class SparcTargetAsmStreamer : public SparcTargetStreamer { 166263320Sdim+ formatted_raw_ostream &OS; 167263320Sdim+ 168263320Sdim+public: 169263320Sdim+ SparcTargetAsmStreamer(formatted_raw_ostream &OS); 170263320Sdim+ virtual void emitSparcRegisterIgnore(unsigned reg); 171263320Sdim+ virtual void emitSparcRegisterScratch(unsigned reg); 172263320Sdim+ 173263320Sdim+}; 174263320Sdim+ 175263320Sdim+// This part is for ELF object output 176263320Sdim+class SparcTargetELFStreamer : public SparcTargetStreamer { 177263320Sdim+public: 178263320Sdim+ MCELFStreamer &getStreamer(); 179263320Sdim+ virtual void emitSparcRegisterIgnore(unsigned reg) {} 180263320Sdim+ virtual void emitSparcRegisterScratch(unsigned reg) {} 181263320Sdim+}; 182263320Sdim+} // end namespace llvm 183263320Sdim+ 184263320Sdim+#endif 185263320SdimIndex: lib/Target/Sparc/CMakeLists.txt 186263320Sdim=================================================================== 187263320Sdim--- lib/Target/Sparc/CMakeLists.txt 188263320Sdim+++ lib/Target/Sparc/CMakeLists.txt 189263320Sdim@@ -23,6 +23,7 @@ add_llvm_target(SparcCodeGen 190263320Sdim SparcSelectionDAGInfo.cpp 191263320Sdim SparcJITInfo.cpp 192263320Sdim SparcCodeEmitter.cpp 193263320Sdim+ SparcMCInstLower.cpp 194263320Sdim ) 195263320Sdim 196263320Sdim add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen) 197263320SdimIndex: lib/Target/Sparc/Sparc.td 198263320Sdim=================================================================== 199263320Sdim--- lib/Target/Sparc/Sparc.td 200263320Sdim+++ lib/Target/Sparc/Sparc.td 201263320Sdim@@ -65,6 +65,10 @@ def : Proc<"ultrasparc", [FeatureV9, FeatureV 202263320Sdim def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>; 203263320Sdim def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>; 204263320Sdim 205263320Sdim+def SparcAsmWriter : AsmWriter { 206263320Sdim+ string AsmWriterClassName = "InstPrinter"; 207263320Sdim+ bit isMCAsmWriter = 1; 208263320Sdim+} 209263320Sdim 210263320Sdim //===----------------------------------------------------------------------===// 211263320Sdim // Declare the target which we are implementing 212263320Sdim@@ -73,4 +77,6 @@ def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV 213263320Sdim def Sparc : Target { 214263320Sdim // Pull in Instruction Info: 215263320Sdim let InstructionSet = SparcInstrInfo; 216263320Sdim+ 217263320Sdim+ let AssemblyWriters = [SparcAsmWriter]; 218263320Sdim } 219263320SdimIndex: lib/Target/Sparc/SparcMCInstLower.cpp 220263320Sdim=================================================================== 221263320Sdim--- lib/Target/Sparc/SparcMCInstLower.cpp 222263320Sdim+++ lib/Target/Sparc/SparcMCInstLower.cpp 223263320Sdim@@ -0,0 +1,141 @@ 224263320Sdim+//===-- SparcMCInstLower.cpp - Convert Sparc MachineInstr to MCInst -------===// 225263320Sdim+// 226263320Sdim+// The LLVM Compiler Infrastructure 227263320Sdim+// 228263320Sdim+// This file is distributed under the University of Illinois Open Source 229263320Sdim+// License. See LICENSE.TXT for details. 230263320Sdim+// 231263320Sdim+//===----------------------------------------------------------------------===// 232263320Sdim+// 233263320Sdim+// This file contains code to lower Sparc MachineInstrs to their corresponding 234263320Sdim+// MCInst records. 235263320Sdim+// 236263320Sdim+//===----------------------------------------------------------------------===// 237263320Sdim+ 238263320Sdim+#include "Sparc.h" 239263320Sdim+#include "MCTargetDesc/SparcBaseInfo.h" 240263320Sdim+#include "MCTargetDesc/SparcMCExpr.h" 241263320Sdim+#include "llvm/CodeGen/AsmPrinter.h" 242263320Sdim+#include "llvm/CodeGen/MachineFunction.h" 243263320Sdim+#include "llvm/CodeGen/MachineInstr.h" 244263320Sdim+#include "llvm/CodeGen/MachineOperand.h" 245263320Sdim+#include "llvm/MC/MCContext.h" 246263320Sdim+#include "llvm/MC/MCAsmInfo.h" 247263320Sdim+#include "llvm/MC/MCExpr.h" 248263320Sdim+#include "llvm/MC/MCInst.h" 249263320Sdim+#include "llvm/Target/Mangler.h" 250263320Sdim+#include "llvm/ADT/SmallString.h" 251263320Sdim+ 252263320Sdim+using namespace llvm; 253263320Sdim+ 254263320Sdim+ 255263320Sdim+static MCOperand LowerSymbolOperand(const MachineInstr *MI, 256263320Sdim+ const MachineOperand &MO, 257263320Sdim+ AsmPrinter &AP) { 258263320Sdim+ 259263320Sdim+ SparcMCExpr::VariantKind Kind; 260263320Sdim+ const MCSymbol *Symbol = 0; 261263320Sdim+ 262263320Sdim+ unsigned TF = MO.getTargetFlags(); 263263320Sdim+ 264263320Sdim+ switch(TF) { 265263320Sdim+ default: llvm_unreachable("Unknown target flags on operand"); 266263320Sdim+ case SPII::MO_NO_FLAG: Kind = SparcMCExpr::VK_Sparc_None; break; 267263320Sdim+ case SPII::MO_LO: Kind = SparcMCExpr::VK_Sparc_LO; break; 268263320Sdim+ case SPII::MO_HI: Kind = SparcMCExpr::VK_Sparc_HI; break; 269263320Sdim+ case SPII::MO_H44: Kind = SparcMCExpr::VK_Sparc_H44; break; 270263320Sdim+ case SPII::MO_M44: Kind = SparcMCExpr::VK_Sparc_M44; break; 271263320Sdim+ case SPII::MO_L44: Kind = SparcMCExpr::VK_Sparc_L44; break; 272263320Sdim+ case SPII::MO_HH: Kind = SparcMCExpr::VK_Sparc_HH; break; 273263320Sdim+ case SPII::MO_HM: Kind = SparcMCExpr::VK_Sparc_HM; break; 274263320Sdim+ case SPII::MO_TLS_GD_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_GD_HI22; break; 275263320Sdim+ case SPII::MO_TLS_GD_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_GD_LO10; break; 276263320Sdim+ case SPII::MO_TLS_GD_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_GD_ADD; break; 277263320Sdim+ case SPII::MO_TLS_GD_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_GD_CALL; break; 278263320Sdim+ case SPII::MO_TLS_LDM_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_HI22; break; 279263320Sdim+ case SPII::MO_TLS_LDM_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_LO10; break; 280263320Sdim+ case SPII::MO_TLS_LDM_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_ADD; break; 281263320Sdim+ case SPII::MO_TLS_LDM_CALL: Kind = SparcMCExpr::VK_Sparc_TLS_LDM_CALL; break; 282263320Sdim+ case SPII::MO_TLS_LDO_HIX22:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_HIX22; break; 283263320Sdim+ case SPII::MO_TLS_LDO_LOX10:Kind = SparcMCExpr::VK_Sparc_TLS_LDO_LOX10; break; 284263320Sdim+ case SPII::MO_TLS_LDO_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_LDO_ADD; break; 285263320Sdim+ case SPII::MO_TLS_IE_HI22: Kind = SparcMCExpr::VK_Sparc_TLS_IE_HI22; break; 286263320Sdim+ case SPII::MO_TLS_IE_LO10: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LO10; break; 287263320Sdim+ case SPII::MO_TLS_IE_LD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LD; break; 288263320Sdim+ case SPII::MO_TLS_IE_LDX: Kind = SparcMCExpr::VK_Sparc_TLS_IE_LDX; break; 289263320Sdim+ case SPII::MO_TLS_IE_ADD: Kind = SparcMCExpr::VK_Sparc_TLS_IE_ADD; break; 290263320Sdim+ case SPII::MO_TLS_LE_HIX22: Kind = SparcMCExpr::VK_Sparc_TLS_LE_HIX22; break; 291263320Sdim+ case SPII::MO_TLS_LE_LOX10: Kind = SparcMCExpr::VK_Sparc_TLS_LE_LOX10; break; 292263320Sdim+ } 293263320Sdim+ 294263320Sdim+ switch(MO.getType()) { 295263320Sdim+ default: llvm_unreachable("Unknown type in LowerSymbolOperand"); 296263320Sdim+ case MachineOperand::MO_MachineBasicBlock: 297263320Sdim+ Symbol = MO.getMBB()->getSymbol(); 298263320Sdim+ break; 299263320Sdim+ 300263320Sdim+ case MachineOperand::MO_GlobalAddress: 301263320Sdim+ Symbol = AP.getSymbol(MO.getGlobal()); 302263320Sdim+ break; 303263320Sdim+ 304263320Sdim+ case MachineOperand::MO_BlockAddress: 305263320Sdim+ Symbol = AP.GetBlockAddressSymbol(MO.getBlockAddress()); 306263320Sdim+ break; 307263320Sdim+ 308263320Sdim+ case MachineOperand::MO_ExternalSymbol: 309263320Sdim+ Symbol = AP.GetExternalSymbolSymbol(MO.getSymbolName()); 310263320Sdim+ break; 311263320Sdim+ 312263320Sdim+ case MachineOperand::MO_ConstantPoolIndex: 313263320Sdim+ Symbol = AP.GetCPISymbol(MO.getIndex()); 314263320Sdim+ break; 315263320Sdim+ } 316263320Sdim+ 317263320Sdim+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, 318263320Sdim+ AP.OutContext); 319263320Sdim+ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, 320263320Sdim+ AP.OutContext); 321263320Sdim+ return MCOperand::CreateExpr(expr); 322263320Sdim+} 323263320Sdim+ 324263320Sdim+static MCOperand LowerOperand(const MachineInstr *MI, 325263320Sdim+ const MachineOperand &MO, 326263320Sdim+ AsmPrinter &AP) { 327263320Sdim+ switch(MO.getType()) { 328263320Sdim+ default: llvm_unreachable("unknown operand type"); break; 329263320Sdim+ case MachineOperand::MO_Register: 330263320Sdim+ if (MO.isImplicit()) 331263320Sdim+ break; 332263320Sdim+ return MCOperand::CreateReg(MO.getReg()); 333263320Sdim+ 334263320Sdim+ case MachineOperand::MO_Immediate: 335263320Sdim+ return MCOperand::CreateImm(MO.getImm()); 336263320Sdim+ 337263320Sdim+ case MachineOperand::MO_MachineBasicBlock: 338263320Sdim+ case MachineOperand::MO_GlobalAddress: 339263320Sdim+ case MachineOperand::MO_BlockAddress: 340263320Sdim+ case MachineOperand::MO_ExternalSymbol: 341263320Sdim+ case MachineOperand::MO_ConstantPoolIndex: 342263320Sdim+ return LowerSymbolOperand(MI, MO, AP); 343263320Sdim+ 344263320Sdim+ case MachineOperand::MO_RegisterMask: break; 345263320Sdim+ 346263320Sdim+ } 347263320Sdim+ return MCOperand(); 348263320Sdim+} 349263320Sdim+ 350263320Sdim+void llvm::LowerSparcMachineInstrToMCInst(const MachineInstr *MI, 351263320Sdim+ MCInst &OutMI, 352263320Sdim+ AsmPrinter &AP) 353263320Sdim+{ 354263320Sdim+ 355263320Sdim+ OutMI.setOpcode(MI->getOpcode()); 356263320Sdim+ 357263320Sdim+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 358263320Sdim+ const MachineOperand &MO = MI->getOperand(i); 359263320Sdim+ MCOperand MCOp = LowerOperand(MI, MO, AP); 360263320Sdim+ 361263320Sdim+ if (MCOp.isValid()) 362263320Sdim+ OutMI.addOperand(MCOp); 363263320Sdim+ } 364263320Sdim+} 365263320SdimIndex: lib/Target/Sparc/Sparc.h 366263320Sdim=================================================================== 367263320Sdim--- lib/Target/Sparc/Sparc.h 368263320Sdim+++ lib/Target/Sparc/Sparc.h 369263320Sdim@@ -23,6 +23,9 @@ namespace llvm { 370263320Sdim class FunctionPass; 371263320Sdim class SparcTargetMachine; 372263320Sdim class formatted_raw_ostream; 373263320Sdim+ class AsmPrinter; 374263320Sdim+ class MCInst; 375263320Sdim+ class MachineInstr; 376263320Sdim 377263320Sdim FunctionPass *createSparcISelDag(SparcTargetMachine &TM); 378263320Sdim FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM); 379263320Sdim@@ -29,6 +32,9 @@ namespace llvm { 380263320Sdim FunctionPass *createSparcJITCodeEmitterPass(SparcTargetMachine &TM, 381263320Sdim JITCodeEmitter &JCE); 382263320Sdim 383263320Sdim+ void LowerSparcMachineInstrToMCInst(const MachineInstr *MI, 384263320Sdim+ MCInst &OutMI, 385263320Sdim+ AsmPrinter &AP); 386263320Sdim } // end namespace llvm; 387263320Sdim 388263320Sdim namespace llvm { 389263320SdimIndex: lib/Target/Sparc/SparcAsmPrinter.cpp 390263320Sdim=================================================================== 391263320Sdim--- lib/Target/Sparc/SparcAsmPrinter.cpp 392263320Sdim+++ lib/Target/Sparc/SparcAsmPrinter.cpp 393263320Sdim@@ -16,12 +16,17 @@ 394263320Sdim #include "Sparc.h" 395263320Sdim #include "SparcInstrInfo.h" 396263320Sdim #include "SparcTargetMachine.h" 397263320Sdim+#include "SparcTargetStreamer.h" 398263320Sdim+#include "InstPrinter/SparcInstPrinter.h" 399263320Sdim #include "MCTargetDesc/SparcBaseInfo.h" 400263320Sdim+#include "MCTargetDesc/SparcMCExpr.h" 401263320Sdim #include "llvm/ADT/SmallString.h" 402263320Sdim #include "llvm/CodeGen/AsmPrinter.h" 403263320Sdim #include "llvm/CodeGen/MachineInstr.h" 404263320Sdim #include "llvm/CodeGen/MachineRegisterInfo.h" 405263320Sdim #include "llvm/MC/MCAsmInfo.h" 406263320Sdim+#include "llvm/MC/MCContext.h" 407263320Sdim+#include "llvm/MC/MCInst.h" 408263320Sdim #include "llvm/MC/MCStreamer.h" 409263320Sdim #include "llvm/MC/MCSymbol.h" 410263320Sdim #include "llvm/Support/TargetRegistry.h" 411263320Sdim@@ -31,6 +36,9 @@ using namespace llvm; 412263320Sdim 413263320Sdim namespace { 414263320Sdim class SparcAsmPrinter : public AsmPrinter { 415263320Sdim+ SparcTargetStreamer &getTargetStreamer() { 416263320Sdim+ return static_cast<SparcTargetStreamer&>(OutStreamer.getTargetStreamer()); 417263320Sdim+ } 418263320Sdim public: 419263320Sdim explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 420263320Sdim : AsmPrinter(TM, Streamer) {} 421263320Sdim@@ -45,14 +53,11 @@ namespace { 422263320Sdim void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); 423263320Sdim 424263320Sdim virtual void EmitFunctionBodyStart(); 425263320Sdim- virtual void EmitInstruction(const MachineInstr *MI) { 426263320Sdim- SmallString<128> Str; 427263320Sdim- raw_svector_ostream OS(Str); 428263320Sdim- printInstruction(MI, OS); 429263320Sdim- OutStreamer.EmitRawText(OS.str()); 430263320Sdim+ virtual void EmitInstruction(const MachineInstr *MI); 431263320Sdim+ 432263320Sdim+ static const char *getRegisterName(unsigned RegNo) { 433263320Sdim+ return SparcInstPrinter::getRegisterName(RegNo); 434263320Sdim } 435263320Sdim- void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd. 436263320Sdim- static const char *getRegisterName(unsigned RegNo); 437263320Sdim 438263320Sdim bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 439263320Sdim unsigned AsmVariant, const char *ExtraCode, 440263320Sdim@@ -61,25 +66,139 @@ namespace { 441263320Sdim unsigned AsmVariant, const char *ExtraCode, 442263320Sdim raw_ostream &O); 443263320Sdim 444263320Sdim- bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS); 445263320Sdim- 446263320Sdim virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) 447263320Sdim const; 448263320Sdim- void EmitGlobalRegisterDecl(unsigned reg) { 449263320Sdim- SmallString<128> Str; 450263320Sdim- raw_svector_ostream OS(Str); 451263320Sdim- OS << "\t.register " 452263320Sdim- << "%" << StringRef(getRegisterName(reg)).lower() 453263320Sdim- << ", " 454263320Sdim- << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch"); 455263320Sdim- OutStreamer.EmitRawText(OS.str()); 456263320Sdim- } 457263320Sdim 458263320Sdim }; 459263320Sdim } // end of anonymous namespace 460263320Sdim 461263320Sdim-#include "SparcGenAsmWriter.inc" 462263320Sdim+static MCOperand createPCXCallOP(MCSymbol *Label, 463263320Sdim+ MCContext &OutContext) 464263320Sdim+{ 465263320Sdim+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label, 466263320Sdim+ OutContext); 467263320Sdim+ const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None, 468263320Sdim+ MCSym, OutContext); 469263320Sdim+ return MCOperand::CreateExpr(expr); 470263320Sdim+} 471263320Sdim 472263320Sdim+static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind, 473263320Sdim+ MCSymbol *GOTLabel, MCSymbol *StartLabel, 474263320Sdim+ MCSymbol *CurLabel, 475263320Sdim+ MCContext &OutContext) 476263320Sdim+{ 477263320Sdim+ const MCSymbolRefExpr *GOT = MCSymbolRefExpr::Create(GOTLabel, OutContext); 478263320Sdim+ const MCSymbolRefExpr *Start = MCSymbolRefExpr::Create(StartLabel, 479263320Sdim+ OutContext); 480263320Sdim+ const MCSymbolRefExpr *Cur = MCSymbolRefExpr::Create(CurLabel, 481263320Sdim+ OutContext); 482263320Sdim+ 483263320Sdim+ const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Cur, Start, OutContext); 484263320Sdim+ const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(GOT, Sub, OutContext); 485263320Sdim+ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, 486263320Sdim+ Add, OutContext); 487263320Sdim+ return MCOperand::CreateExpr(expr); 488263320Sdim+} 489263320Sdim+ 490263320Sdim+static void EmitCall(MCStreamer &OutStreamer, 491263320Sdim+ MCOperand &Callee) 492263320Sdim+{ 493263320Sdim+ MCInst CallInst; 494263320Sdim+ CallInst.setOpcode(SP::CALL); 495263320Sdim+ CallInst.addOperand(Callee); 496263320Sdim+ OutStreamer.EmitInstruction(CallInst); 497263320Sdim+} 498263320Sdim+ 499263320Sdim+static void EmitSETHI(MCStreamer &OutStreamer, 500263320Sdim+ MCOperand &Imm, MCOperand &RD) 501263320Sdim+{ 502263320Sdim+ MCInst SETHIInst; 503263320Sdim+ SETHIInst.setOpcode(SP::SETHIi); 504263320Sdim+ SETHIInst.addOperand(RD); 505263320Sdim+ SETHIInst.addOperand(Imm); 506263320Sdim+ OutStreamer.EmitInstruction(SETHIInst); 507263320Sdim+} 508263320Sdim+ 509263320Sdim+static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1, 510263320Sdim+ MCOperand &Imm, MCOperand &RD) 511263320Sdim+{ 512263320Sdim+ MCInst ORInst; 513263320Sdim+ ORInst.setOpcode(SP::ORri); 514263320Sdim+ ORInst.addOperand(RD); 515263320Sdim+ ORInst.addOperand(RS1); 516263320Sdim+ ORInst.addOperand(Imm); 517263320Sdim+ OutStreamer.EmitInstruction(ORInst); 518263320Sdim+} 519263320Sdim+ 520263320Sdim+void EmitADD(MCStreamer &OutStreamer, 521263320Sdim+ MCOperand &RS1, MCOperand &RS2, MCOperand &RD) 522263320Sdim+{ 523263320Sdim+ MCInst ADDInst; 524263320Sdim+ ADDInst.setOpcode(SP::ADDrr); 525263320Sdim+ ADDInst.addOperand(RD); 526263320Sdim+ ADDInst.addOperand(RS1); 527263320Sdim+ ADDInst.addOperand(RS2); 528263320Sdim+ OutStreamer.EmitInstruction(ADDInst); 529263320Sdim+} 530263320Sdim+ 531263320Sdim+static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, 532263320Sdim+ MCStreamer &OutStreamer, 533263320Sdim+ MCContext &OutContext) 534263320Sdim+{ 535263320Sdim+ const MachineOperand &MO = MI->getOperand(0); 536263320Sdim+ MCSymbol *StartLabel = OutContext.CreateTempSymbol(); 537263320Sdim+ MCSymbol *EndLabel = OutContext.CreateTempSymbol(); 538263320Sdim+ MCSymbol *SethiLabel = OutContext.CreateTempSymbol(); 539263320Sdim+ MCSymbol *GOTLabel = 540263320Sdim+ OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); 541263320Sdim+ 542263320Sdim+ assert(MO.getReg() != SP::O7 && 543263320Sdim+ "%o7 is assigned as destination for getpcx!"); 544263320Sdim+ 545263320Sdim+ MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg()); 546263320Sdim+ MCOperand RegO7 = MCOperand::CreateReg(SP::O7); 547263320Sdim+ 548263320Sdim+ // <StartLabel>: 549263320Sdim+ // call <EndLabel> 550263320Sdim+ // <SethiLabel>: 551263320Sdim+ // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO> 552263320Sdim+ // <EndLabel>: 553263320Sdim+ // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO> 554263320Sdim+ // add <MO>, %o7, <MO> 555263320Sdim+ 556263320Sdim+ OutStreamer.EmitLabel(StartLabel); 557263320Sdim+ MCOperand Callee = createPCXCallOP(EndLabel, OutContext); 558263320Sdim+ EmitCall(OutStreamer, Callee); 559263320Sdim+ OutStreamer.EmitLabel(SethiLabel); 560263320Sdim+ MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI, 561263320Sdim+ GOTLabel, StartLabel, SethiLabel, 562263320Sdim+ OutContext); 563263320Sdim+ EmitSETHI(OutStreamer, hiImm, MCRegOP); 564263320Sdim+ OutStreamer.EmitLabel(EndLabel); 565263320Sdim+ MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO, 566263320Sdim+ GOTLabel, StartLabel, EndLabel, 567263320Sdim+ OutContext); 568263320Sdim+ EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP); 569263320Sdim+ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); 570263320Sdim+} 571263320Sdim+ 572263320Sdim+void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI) 573263320Sdim+{ 574263320Sdim+ MCInst TmpInst; 575263320Sdim+ 576263320Sdim+ switch (MI->getOpcode()) { 577263320Sdim+ default: break; 578263320Sdim+ case TargetOpcode::DBG_VALUE: 579263320Sdim+ // FIXME: Debug Value. 580263320Sdim+ return; 581263320Sdim+ case SP::GETPCX: 582263320Sdim+ LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext); 583263320Sdim+ return; 584263320Sdim+ } 585263320Sdim+ LowerSparcMachineInstrToMCInst(MI, TmpInst, *this); 586263320Sdim+ OutStreamer.EmitInstruction(TmpInst); 587263320Sdim+} 588263320Sdim+ 589263320Sdim void SparcAsmPrinter::EmitFunctionBodyStart() { 590263320Sdim if (!TM.getSubtarget<SparcSubtarget>().is64Bit()) 591263320Sdim return; 592263320Sdim@@ -90,7 +209,11 @@ void SparcAsmPrinter::EmitFunctionBodyStart() { 593263320Sdim unsigned reg = globalRegs[i]; 594263320Sdim if (MRI.use_empty(reg)) 595263320Sdim continue; 596263320Sdim- EmitGlobalRegisterDecl(reg); 597263320Sdim+ 598263320Sdim+ if (reg == SP::G6 || reg == SP::G7) 599263320Sdim+ getTargetStreamer().emitSparcRegisterIgnore(reg); 600263320Sdim+ else 601263320Sdim+ getTargetStreamer().emitSparcRegisterScratch(reg); 602263320Sdim } 603263320Sdim } 604263320Sdim 605263320Sdim@@ -226,46 +349,6 @@ void SparcAsmPrinter::printMemOperand(const Machin 606263320Sdim printOperand(MI, opNum+1, O); 607263320Sdim } 608263320Sdim 609263320Sdim-bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum, 610263320Sdim- raw_ostream &O) { 611263320Sdim- std::string operand = ""; 612263320Sdim- const MachineOperand &MO = MI->getOperand(opNum); 613263320Sdim- switch (MO.getType()) { 614263320Sdim- default: llvm_unreachable("Operand is not a register"); 615263320Sdim- case MachineOperand::MO_Register: 616263320Sdim- assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && 617263320Sdim- "Operand is not a physical register "); 618263320Sdim- assert(MO.getReg() != SP::O7 && 619263320Sdim- "%o7 is assigned as destination for getpcx!"); 620263320Sdim- operand = "%" + StringRef(getRegisterName(MO.getReg())).lower(); 621263320Sdim- break; 622263320Sdim- } 623263320Sdim- 624263320Sdim- unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber(); 625263320Sdim- unsigned bbNum = MI->getParent()->getNumber(); 626263320Sdim- 627263320Sdim- O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n"; 628263320Sdim- O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ; 629263320Sdim- 630263320Sdim- O << "\t sethi\t" 631263320Sdim- << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum 632263320Sdim- << ")), " << operand << '\n' ; 633263320Sdim- 634263320Sdim- O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ; 635263320Sdim- O << "\tor\t" << operand 636263320Sdim- << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum 637263320Sdim- << ")), " << operand << '\n'; 638263320Sdim- O << "\tadd\t" << operand << ", %o7, " << operand << '\n'; 639263320Sdim- 640263320Sdim- return true; 641263320Sdim-} 642263320Sdim- 643263320Sdim-void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum, 644263320Sdim- raw_ostream &O) { 645263320Sdim- int CC = (int)MI->getOperand(opNum).getImm(); 646263320Sdim- O << SPARCCondCodeToString((SPCC::CondCodes)CC); 647263320Sdim-} 648263320Sdim- 649263320Sdim /// PrintAsmOperand - Print out an operand for an inline asm expression. 650263320Sdim /// 651263320Sdim bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 652263320SdimIndex: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp 653263320Sdim=================================================================== 654263320Sdim--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp 655263320Sdim+++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp 656263320Sdim@@ -23,8 +23,7 @@ 657263320Sdim using namespace llvm; 658263320Sdim 659263320Sdim #define GET_INSTRUCTION_NAME 660263320Sdim-// Uncomment the following line once we are ready to use MCAsmWriter. 661263320Sdim-//#include "SparcGenAsmWriter.inc" 662263320Sdim+#include "SparcGenAsmWriter.inc" 663263320Sdim 664263320Sdim void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const 665263320Sdim { 666263320SdimIndex: test/CodeGen/SPARC/exception.ll 667263320Sdim=================================================================== 668263320Sdim--- test/CodeGen/SPARC/exception.ll 669263320Sdim+++ test/CodeGen/SPARC/exception.ll 670263320Sdim@@ -11,7 +11,7 @@ 671263320Sdim 672263320Sdim ; CHECK-LABEL: main: 673263320Sdim ; CHECK: .cfi_startproc 674263320Sdim-; CHECK: .cfi_def_cfa_register 30 675263320Sdim+; CHECK: .cfi_def_cfa_register {{30|%fp}} 676263320Sdim ; CHECK: .cfi_window_save 677263320Sdim ; CHECK: .cfi_register 15, 31 678263320Sdim 679