| Brian Gaeke | 03cac37 | 2004-04-25 07:04:49 +0000 | [diff] [blame] | 1 | //===-- EmitAssembly.cpp - Emit SparcV9 Specific .s File -------------------==// |
| John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 9 | // |
| Misha Brukman | 7eb05a1 | 2003-08-18 14:43:39 +0000 | [diff] [blame] | 10 | // This file implements all of the stuff necessary to output a .s file from |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 11 | // LLVM. The code in this file assumes that the specified module has already |
| 12 | // been compiled into the internal data structures of the Module. |
| 13 | // |
| Chris Lattner | c8e6654 | 2002-04-27 06:56:12 +0000 | [diff] [blame] | 14 | // This code largely consists of two LLVM Pass's: a FunctionPass and a Pass. |
| 15 | // The FunctionPass is pipelined together with all of the rest of the code |
| 16 | // generation stages, and the Pass runs at the end to emit code for global |
| 17 | // variables and such. |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 18 | // |
| 19 | //===----------------------------------------------------------------------===// |
| 20 | |
| Chris Lattner | ca14237 | 2002-04-28 19:55:58 +0000 | [diff] [blame] | 21 | #include "llvm/Constants.h" |
| Vikram S. Adve | 71b265a | 2001-10-28 21:38:52 +0000 | [diff] [blame] | 22 | #include "llvm/DerivedTypes.h" |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 23 | #include "llvm/Module.h" |
| Chris Lattner | 63c52f3 | 2002-04-28 20:40:59 +0000 | [diff] [blame] | 24 | #include "llvm/Pass.h" |
| Chris Lattner | c3728c2 | 2002-04-18 18:15:38 +0000 | [diff] [blame] | 25 | #include "llvm/Assembly/Writer.h" |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 26 | #include "llvm/CodeGen/AsmPrinter.h" |
| Misha Brukman | 0f42585 | 2003-12-17 22:06:28 +0000 | [diff] [blame] | 27 | #include "llvm/CodeGen/MachineConstantPool.h" |
| 28 | #include "llvm/CodeGen/MachineFunction.h" |
| Misha Brukman | 0f42585 | 2003-12-17 22:06:28 +0000 | [diff] [blame] | 29 | #include "llvm/CodeGen/MachineInstr.h" |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 30 | #include "llvm/Support/Mangler.h" |
| Reid Spencer | 7c16caa | 2004-09-01 22:55:40 +0000 | [diff] [blame^] | 31 | #include "llvm/ADT/StringExtras.h" |
| 32 | #include "llvm/ADT/Statistic.h" |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 33 | #include "SparcV9Internals.h" |
| Chris Lattner | 9fb30a4 | 2004-08-16 21:55:02 +0000 | [diff] [blame] | 34 | #include "MachineFunctionInfo.h" |
| Misha Brukman | 1e88cfb | 2003-08-05 16:01:50 +0000 | [diff] [blame] | 35 | #include <string> |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 36 | using namespace llvm; |
| 37 | |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 38 | namespace { |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 39 | Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 40 | } |
| Vikram S. Adve | 270f56a | 2002-03-18 03:07:26 +0000 | [diff] [blame] | 41 | |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 42 | namespace { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 43 | struct SparcV9AsmPrinter : public AsmPrinter { |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 44 | public: |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 45 | enum Sections { |
| 46 | Unknown, |
| 47 | Text, |
| 48 | ReadOnlyData, |
| 49 | InitRWData, |
| 50 | ZeroInitRWData, |
| 51 | } CurSection; |
| 52 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 53 | SparcV9AsmPrinter(std::ostream &OS, TargetMachine &TM) |
| 54 | : AsmPrinter(OS, TM), CurSection(Unknown) { |
| 55 | ZeroDirective = 0; // No way to get zeros. |
| 56 | Data16bitsDirective = "\t.half\t"; |
| 57 | Data32bitsDirective = "\t.word\t"; |
| 58 | Data64bitsDirective = "\t.xword\t"; |
| 59 | CommentString = "!"; |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 60 | } |
| 61 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 62 | const char *getPassName() const { |
| 63 | return "SparcV9 Assembly Printer"; |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 64 | } |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 65 | |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 66 | // Print a constant (which may be an aggregate) prefixed by all the |
| 67 | // appropriate directives. Uses printConstantValueOnly() to print the |
| 68 | // value or values. |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 69 | void printConstant(const Constant* CV, const std::string &valID) { |
| 70 | emitAlignment(TM.getTargetData().getTypeAlignmentShift(CV->getType())); |
| 71 | O << "\t.type" << "\t" << valID << ",#object\n"; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 72 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 73 | unsigned constSize = TM.getTargetData().getTypeSize(CV->getType()); |
| 74 | O << "\t.size" << "\t" << valID << "," << constSize << "\n"; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 75 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 76 | O << valID << ":\n"; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 77 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 78 | emitGlobalConstant(CV); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 81 | // enterSection - Use this method to enter a different section of the output |
| 82 | // executable. This is used to only output necessary section transitions. |
| 83 | // |
| 84 | void enterSection(enum Sections S) { |
| 85 | if (S == CurSection) return; // Only switch section if necessary |
| 86 | CurSection = S; |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 87 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 88 | O << "\n\t.section "; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 89 | switch (S) |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 90 | { |
| 91 | default: assert(0 && "Bad section name!"); |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 92 | case Text: O << "\".text\""; break; |
| 93 | case ReadOnlyData: O << "\".rodata\",#alloc"; break; |
| 94 | case InitRWData: O << "\".data\",#alloc,#write"; break; |
| 95 | case ZeroInitRWData: O << "\".bss\",#alloc,#write"; break; |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 96 | } |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 97 | O << "\n"; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 98 | } |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 99 | |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 100 | // getID Wrappers - Ensure consistent usage |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 101 | // Symbol names in SparcV9 assembly language have these rules: |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 102 | // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }* |
| 103 | // (b) A name beginning in "." is treated as a local name. |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 104 | std::string getID(const Function *F) { |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 105 | return Mang->getValueName(F); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 106 | } |
| 107 | std::string getID(const BasicBlock *BB) { |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 108 | return ".L_" + getID(BB->getParent()) + "_" + Mang->getValueName(BB); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 109 | } |
| 110 | std::string getID(const GlobalVariable *GV) { |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 111 | return Mang->getValueName(GV); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 112 | } |
| 113 | std::string getID(const Constant *CV) { |
| Misha Brukman | 929d1d1 | 2004-01-15 22:44:19 +0000 | [diff] [blame] | 114 | return ".C_" + Mang->getValueName(CV); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 115 | } |
| 116 | std::string getID(const GlobalValue *GV) { |
| 117 | if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV)) |
| 118 | return getID(V); |
| 119 | else if (const Function *F = dyn_cast<Function>(GV)) |
| 120 | return getID(F); |
| 121 | assert(0 && "Unexpected type of GlobalValue!"); |
| 122 | return ""; |
| 123 | } |
| Vikram S. Adve | c3a5e4e | 2002-08-22 02:58:36 +0000 | [diff] [blame] | 124 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 125 | virtual bool runOnMachineFunction(MachineFunction &MF) { |
| 126 | setupMachineFunction(MF); |
| 127 | emitFunction(MF); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 128 | return false; |
| 129 | } |
| 130 | |
| 131 | virtual bool doFinalization(Module &M) { |
| 132 | emitGlobals(M); |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 133 | AsmPrinter::doFinalization(M); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 134 | return false; |
| 135 | } |
| 136 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 137 | void emitFunction(MachineFunction &F); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 138 | private : |
| 139 | void emitBasicBlock(const MachineBasicBlock &MBB); |
| 140 | void emitMachineInst(const MachineInstr *MI); |
| 141 | |
| 142 | unsigned int printOperands(const MachineInstr *MI, unsigned int opNum); |
| 143 | void printOneOperand(const MachineOperand &Op, MachineOpCode opCode); |
| 144 | |
| 145 | bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum); |
| 146 | bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum); |
| 147 | |
| 148 | unsigned getOperandMask(unsigned Opcode) { |
| 149 | switch (Opcode) { |
| 150 | case V9::SUBccr: |
| 151 | case V9::SUBcci: return 1 << 3; // Remove CC argument |
| 152 | default: return 0; // By default, don't hack operands... |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | void emitGlobals(const Module &M); |
| 157 | void printGlobalVariable(const GlobalVariable *GV); |
| 158 | }; |
| 159 | |
| 160 | } // End anonymous namespace |
| Chris Lattner | 036a317 | 2001-09-19 13:47:27 +0000 | [diff] [blame] | 161 | |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 162 | inline bool |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 163 | SparcV9AsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI, |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 164 | unsigned int opNum) { |
| Brian Gaeke | b22186a | 2004-02-11 20:47:34 +0000 | [diff] [blame] | 165 | switch (MI->getOpcode()) { |
| Misha Brukman | 8bde6a6 | 2003-05-27 22:35:43 +0000 | [diff] [blame] | 166 | case V9::JMPLCALLr: |
| 167 | case V9::JMPLCALLi: |
| 168 | case V9::JMPLRETr: |
| 169 | case V9::JMPLRETi: |
| Misha Brukman | 56f4fa1 | 2003-05-20 20:32:24 +0000 | [diff] [blame] | 170 | return (opNum == 0); |
| 171 | default: |
| 172 | return false; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 173 | } |
| 174 | } |
| 175 | |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 176 | inline bool |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 177 | SparcV9AsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI, |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 178 | unsigned int opNum) { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 179 | if (TM.getInstrInfo()->isLoad(MI->getOpcode())) |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 180 | return (opNum == 0); |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 181 | else if (TM.getInstrInfo()->isStore(MI->getOpcode())) |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 182 | return (opNum == 1); |
| 183 | else |
| 184 | return false; |
| 185 | } |
| 186 | |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 187 | unsigned int |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 188 | SparcV9AsmPrinter::printOperands(const MachineInstr *MI, unsigned opNum) { |
| Vikram S. Adve | 4e1ee14 | 2002-07-10 21:41:21 +0000 | [diff] [blame] | 189 | const MachineOperand& mop = MI->getOperand(opNum); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 190 | if (OpIsBranchTargetLabel(MI, opNum)) { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 191 | printOneOperand(mop, MI->getOpcode()); |
| 192 | O << "+"; |
| 193 | printOneOperand(MI->getOperand(opNum+1), MI->getOpcode()); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 194 | return 2; |
| 195 | } else if (OpIsMemoryAddressBase(MI, opNum)) { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 196 | O << "["; |
| 197 | printOneOperand(mop, MI->getOpcode()); |
| 198 | O << "+"; |
| 199 | printOneOperand(MI->getOperand(opNum+1), MI->getOpcode()); |
| 200 | O << "]"; |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 201 | return 2; |
| 202 | } else { |
| Brian Gaeke | b22186a | 2004-02-11 20:47:34 +0000 | [diff] [blame] | 203 | printOneOperand(mop, MI->getOpcode()); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 204 | return 1; |
| 205 | } |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 206 | } |
| 207 | |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 208 | void |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 209 | SparcV9AsmPrinter::printOneOperand(const MachineOperand &mop, |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 210 | MachineOpCode opCode) |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 211 | { |
| Vikram S. Adve | 4e1ee14 | 2002-07-10 21:41:21 +0000 | [diff] [blame] | 212 | bool needBitsFlag = true; |
| 213 | |
| Alkis Evlogimenos | aaba463 | 2003-12-14 13:24:17 +0000 | [diff] [blame] | 214 | if (mop.isHiBits32()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 215 | O << "%lm("; |
| Alkis Evlogimenos | aaba463 | 2003-12-14 13:24:17 +0000 | [diff] [blame] | 216 | else if (mop.isLoBits32()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 217 | O << "%lo("; |
| Alkis Evlogimenos | aaba463 | 2003-12-14 13:24:17 +0000 | [diff] [blame] | 218 | else if (mop.isHiBits64()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 219 | O << "%hh("; |
| Alkis Evlogimenos | aaba463 | 2003-12-14 13:24:17 +0000 | [diff] [blame] | 220 | else if (mop.isLoBits64()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 221 | O << "%hm("; |
| Vikram S. Adve | 4e1ee14 | 2002-07-10 21:41:21 +0000 | [diff] [blame] | 222 | else |
| 223 | needBitsFlag = false; |
| 224 | |
| Chris Lattner | 6a30b02 | 2002-10-28 04:45:29 +0000 | [diff] [blame] | 225 | switch (mop.getType()) |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 226 | { |
| Vikram S. Adve | d09c4c3 | 2003-07-06 20:13:59 +0000 | [diff] [blame] | 227 | case MachineOperand::MO_VirtualRegister: |
| Vikram S. Adve | 6528067 | 2003-07-10 19:42:11 +0000 | [diff] [blame] | 228 | case MachineOperand::MO_CCRegister: |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 229 | case MachineOperand::MO_MachineRegister: |
| 230 | { |
| Alkis Evlogimenos | 8cdd021 | 2004-02-13 21:01:20 +0000 | [diff] [blame] | 231 | int regNum = (int)mop.getReg(); |
| Vikram S. Adve | 6528067 | 2003-07-10 19:42:11 +0000 | [diff] [blame] | 232 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 233 | if (regNum == TM.getRegInfo()->getInvalidRegNum()) { |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 234 | // better to print code with NULL registers than to die |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 235 | O << "<NULL VALUE>"; |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 236 | } else { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 237 | O << "%" << TM.getRegInfo()->getUnifiedRegName(regNum); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 238 | } |
| 239 | break; |
| 240 | } |
| Misha Brukman | 8d53167 | 2003-05-31 06:22:37 +0000 | [diff] [blame] | 241 | |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 242 | case MachineOperand::MO_ConstantPoolIndex: |
| 243 | { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 244 | O << ".CPI_" << CurrentFnName << "_" << mop.getConstantPoolIndex(); |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 245 | break; |
| 246 | } |
| 247 | |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 248 | case MachineOperand::MO_PCRelativeDisp: |
| 249 | { |
| 250 | const Value *Val = mop.getVRegValue(); |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 251 | assert(Val && "\tNULL Value in SparcV9AsmPrinter"); |
| Misha Brukman | 8d53167 | 2003-05-31 06:22:37 +0000 | [diff] [blame] | 252 | |
| Chris Lattner | f26a8ee | 2003-07-23 15:30:06 +0000 | [diff] [blame] | 253 | if (const BasicBlock *BB = dyn_cast<BasicBlock>(Val)) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 254 | O << getID(BB); |
| Brian Gaeke | f2ff5dd | 2004-05-04 21:09:02 +0000 | [diff] [blame] | 255 | else if (const Function *F = dyn_cast<Function>(Val)) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 256 | O << getID(F); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 257 | else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val)) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 258 | O << getID(GV); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 259 | else if (const Constant *CV = dyn_cast<Constant>(Val)) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 260 | O << getID(CV); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 261 | else |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 262 | assert(0 && "Unrecognized value in SparcV9AsmPrinter"); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 263 | break; |
| 264 | } |
| Misha Brukman | 8d53167 | 2003-05-31 06:22:37 +0000 | [diff] [blame] | 265 | |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 266 | case MachineOperand::MO_SignExtendedImmed: |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 267 | O << mop.getImmedValue(); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 268 | break; |
| Misha Brukman | 8d53167 | 2003-05-31 06:22:37 +0000 | [diff] [blame] | 269 | |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 270 | case MachineOperand::MO_UnextendedImmed: |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 271 | O << (uint64_t) mop.getImmedValue(); |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 272 | break; |
| Misha Brukman | 8d53167 | 2003-05-31 06:22:37 +0000 | [diff] [blame] | 273 | |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 274 | default: |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 275 | O << mop; // use dump field |
| Vikram S. Adve | 96b801a | 2003-05-31 07:27:17 +0000 | [diff] [blame] | 276 | break; |
| 277 | } |
| Vikram S. Adve | 4e1ee14 | 2002-07-10 21:41:21 +0000 | [diff] [blame] | 278 | |
| 279 | if (needBitsFlag) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 280 | O << ")"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 281 | } |
| 282 | |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 283 | void SparcV9AsmPrinter::emitMachineInst(const MachineInstr *MI) { |
| Brian Gaeke | b22186a | 2004-02-11 20:47:34 +0000 | [diff] [blame] | 284 | unsigned Opcode = MI->getOpcode(); |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 285 | |
| Brian Gaeke | 7593525 | 2004-08-18 20:04:24 +0000 | [diff] [blame] | 286 | if (Opcode == V9::PHI) |
| 287 | return; // Ignore Machine-PHI nodes. |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 288 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 289 | O << "\t" << TM.getInstrInfo()->getName(Opcode) << "\t"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 290 | |
| 291 | unsigned Mask = getOperandMask(Opcode); |
| 292 | |
| 293 | bool NeedComma = false; |
| 294 | unsigned N = 1; |
| 295 | for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N) |
| 296 | if (! ((1 << OpNum) & Mask)) { // Ignore this operand? |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 297 | if (NeedComma) O << ", "; // Handle comma outputting |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 298 | NeedComma = true; |
| 299 | N = printOperands(MI, OpNum); |
| Chris Lattner | 5961102 | 2002-11-17 22:57:23 +0000 | [diff] [blame] | 300 | } else |
| 301 | N = 1; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 302 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 303 | O << "\n"; |
| Brian Gaeke | 4547ab1 | 2003-10-06 15:41:21 +0000 | [diff] [blame] | 304 | ++EmittedInsts; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 305 | } |
| 306 | |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 307 | void SparcV9AsmPrinter::emitBasicBlock(const MachineBasicBlock &MBB) { |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 308 | // Emit a label for the basic block |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 309 | O << getID(MBB.getBasicBlock()) << ":\n"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 310 | |
| 311 | // Loop over all of the instructions in the basic block... |
| Misha Brukman | 181ea4a | 2002-10-28 20:01:13 +0000 | [diff] [blame] | 312 | for (MachineBasicBlock::const_iterator MII = MBB.begin(), MIE = MBB.end(); |
| Chris Lattner | 8710aab | 2002-10-28 01:41:47 +0000 | [diff] [blame] | 313 | MII != MIE; ++MII) |
| Alkis Evlogimenos | 80da865 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 314 | emitMachineInst(MII); |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 315 | O << "\n"; // Separate BB's with newlines |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 316 | } |
| 317 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 318 | void SparcV9AsmPrinter::emitFunction(MachineFunction &MF) { |
| 319 | O << "!****** Outputing Function: " << CurrentFnName << " ******\n"; |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 320 | |
| 321 | // Emit constant pool for this function |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 322 | const MachineConstantPool *MCP = MF.getConstantPool(); |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 323 | const std::vector<Constant*> &CP = MCP->getConstants(); |
| 324 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 325 | enterSection(ReadOnlyData); |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 326 | for (unsigned i = 0, e = CP.size(); i != e; ++i) { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 327 | std::string cpiName = ".CPI_" + CurrentFnName + "_" + utostr(i); |
| Misha Brukman | 2133b05 | 2003-11-07 17:45:28 +0000 | [diff] [blame] | 328 | printConstant(CP[i], cpiName); |
| 329 | } |
| 330 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 331 | enterSection(Text); |
| 332 | O << "\t.align\t4\n\t.global\t" << CurrentFnName << "\n"; |
| 333 | //O << "\t.type\t" << CurrentFnName << ",#function\n"; |
| 334 | O << "\t.type\t" << CurrentFnName << ", 2\n"; |
| 335 | O << CurrentFnName << ":\n"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 336 | |
| Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 337 | // Output code for all of the basic blocks in the function... |
| Chris Lattner | 4d84d49 | 2002-12-28 20:15:01 +0000 | [diff] [blame] | 338 | for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E;++I) |
| Misha Brukman | 181ea4a | 2002-10-28 20:01:13 +0000 | [diff] [blame] | 339 | emitBasicBlock(*I); |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 340 | |
| 341 | // Output a .size directive so the debugger knows the extents of the function |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 342 | O << ".EndOf_" << CurrentFnName << ":\n\t.size " |
| 343 | << CurrentFnName << ", .EndOf_" |
| 344 | << CurrentFnName << "-" << CurrentFnName << "\n"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 345 | |
| Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 346 | // Put some spaces between the functions |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 347 | O << "\n\n"; |
| Chris Lattner | d682045 | 2002-02-03 23:41:08 +0000 | [diff] [blame] | 348 | } |
| 349 | |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 350 | void SparcV9AsmPrinter::printGlobalVariable(const GlobalVariable* GV) { |
| Vikram S. Adve | 8cbdbd8 | 2002-09-16 15:54:02 +0000 | [diff] [blame] | 351 | if (GV->hasExternalLinkage()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 352 | O << "\t.global\t" << getID(GV) << "\n"; |
| Vikram S. Adve | 71b265a | 2001-10-28 21:38:52 +0000 | [diff] [blame] | 353 | |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 354 | if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue()) { |
| Vikram S. Adve | 71b265a | 2001-10-28 21:38:52 +0000 | [diff] [blame] | 355 | printConstant(GV->getInitializer(), getID(GV)); |
| Misha Brukman | 6675f98 | 2003-11-13 00:22:19 +0000 | [diff] [blame] | 356 | } else { |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 357 | const Type *ValTy = GV->getType()->getElementType(); |
| 358 | emitAlignment(TM.getTargetData().getTypeAlignmentShift(ValTy)); |
| 359 | O << "\t.type\t" << getID(GV) << ",#object\n"; |
| 360 | O << "\t.reserve\t" << getID(GV) << "," |
| 361 | << TM.getTargetData().getTypeSize(GV->getType()->getElementType()) |
| 362 | << "\n"; |
| Vikram S. Adve | 71b265a | 2001-10-28 21:38:52 +0000 | [diff] [blame] | 363 | } |
| 364 | } |
| 365 | |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 366 | void SparcV9AsmPrinter::emitGlobals(const Module &M) { |
| Chris Lattner | c93df6b | 2002-08-07 21:39:48 +0000 | [diff] [blame] | 367 | // Output global variables... |
| Vikram S. Adve | 10d8164 | 2002-10-13 00:32:18 +0000 | [diff] [blame] | 368 | for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI) |
| 369 | if (! GI->isExternal()) { |
| 370 | assert(GI->hasInitializer()); |
| 371 | if (GI->isConstant()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 372 | enterSection(ReadOnlyData); // read-only, initialized data |
| Vikram S. Adve | 10d8164 | 2002-10-13 00:32:18 +0000 | [diff] [blame] | 373 | else if (GI->getInitializer()->isNullValue()) |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 374 | enterSection(ZeroInitRWData); // read-write zero data |
| Vikram S. Adve | 10d8164 | 2002-10-13 00:32:18 +0000 | [diff] [blame] | 375 | else |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 376 | enterSection(InitRWData); // read-write non-zero data |
| Vikram S. Adve | 10d8164 | 2002-10-13 00:32:18 +0000 | [diff] [blame] | 377 | |
| 378 | printGlobalVariable(GI); |
| Chris Lattner | c93df6b | 2002-08-07 21:39:48 +0000 | [diff] [blame] | 379 | } |
| Chris Lattner | c93df6b | 2002-08-07 21:39:48 +0000 | [diff] [blame] | 380 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 381 | O << "\n"; |
| Vikram S. Adve | 71b265a | 2001-10-28 21:38:52 +0000 | [diff] [blame] | 382 | } |
| 383 | |
| Chris Lattner | 12754fe | 2004-08-18 05:29:08 +0000 | [diff] [blame] | 384 | FunctionPass *llvm::createAsmPrinterPass(std::ostream &Out, TargetMachine &TM) { |
| Brian Gaeke | 94e95d2 | 2004-02-25 18:44:15 +0000 | [diff] [blame] | 385 | return new SparcV9AsmPrinter(Out, TM); |
| Chris Lattner | e772d28 | 2002-02-03 07:48:06 +0000 | [diff] [blame] | 386 | } |