17c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner//===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// 2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 34acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke// The LLVM Compiler Infrastructure 44acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 84acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke//===----------------------------------------------------------------------===// 94acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke// 104acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke// This file contains a printer that converts from our internal representation 117c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner// of machine-dependent LLVM code to GAS-format SPARC assembly language. 124acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke// 134acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke//===----------------------------------------------------------------------===// 144acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke 1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer" 167c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "Sparc.h" 177c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "SparcInstrInfo.h" 18225503a5b5de954788ad1e4bc9c69211de334c05Chris Lattner#include "SparcTargetMachine.h" 19cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen#include "MCTargetDesc/SparcBaseInfo.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h" 211dbed16fec1de205a7e69cc5c63798ec18e17f4cChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 224acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke#include "llvm/CodeGen/MachineInstr.h" 23af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 248e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner#include "llvm/MC/MCStreamer.h" 25325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 263e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 27b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/Mangler.h" 294acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaekeusing namespace llvm; 304acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke 3195b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 326726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class SparcAsmPrinter : public AsmPrinter { 3357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 34b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit SparcAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 35b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner : AsmPrinter(TM, Streamer) {} 364acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke 374acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke virtual const char *getPassName() const { 387c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner return "Sparc Assembly Printer"; 394acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke } 404acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke 4135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); 4235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, 43ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner const char *Modifier = 0); 4435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); 456788faa06ad77fbfb57db7bcf8bc6a79389775a6Chris Lattner 46745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner virtual void EmitInstruction(const MachineInstr *MI) { 477ad07c46362500f7291a92742569e94fd3538dfdChris Lattner SmallString<128> Str; 487ad07c46362500f7291a92742569e94fd3538dfdChris Lattner raw_svector_ostream OS(Str); 497ad07c46362500f7291a92742569e94fd3538dfdChris Lattner printInstruction(MI, OS); 507ad07c46362500f7291a92742569e94fd3538dfdChris Lattner OutStreamer.EmitRawText(OS.str()); 51745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner } 5235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd. 53d95148f073c31924f275a34296da52a7cdefad91Chris Lattner static const char *getRegisterName(unsigned RegNo); 5405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 55f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 56c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 57c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 58f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 59c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 60c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 61db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 6235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS); 631e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 640a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) 650a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const; 664acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke }; 674acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke} // end of anonymous namespace 684acfd039f92fea3b02227020e4e28f2e5db2d92eBrian Gaeke 697c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "SparcGenAsmWriter.inc" 70994b735de8f4bb9b79a967beb80442558625fcb0Chris Lattner 7135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 7235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 73446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke const MachineOperand &MO = MI->getOperand (opNum); 74cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen unsigned TF = MO.getTargetFlags(); 75cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen#ifndef NDEBUG 76cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen // Verify the target flags. 77cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { 78cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen if (MI->getOpcode() == SP::CALL) 79cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen assert(TF == SPII::MO_NO_FLAG && 80cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen "Cannot handle target flags on call address"); 81cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen else if (MI->getOpcode() == SP::SETHIi) 82cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH) && 83cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen "Invalid target flags for address operand on sethi"); 84cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen else 85cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen assert((TF == SPII::MO_LO || TF == SPII::MO_M44 || TF == SPII::MO_L44 || 86cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen TF == SPII::MO_HM) && 87cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen "Invalid target flags for small address operand"); 88446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke } 89cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen#endif 90cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen 91cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen bool CloseParen = true; 92cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen switch (TF) { 93cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen default: 94cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen llvm_unreachable("Unknown target flags on operand"); 95cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_NO_FLAG: 96cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen CloseParen = false; 97cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen break; 98cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_LO: O << "%lo("; break; 99cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_HI: O << "%hi("; break; 100cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_H44: O << "%h44("; break; 101cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_M44: O << "%m44("; break; 102cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_L44: O << "%l44("; break; 103cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_HH: O << "%hh("; break; 104cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen case SPII::MO_HM: O << "%hm("; break; 105cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen } 106cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen 10762aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke switch (MO.getType()) { 1082d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner case MachineOperand::MO_Register: 109590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer O << "%" << StringRef(getRegisterName(MO.getReg())).lower(); 110446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke break; 11162aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke 11263b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner case MachineOperand::MO_Immediate: 1139a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner O << (int)MO.getImm(); 114446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke break; 11537efe6764568a3829fee26aba532283131d1a104Nate Begeman case MachineOperand::MO_MachineBasicBlock: 1161b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 11709c130981456e54305c0d05f7842aa15164d0950Brian Gaeke return; 11862aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke case MachineOperand::MO_GlobalAddress: 119d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(MO.getGlobal()); 120446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke break; 121e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju case MachineOperand::MO_BlockAddress: 122e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju O << GetBlockAddressSymbol(MO.getBlockAddress())->getName(); 123e7cbb792c95cb27a9704551579da19ebcaa06cdbVenkatraman Govindaraju break; 12462aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke case MachineOperand::MO_ExternalSymbol: 12562aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke O << MO.getSymbolName(); 126446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke break; 1278a0ae9e9ca918808d29379b92e245944eff70dd7Brian Gaeke case MachineOperand::MO_ConstantPoolIndex: 12833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" 1298aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner << MO.getIndex(); 1308a0ae9e9ca918808d29379b92e245944eff70dd7Brian Gaeke break; 13162aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke default: 132c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("<unknown operand type>"); 13362aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke } 134446ae11d7c1a6a2a3ce5080bab60123f4dfe63e1Brian Gaeke if (CloseParen) O << ")"; 13562aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke} 13662aa28aef392ccde76888dbb444c567d3f95ef8aBrian Gaeke 137ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattnervoid SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 13835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O, const char *Modifier) { 13935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, opNum, O); 1405b794b98cebbc3982b87780657e0d280c2bcdd04Anton Korobeynikov 141ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner // If this is an ADD operand, emit it like normal operands. 142ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner if (Modifier && !strcmp(Modifier, "arith")) { 143ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner O << ", "; 14435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, opNum+1, O); 145ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner return; 146ad7a3e62085f776ec87e857e769e210a89a0d544Chris Lattner } 1475b794b98cebbc3982b87780657e0d280c2bcdd04Anton Korobeynikov 148d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(opNum+1).isReg() && 1497c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner MI->getOperand(opNum+1).getReg() == SP::G0) 15076acc872b3c63c26a83c2832ece6fa9b04786f24Chris Lattner return; // don't print "+%g0" 151d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(opNum+1).isImm() && 1529a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner MI->getOperand(opNum+1).getImm() == 0) 15376acc872b3c63c26a83c2832ece6fa9b04786f24Chris Lattner return; // don't print "+0" 1545b794b98cebbc3982b87780657e0d280c2bcdd04Anton Korobeynikov 155bc83fd96721eda272d90eafcb3a2a31ef9a2c366Chris Lattner O << "+"; 156cab0abd03ded35006f594c2a7707753eefd88530Jakob Stoklund Olesen printOperand(MI, opNum+1, O); 157bc83fd96721eda272d90eafcb3a2a31ef9a2c366Chris Lattner} 158bc83fd96721eda272d90eafcb3a2a31ef9a2c366Chris Lattner 15935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnerbool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum, 16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 161db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner std::string operand = ""; 162db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner const MachineOperand &MO = MI->getOperand(opNum); 163db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner switch (MO.getType()) { 164bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Operand is not a register"); 165db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner case MachineOperand::MO_Register: 166db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && 167db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner "Operand is not a physical register "); 1681e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju assert(MO.getReg() != SP::O7 && 169c178308b23f796b6f5c15c8b3f742cc7b3336d6bVenkatraman Govindaraju "%o7 is assigned as destination for getpcx!"); 170590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer operand = "%" + StringRef(getRegisterName(MO.getReg())).lower(); 171db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner break; 172db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner } 173db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 174f3047cdbd4b729015fd6b0f64cfc5a861a6f6a2cChris Lattner unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber(); 175d3b31a73e8b58e837510fd429f0f4cb2b8c1a0c2Chris Lattner unsigned bbNum = MI->getParent()->getNumber(); 176db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 177f3047cdbd4b729015fd6b0f64cfc5a861a6f6a2cChris Lattner O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n"; 178f3047cdbd4b729015fd6b0f64cfc5a861a6f6a2cChris Lattner O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ; 179db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 180db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner O << "\t sethi\t" 1811e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum 182c178308b23f796b6f5c15c8b3f742cc7b3336d6bVenkatraman Govindaraju << ")), " << operand << '\n' ; 183db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 184f3047cdbd4b729015fd6b0f64cfc5a861a6f6a2cChris Lattner O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ; 1851e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju O << "\tor\t" << operand 18635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum 18735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner << ")), " << operand << '\n'; 1881e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju O << "\tadd\t" << operand << ", %o7, " << operand << '\n'; 1891e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 190db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner return true; 191db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner} 192db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner 19335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum, 19435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 1959a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner int CC = (int)MI->getOperand(opNum).getImm(); 1967c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner O << SPARCCondCodeToString((SPCC::CondCodes)CC); 1976788faa06ad77fbfb57db7bcf8bc6a79389775a6Chris Lattner} 1986788faa06ad77fbfb57db7bcf8bc6a79389775a6Chris Lattner 199f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov/// PrintAsmOperand - Print out an operand for an inline asm expression. 200f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov/// 201f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikovbool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 202f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov unsigned AsmVariant, 203c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 204c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 2054cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov if (ExtraCode && ExtraCode[0]) { 2064cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov if (ExtraCode[1] != 0) return true; // Unknown modifier. 2074cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov 2084cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov switch (ExtraCode[0]) { 2090518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter default: 2100518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter // See if this is a generic print operand 2110518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 2124cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov case 'r': 2134cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov break; 2144cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov } 2154cf5e2eb6cbbe5e51b18921bd85056aaf4dc1c37Anton Korobeynikov } 216f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov 21735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, OpNo, O); 218f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov 219f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov return false; 220f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov} 221f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov 222f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikovbool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 223c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned OpNo, unsigned AsmVariant, 224c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner const char *ExtraCode, 225c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 226f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov if (ExtraCode && ExtraCode[0]) 227f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov return true; // Unknown modifier 228f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov 229f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov O << '['; 23035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printMemOperand(MI, OpNo, O); 231f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov O << ']'; 232f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov 233f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov return false; 234f369330c2d25b37d2590720e45d11a1d47950ce6Anton Korobeynikov} 2351555a23335400143f2b54a66aedc4b5cbbb79f8dDouglas Gregor 2360a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// isBlockOnlyReachableByFallthough - Return true if the basic block has 2370a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// exactly one predecessor and the control transfer mechanism between 2380a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner/// the predecessor and this block is a fall-through. 239eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris Lattner/// 240eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris Lattner/// This overrides AsmPrinter's implementation to handle delay slots. 241eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris Lattnerbool SparcAsmPrinter:: 242eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris LattnerisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 2430a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If this is a landing pad, it isn't a fall through. If it has no preds, 2440a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // then nothing falls through to it. 2450a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (MBB->isLandingPad() || MBB->pred_empty()) 2460a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 2471e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 2480a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // If there isn't exactly one predecessor, it can't be a fall through. 2490a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 2500a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner ++PI2; 2510a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (PI2 != MBB->pred_end()) 2520a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 2531e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 2540a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner // The predecessor has to be immediately before this block. 2550a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner const MachineBasicBlock *Pred = *PI; 2561e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 2570a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner if (!Pred->isLayoutSuccessor(MBB)) 2580a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner return false; 2591e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju 260eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris Lattner // Check if the last terminator is an unconditional branch. 2610a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner MachineBasicBlock::const_iterator I = Pred->end(); 2625a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I != Pred->begin() && !(--I)->isTerminator()) 263eea3f7e4eeab2840b81d6c84ffdcca1477fbe265Chris Lattner ; // Noop 2645a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng return I == Pred->end() || !I->isBarrier(); 2650a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner} 2660a3f39985b3827a02a7ce1ca5e310b68820fd26dChris Lattner 267a96751fc8ff1cc9a225ffbba73de53e2b9e1ae35Bob Wilson// Force static initialization. 2681e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindarajuextern "C" void LLVMInitializeSparcAsmPrinter() { 2690c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget); 27087c06d617917f4a388fbe9db81198e13cde3e431Chris Lattner RegisterAsmPrinter<SparcAsmPrinter> Y(TheSparcV9Target); 27151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar} 272