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