PPCAsmPrinter.cpp revision 564da5d646dfeb56df931b42fefa7c5f2591057e
17842e56b97ce677b83bdab09cda48bc2d89ac75aJust//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// 28413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbod// 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust// The LLVM Compiler Infrastructure 47842e56b97ce677b83bdab09cda48bc2d89ac75aJust// 57842e56b97ce677b83bdab09cda48bc2d89ac75aJust// This file is distributed under the University of Illinois Open Source 67842e56b97ce677b83bdab09cda48bc2d89ac75aJust// License. See LICENSE.TXT for details. 77842e56b97ce677b83bdab09cda48bc2d89ac75aJust// 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust//===----------------------------------------------------------------------===// 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust// 10df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// This file contains a printer that converts from our internal representation 11df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// of machine-dependent LLVM code to PowerPC assembly language. This printer is 12df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// the output mechanism used by `llc'. 13df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// 14df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// Documentation at http://developer.apple.com/documentation/DeveloperTools/ 15df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 16df22c27d923417c2cd2682704145ca81f3a7aaf3jvr// 17df22c27d923417c2cd2682704145ca81f3a7aaf3jvr//===----------------------------------------------------------------------===// 18df22c27d923417c2cd2682704145ca81f3a7aaf3jvr 19df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#define DEBUG_TYPE "asmprinter" 20df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "PPC.h" 21df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "PPCPredicates.h" 22df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "PPCTargetMachine.h" 23df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "PPCSubtarget.h" 24df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "llvm/Constants.h" 25df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "llvm/DerivedTypes.h" 26df22c27d923417c2cd2682704145ca81f3a7aaf3jvr#include "llvm/Module.h" 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/Assembly/Writer.h" 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/CodeGen/AsmPrinter.h" 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/CodeGen/DwarfWriter.h" 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/CodeGen/MachineModuleInfo.h" 317842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/CodeGen/MachineFunctionPass.h" 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/CodeGen/MachineInstr.h" 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/Support/Mangler.h" 347268e24408586e5a52d716149cd214a301924778Just#include "llvm/Support/MathExtras.h" 357268e24408586e5a52d716149cd214a301924778Just#include "llvm/Support/CommandLine.h" 367268e24408586e5a52d716149cd214a301924778Just#include "llvm/Support/Debug.h" 377268e24408586e5a52d716149cd214a301924778Just#include "llvm/Support/Compiler.h" 387842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/Target/TargetAsmInfo.h" 39cb317bfad3213dc009e8150149d5ce9a70356f10Just#include "llvm/Target/MRegisterInfo.h" 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/Target/TargetInstrInfo.h" 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/Target/TargetOptions.h" 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/ADT/Statistic.h" 437842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/ADT/StringExtras.h" 447842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include <set> 457842e56b97ce677b83bdab09cda48bc2d89ac75aJustusing namespace llvm; 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 477842e56b97ce677b83bdab09cda48bc2d89ac75aJustSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 487842e56b97ce677b83bdab09cda48bc2d89ac75aJust 497842e56b97ce677b83bdab09cda48bc2d89ac75aJustnamespace { 507842e56b97ce677b83bdab09cda48bc2d89ac75aJust struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter { 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust std::set<std::string> FnStubs, GVStubs; 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust const PPCSubtarget &Subtarget; 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust PPCAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust : AsmPrinter(O, TM, T), Subtarget(TM.getSubtarget<PPCSubtarget>()) { 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust virtual const char *getPassName() const { 597842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "PowerPC Assembly Printer"; 607842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 617842e56b97ce677b83bdab09cda48bc2d89ac75aJust 627842e56b97ce677b83bdab09cda48bc2d89ac75aJust PPCTargetMachine &getTM() { 637842e56b97ce677b83bdab09cda48bc2d89ac75aJust return static_cast<PPCTargetMachine&>(TM); 6483f069d66c3165a8899c35296053f7fbd350a9f6fcoiffie } 6583f069d66c3165a8899c35296053f7fbd350a9f6fcoiffie 6683f069d66c3165a8899c35296053f7fbd350a9f6fcoiffie unsigned enumRegToMachineReg(unsigned enumReg) { 6783f069d66c3165a8899c35296053f7fbd350a9f6fcoiffie switch (enumReg) { 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust default: assert(0 && "Unhandled register!"); break; 69f34c6f393799c77de669dab4ad84f299b11f0875jvr case PPC::CR0: return 0; 70f34c6f393799c77de669dab4ad84f299b11f0875jvr case PPC::CR1: return 1; 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust case PPC::CR2: return 2; 721332d3e5491140c90fde2dfac5225ce820c64e20jvr case PPC::CR3: return 3; 731332d3e5491140c90fde2dfac5225ce820c64e20jvr case PPC::CR4: return 4; 74c3403cfbd4ceb9f5cea0080745ea091aff9f4fbdjvr case PPC::CR5: return 5; 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust case PPC::CR6: return 6; 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust case PPC::CR7: return 7; 777842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust abort(); 797842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 807842e56b97ce677b83bdab09cda48bc2d89ac75aJust 817842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// printInstruction - This method is automatically generated by tablegen 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// from the instruction set description. This method returns true if the 83c3403cfbd4ceb9f5cea0080745ea091aff9f4fbdjvr /// machine instruction was sufficiently described to print it, otherwise it 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// returns false. 857842e56b97ce677b83bdab09cda48bc2d89ac75aJust bool printInstruction(const MachineInstr *MI); 861332d3e5491140c90fde2dfac5225ce820c64e20jvr 871332d3e5491140c90fde2dfac5225ce820c64e20jvr void printMachineInstruction(const MachineInstr *MI); 881332d3e5491140c90fde2dfac5225ce820c64e20jvr void printOp(const MachineOperand &MO); 891332d3e5491140c90fde2dfac5225ce820c64e20jvr 907842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// stripRegisterPrefix - This method strips the character prefix from a 917842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// register name so that only the number is left. Used by for linux asm. 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust const char *stripRegisterPrefix(const char *RegName) { 9396b321c8aea4dc64110d15a541c6f85152ae19cfBehdad Esfahbod switch (RegName[0]) { 9496b321c8aea4dc64110d15a541c6f85152ae19cfBehdad Esfahbod case 'r': 9596b321c8aea4dc64110d15a541c6f85152ae19cfBehdad Esfahbod case 'f': 9696b321c8aea4dc64110d15a541c6f85152ae19cfBehdad Esfahbod case 'v': return RegName + 1; 977842e56b97ce677b83bdab09cda48bc2d89ac75aJust case 'c': if (RegName[1] == 'r') return RegName + 2; 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust return RegName; 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// printRegister - Print register according to target requirements. 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust /// 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust void printRegister(const MachineOperand &MO, bool R0AsZero) { 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust unsigned RegNo = MO.getReg(); 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust // If we should use 0 for R0. 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (R0AsZero && RegNo == PPC::R0) { 111e73b8a53a54b2e9cb6a108412cbeb138e8fca7c2jvr O << "0"; 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust return; 113a220bf3567a71be4fb5e9f5335b3a0b92f222491jvr } 114a220bf3567a71be4fb5e9f5335b3a0b92f222491jvr 115e73b8a53a54b2e9cb6a108412cbeb138e8fca7c2jvr const char *RegName = TM.getRegisterInfo()->get(RegNo).Name; 116e73b8a53a54b2e9cb6a108412cbeb138e8fca7c2jvr // Linux assembler (Others?) does not take register mnemonics. 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust // FIXME - What about special registers used in mfspr/mtspr? 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust O << RegName; 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 12164892f5a34ad2eda5b7675566837b546e3b717e6Just 12264892f5a34ad2eda5b7675566837b546e3b717e6Just void printOperand(const MachineInstr *MI, unsigned OpNo) { 12364892f5a34ad2eda5b7675566837b546e3b717e6Just const MachineOperand &MO = MI->getOperand(OpNo); 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (MO.isRegister()) { 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust printRegister(MO, false); 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust } else if (MO.isImmediate()) { 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust O << MO.getImm(); 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust } else { 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust printOp(MO); 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 134266bf21dbe3c4b8aad86dfccbe97549fb04d18c1jvr unsigned AsmVariant, const char *ExtraCode); 135266bf21dbe3c4b8aad86dfccbe97549fb04d18c1jvr bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 136266bf21dbe3c4b8aad86dfccbe97549fb04d18c1jvr unsigned AsmVariant, const char *ExtraCode); 137266bf21dbe3c4b8aad86dfccbe97549fb04d18c1jvr 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) { 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust char value = MI->getOperand(OpNo).getImm(); 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = (value << (32-5)) >> (32-5); 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust O << (int)value; 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) { 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust unsigned char value = MI->getOperand(OpNo).getImm(); 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert(value <= 31 && "Invalid u5imm argument!"); 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust O << (unsigned int)value; 148b74f03c7e5cf0823b4adefbd84a6c6c59a507889jvr } 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) { 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust unsigned char value = MI->getOperand(OpNo).getImm(); 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert(value <= 63 && "Invalid u6imm argument!"); 152b74f03c7e5cf0823b4adefbd84a6c6c59a507889jvr O << (unsigned int)value; 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1547842e56b97ce677b83bdab09cda48bc2d89ac75aJust void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) { 1557842e56b97ce677b83bdab09cda48bc2d89ac75aJust O << (short)MI->getOperand(OpNo).getImm(); 1567842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 157 void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) { 158 O << (unsigned short)MI->getOperand(OpNo).getImm(); 159 } 160 void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) { 161 if (MI->getOperand(OpNo).isImmediate()) { 162 O << (short)(MI->getOperand(OpNo).getImm()*4); 163 } else { 164 O << "lo16("; 165 printOp(MI->getOperand(OpNo)); 166 if (TM.getRelocationModel() == Reloc::PIC_) 167 O << "-\"L" << getFunctionNumber() << "$pb\")"; 168 else 169 O << ')'; 170 } 171 } 172 void printBranchOperand(const MachineInstr *MI, unsigned OpNo) { 173 // Branches can take an immediate operand. This is used by the branch 174 // selection pass to print $+8, an eight byte displacement from the PC. 175 if (MI->getOperand(OpNo).isImmediate()) { 176 O << "$+" << MI->getOperand(OpNo).getImm()*4; 177 } else { 178 printOp(MI->getOperand(OpNo)); 179 } 180 } 181 void printCallOperand(const MachineInstr *MI, unsigned OpNo) { 182 const MachineOperand &MO = MI->getOperand(OpNo); 183 if (TM.getRelocationModel() != Reloc::Static) { 184 if (MO.getType() == MachineOperand::MO_GlobalAddress) { 185 GlobalValue *GV = MO.getGlobal(); 186 if (((GV->isDeclaration() || GV->hasWeakLinkage() || 187 GV->hasLinkOnceLinkage()))) { 188 // Dynamically-resolved functions need a stub for the function. 189 std::string Name = Mang->getValueName(GV); 190 FnStubs.insert(Name); 191 O << "L" << Name << "$stub"; 192 if (GV->hasExternalWeakLinkage()) 193 ExtWeakSymbols.insert(GV); 194 return; 195 } 196 } 197 if (MO.getType() == MachineOperand::MO_ExternalSymbol) { 198 std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); 199 FnStubs.insert(Name); 200 O << "L" << Name << "$stub"; 201 return; 202 } 203 } 204 205 printOp(MI->getOperand(OpNo)); 206 } 207 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) { 208 O << (int)MI->getOperand(OpNo).getImm()*4; 209 } 210 void printPICLabel(const MachineInstr *MI, unsigned OpNo) { 211 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 212 O << "\"L" << getFunctionNumber() << "$pb\":"; 213 } 214 void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { 215 if (MI->getOperand(OpNo).isImmediate()) { 216 printS16ImmOperand(MI, OpNo); 217 } else { 218 if (Subtarget.isDarwin()) O << "ha16("; 219 printOp(MI->getOperand(OpNo)); 220 if (TM.getRelocationModel() == Reloc::PIC_) 221 O << "-\"L" << getFunctionNumber() << "$pb\""; 222 if (Subtarget.isDarwin()) 223 O << ')'; 224 else 225 O << "@ha"; 226 } 227 } 228 void printSymbolLo(const MachineInstr *MI, unsigned OpNo) { 229 if (MI->getOperand(OpNo).isImmediate()) { 230 printS16ImmOperand(MI, OpNo); 231 } else { 232 if (Subtarget.isDarwin()) O << "lo16("; 233 printOp(MI->getOperand(OpNo)); 234 if (TM.getRelocationModel() == Reloc::PIC_) 235 O << "-\"L" << getFunctionNumber() << "$pb\""; 236 if (Subtarget.isDarwin()) 237 O << ')'; 238 else 239 O << "@l"; 240 } 241 } 242 void printcrbitm(const MachineInstr *MI, unsigned OpNo) { 243 unsigned CCReg = MI->getOperand(OpNo).getReg(); 244 unsigned RegNo = enumRegToMachineReg(CCReg); 245 O << (0x80 >> RegNo); 246 } 247 // The new addressing mode printers. 248 void printMemRegImm(const MachineInstr *MI, unsigned OpNo) { 249 printSymbolLo(MI, OpNo); 250 O << '('; 251 if (MI->getOperand(OpNo+1).isRegister() && 252 MI->getOperand(OpNo+1).getReg() == PPC::R0) 253 O << "0"; 254 else 255 printOperand(MI, OpNo+1); 256 O << ')'; 257 } 258 void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) { 259 if (MI->getOperand(OpNo).isImmediate()) 260 printS16X4ImmOperand(MI, OpNo); 261 else 262 printSymbolLo(MI, OpNo); 263 O << '('; 264 if (MI->getOperand(OpNo+1).isRegister() && 265 MI->getOperand(OpNo+1).getReg() == PPC::R0) 266 O << "0"; 267 else 268 printOperand(MI, OpNo+1); 269 O << ')'; 270 } 271 272 void printMemRegReg(const MachineInstr *MI, unsigned OpNo) { 273 // When used as the base register, r0 reads constant zero rather than 274 // the value contained in the register. For this reason, the darwin 275 // assembler requires that we print r0 as 0 (no r) when used as the base. 276 const MachineOperand &MO = MI->getOperand(OpNo); 277 printRegister(MO, true); 278 O << ", "; 279 printOperand(MI, OpNo+1); 280 } 281 282 void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 283 const char *Modifier); 284 285 virtual bool runOnMachineFunction(MachineFunction &F) = 0; 286 virtual bool doFinalization(Module &M) = 0; 287 288 virtual void EmitExternalGlobal(const GlobalVariable *GV); 289 }; 290 291 /// LinuxAsmPrinter - PowerPC assembly printer, customized for Linux 292 struct VISIBILITY_HIDDEN LinuxAsmPrinter : public PPCAsmPrinter { 293 294 DwarfWriter DW; 295 296 LinuxAsmPrinter(std::ostream &O, PPCTargetMachine &TM, 297 const TargetAsmInfo *T) 298 : PPCAsmPrinter(O, TM, T), DW(O, this, T) { 299 } 300 301 virtual const char *getPassName() const { 302 return "Linux PPC Assembly Printer"; 303 } 304 305 bool runOnMachineFunction(MachineFunction &F); 306 bool doInitialization(Module &M); 307 bool doFinalization(Module &M); 308 309 void getAnalysisUsage(AnalysisUsage &AU) const { 310 AU.setPreservesAll(); 311 AU.addRequired<MachineModuleInfo>(); 312 PPCAsmPrinter::getAnalysisUsage(AU); 313 } 314 315 /// getSectionForFunction - Return the section that we should emit the 316 /// specified function body into. 317 virtual std::string getSectionForFunction(const Function &F) const; 318 }; 319 320 /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS 321 /// X 322 struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter { 323 324 DwarfWriter DW; 325 MachineModuleInfo *MMI; 326 327 DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM, 328 const TargetAsmInfo *T) 329 : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) { 330 } 331 332 virtual const char *getPassName() const { 333 return "Darwin PPC Assembly Printer"; 334 } 335 336 bool runOnMachineFunction(MachineFunction &F); 337 bool doInitialization(Module &M); 338 bool doFinalization(Module &M); 339 340 void getAnalysisUsage(AnalysisUsage &AU) const { 341 AU.setPreservesAll(); 342 AU.addRequired<MachineModuleInfo>(); 343 PPCAsmPrinter::getAnalysisUsage(AU); 344 } 345 346 /// getSectionForFunction - Return the section that we should emit the 347 /// specified function body into. 348 virtual std::string getSectionForFunction(const Function &F) const; 349 }; 350} // end of anonymous namespace 351 352// Include the auto-generated portion of the assembly writer 353#include "PPCGenAsmWriter.inc" 354 355void PPCAsmPrinter::printOp(const MachineOperand &MO) { 356 switch (MO.getType()) { 357 case MachineOperand::MO_Immediate: 358 cerr << "printOp() does not handle immediate values\n"; 359 abort(); 360 return; 361 362 case MachineOperand::MO_MachineBasicBlock: 363 printBasicBlockLabel(MO.getMBB()); 364 return; 365 case MachineOperand::MO_JumpTableIndex: 366 O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 367 << '_' << MO.getIndex(); 368 // FIXME: PIC relocation model 369 return; 370 case MachineOperand::MO_ConstantPoolIndex: 371 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 372 << '_' << MO.getIndex(); 373 return; 374 case MachineOperand::MO_ExternalSymbol: 375 // Computing the address of an external symbol, not calling it. 376 if (TM.getRelocationModel() != Reloc::Static) { 377 std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); 378 GVStubs.insert(Name); 379 O << "L" << Name << "$non_lazy_ptr"; 380 return; 381 } 382 O << TAI->getGlobalPrefix() << MO.getSymbolName(); 383 return; 384 case MachineOperand::MO_GlobalAddress: { 385 // Computing the address of a global symbol, not calling it. 386 GlobalValue *GV = MO.getGlobal(); 387 std::string Name = Mang->getValueName(GV); 388 389 // External or weakly linked global variables need non-lazily-resolved stubs 390 if (TM.getRelocationModel() != Reloc::Static) { 391 if (((GV->isDeclaration() || GV->hasWeakLinkage() || 392 GV->hasLinkOnceLinkage()))) { 393 GVStubs.insert(Name); 394 O << "L" << Name << "$non_lazy_ptr"; 395 return; 396 } 397 } 398 O << Name; 399 400 if (MO.getOffset() > 0) 401 O << "+" << MO.getOffset(); 402 else if (MO.getOffset() < 0) 403 O << MO.getOffset(); 404 405 if (GV->hasExternalWeakLinkage()) 406 ExtWeakSymbols.insert(GV); 407 return; 408 } 409 410 default: 411 O << "<unknown operand type: " << MO.getType() << ">"; 412 return; 413 } 414} 415 416/// EmitExternalGlobal - In this case we need to use the indirect symbol. 417/// 418void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) { 419 std::string Name = getGlobalLinkName(GV); 420 if (TM.getRelocationModel() != Reloc::Static) { 421 GVStubs.insert(Name); 422 O << "L" << Name << "$non_lazy_ptr"; 423 return; 424 } 425 O << Name; 426} 427 428/// PrintAsmOperand - Print out an operand for an inline asm expression. 429/// 430bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 431 unsigned AsmVariant, 432 const char *ExtraCode) { 433 // Does this asm operand have a single letter operand modifier? 434 if (ExtraCode && ExtraCode[0]) { 435 if (ExtraCode[1] != 0) return true; // Unknown modifier. 436 437 switch (ExtraCode[0]) { 438 default: return true; // Unknown modifier. 439 case 'c': // Don't print "$" before a global var name or constant. 440 // PPC never has a prefix. 441 printOperand(MI, OpNo); 442 return false; 443 case 'L': // Write second word of DImode reference. 444 // Verify that this operand has two consecutive registers. 445 if (!MI->getOperand(OpNo).isRegister() || 446 OpNo+1 == MI->getNumOperands() || 447 !MI->getOperand(OpNo+1).isRegister()) 448 return true; 449 ++OpNo; // Return the high-part. 450 break; 451 case 'I': 452 // Write 'i' if an integer constant, otherwise nothing. Used to print 453 // addi vs add, etc. 454 if (MI->getOperand(OpNo).isImmediate()) 455 O << "i"; 456 return false; 457 } 458 } 459 460 printOperand(MI, OpNo); 461 return false; 462} 463 464bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 465 unsigned AsmVariant, 466 const char *ExtraCode) { 467 if (ExtraCode && ExtraCode[0]) 468 return true; // Unknown modifier. 469 if (MI->getOperand(OpNo).isRegister()) 470 printMemRegReg(MI, OpNo); 471 else 472 printMemRegImm(MI, OpNo); 473 return false; 474} 475 476void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 477 const char *Modifier) { 478 assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!"); 479 unsigned Code = MI->getOperand(OpNo).getImm(); 480 if (!strcmp(Modifier, "cc")) { 481 switch ((PPC::Predicate)Code) { 482 case PPC::PRED_ALWAYS: return; // Don't print anything for always. 483 case PPC::PRED_LT: O << "lt"; return; 484 case PPC::PRED_LE: O << "le"; return; 485 case PPC::PRED_EQ: O << "eq"; return; 486 case PPC::PRED_GE: O << "ge"; return; 487 case PPC::PRED_GT: O << "gt"; return; 488 case PPC::PRED_NE: O << "ne"; return; 489 case PPC::PRED_UN: O << "un"; return; 490 case PPC::PRED_NU: O << "nu"; return; 491 } 492 493 } else { 494 assert(!strcmp(Modifier, "reg") && 495 "Need to specify 'cc' or 'reg' as predicate op modifier!"); 496 // Don't print the register for 'always'. 497 if (Code == PPC::PRED_ALWAYS) return; 498 printOperand(MI, OpNo+1); 499 } 500} 501 502 503/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to 504/// the current output stream. 505/// 506void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 507 ++EmittedInsts; 508 509 // Check for slwi/srwi mnemonics. 510 if (MI->getOpcode() == PPC::RLWINM) { 511 bool FoundMnemonic = false; 512 unsigned char SH = MI->getOperand(2).getImm(); 513 unsigned char MB = MI->getOperand(3).getImm(); 514 unsigned char ME = MI->getOperand(4).getImm(); 515 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 516 O << "slwi "; FoundMnemonic = true; 517 } 518 if (SH <= 31 && MB == (32-SH) && ME == 31) { 519 O << "srwi "; FoundMnemonic = true; 520 SH = 32-SH; 521 } 522 if (FoundMnemonic) { 523 printOperand(MI, 0); 524 O << ", "; 525 printOperand(MI, 1); 526 O << ", " << (unsigned int)SH << "\n"; 527 return; 528 } 529 } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) { 530 if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 531 O << "mr "; 532 printOperand(MI, 0); 533 O << ", "; 534 printOperand(MI, 1); 535 O << "\n"; 536 return; 537 } 538 } else if (MI->getOpcode() == PPC::RLDICR) { 539 unsigned char SH = MI->getOperand(2).getImm(); 540 unsigned char ME = MI->getOperand(3).getImm(); 541 // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 542 if (63-SH == ME) { 543 O << "sldi "; 544 printOperand(MI, 0); 545 O << ", "; 546 printOperand(MI, 1); 547 O << ", " << (unsigned int)SH << "\n"; 548 return; 549 } 550 } 551 552 if (printInstruction(MI)) 553 return; // Printer was automatically generated 554 555 assert(0 && "Unhandled instruction in asm writer!"); 556 abort(); 557 return; 558} 559 560/// runOnMachineFunction - This uses the printMachineInstruction() 561/// method to print assembly for each instruction. 562/// 563bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 564 DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>()); 565 566 SetupMachineFunction(MF); 567 O << "\n\n"; 568 569 // Print out constants referenced by the function 570 EmitConstantPool(MF.getConstantPool()); 571 572 // Print out labels for the function. 573 const Function *F = MF.getFunction(); 574 SwitchToTextSection(getSectionForFunction(*F).c_str(), F); 575 576 switch (F->getLinkage()) { 577 default: assert(0 && "Unknown linkage type!"); 578 case Function::InternalLinkage: // Symbols default to internal. 579 break; 580 case Function::ExternalLinkage: 581 O << "\t.global\t" << CurrentFnName << '\n' 582 << "\t.type\t" << CurrentFnName << ", @function\n"; 583 break; 584 case Function::WeakLinkage: 585 case Function::LinkOnceLinkage: 586 O << "\t.global\t" << CurrentFnName << '\n'; 587 O << "\t.weak\t" << CurrentFnName << '\n'; 588 break; 589 } 590 591 if (F->hasHiddenVisibility()) 592 if (const char *Directive = TAI->getHiddenDirective()) 593 O << Directive << CurrentFnName << "\n"; 594 595 EmitAlignment(2, F); 596 O << CurrentFnName << ":\n"; 597 598 // Emit pre-function debug information. 599 DW.BeginFunction(&MF); 600 601 // Print out code for the function. 602 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 603 I != E; ++I) { 604 // Print a label for the basic block. 605 if (I != MF.begin()) { 606 printBasicBlockLabel(I, true); 607 O << '\n'; 608 } 609 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 610 II != E; ++II) { 611 // Print the assembly for the instruction. 612 O << "\t"; 613 printMachineInstruction(II); 614 } 615 } 616 617 O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n"; 618 619 // Print out jump tables referenced by the function. 620 EmitJumpTableInfo(MF.getJumpTableInfo(), MF); 621 622 // Emit post-function debug information. 623 DW.EndFunction(); 624 625 // We didn't modify anything. 626 return false; 627} 628 629bool LinuxAsmPrinter::doInitialization(Module &M) { 630 bool Result = AsmPrinter::doInitialization(M); 631 632 // GNU as handles section names wrapped in quotes 633 Mang->setUseQuotes(true); 634 635 SwitchToTextSection(TAI->getTextSection()); 636 637 // Emit initial debug information. 638 DW.BeginModule(&M); 639 return Result; 640} 641 642bool LinuxAsmPrinter::doFinalization(Module &M) { 643 const TargetData *TD = TM.getTargetData(); 644 645 // Print out module-level global variables here. 646 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 647 I != E; ++I) { 648 if (!I->hasInitializer()) continue; // External global require no code 649 650 // Check to see if this is a special global used by LLVM, if so, emit it. 651 if (EmitSpecialLLVMGlobal(I)) 652 continue; 653 654 std::string name = Mang->getValueName(I); 655 656 if (I->hasHiddenVisibility()) 657 if (const char *Directive = TAI->getHiddenDirective()) 658 O << Directive << name << "\n"; 659 660 Constant *C = I->getInitializer(); 661 unsigned Size = TD->getABITypeSize(C->getType()); 662 unsigned Align = TD->getPreferredAlignmentLog(I); 663 664 if (C->isNullValue() && /* FIXME: Verify correct */ 665 !I->hasSection() && 666 (I->hasInternalLinkage() || I->hasWeakLinkage() || 667 I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { 668 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 669 if (I->hasExternalLinkage()) { 670 O << "\t.global " << name << '\n'; 671 O << "\t.type " << name << ", @object\n"; 672 if (TAI->getBSSSection()) 673 SwitchToDataSection(TAI->getBSSSection(), I); 674 O << name << ":\n"; 675 O << "\t.zero " << Size << "\n"; 676 } else if (I->hasInternalLinkage()) { 677 SwitchToDataSection("\t.data", I); 678 O << TAI->getLCOMMDirective() << name << "," << Size; 679 } else { 680 SwitchToDataSection("\t.data", I); 681 O << ".comm " << name << "," << Size; 682 } 683 O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n"; 684 } else { 685 switch (I->getLinkage()) { 686 case GlobalValue::LinkOnceLinkage: 687 case GlobalValue::WeakLinkage: 688 O << "\t.global " << name << '\n' 689 << "\t.type " << name << ", @object\n" 690 << "\t.weak " << name << '\n'; 691 SwitchToDataSection("\t.data", I); 692 break; 693 case GlobalValue::AppendingLinkage: 694 // FIXME: appending linkage variables should go into a section of 695 // their name or something. For now, just emit them as external. 696 case GlobalValue::ExternalLinkage: 697 // If external or appending, declare as a global symbol 698 O << "\t.global " << name << "\n" 699 << "\t.type " << name << ", @object\n"; 700 // FALL THROUGH 701 case GlobalValue::InternalLinkage: 702 if (I->isConstant()) { 703 const ConstantArray *CVA = dyn_cast<ConstantArray>(C); 704 if (TAI->getCStringSection() && CVA && CVA->isCString()) { 705 SwitchToDataSection(TAI->getCStringSection(), I); 706 break; 707 } 708 } 709 710 // FIXME: special handling for ".ctors" & ".dtors" sections 711 if (I->hasSection() && 712 (I->getSection() == ".ctors" || 713 I->getSection() == ".dtors")) { 714 std::string SectionName = ".section " + I->getSection() 715 + ",\"aw\",@progbits"; 716 SwitchToDataSection(SectionName.c_str()); 717 } else { 718 if (I->isConstant() && TAI->getReadOnlySection()) 719 SwitchToDataSection(TAI->getReadOnlySection(), I); 720 else 721 SwitchToDataSection(TAI->getDataSection(), I); 722 } 723 break; 724 default: 725 cerr << "Unknown linkage type!"; 726 abort(); 727 } 728 729 EmitAlignment(Align, I); 730 O << name << ":\t\t\t\t" << TAI->getCommentString() << " '" 731 << I->getName() << "'\n"; 732 733 // If the initializer is a extern weak symbol, remember to emit the weak 734 // reference! 735 if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 736 if (GV->hasExternalWeakLinkage()) 737 ExtWeakSymbols.insert(GV); 738 739 EmitGlobalConstant(C); 740 O << '\n'; 741 } 742 } 743 744 // TODO 745 746 // Emit initial debug information. 747 DW.EndModule(); 748 749 return AsmPrinter::doFinalization(M); 750} 751 752std::string LinuxAsmPrinter::getSectionForFunction(const Function &F) const { 753 switch (F.getLinkage()) { 754 default: assert(0 && "Unknown linkage type!"); 755 case Function::ExternalLinkage: 756 case Function::InternalLinkage: return TAI->getTextSection(); 757 case Function::WeakLinkage: 758 case Function::LinkOnceLinkage: 759 return ".text"; 760 } 761} 762 763std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const { 764 switch (F.getLinkage()) { 765 default: assert(0 && "Unknown linkage type!"); 766 case Function::ExternalLinkage: 767 case Function::InternalLinkage: return TAI->getTextSection(); 768 case Function::WeakLinkage: 769 case Function::LinkOnceLinkage: 770 return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions"; 771 } 772} 773 774/// runOnMachineFunction - This uses the printMachineInstruction() 775/// method to print assembly for each instruction. 776/// 777bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 778 // We need this for Personality functions. 779 MMI = &getAnalysis<MachineModuleInfo>(); 780 DW.SetModuleInfo(MMI); 781 782 SetupMachineFunction(MF); 783 O << "\n\n"; 784 785 // Print out constants referenced by the function 786 EmitConstantPool(MF.getConstantPool()); 787 788 // Print out labels for the function. 789 const Function *F = MF.getFunction(); 790 SwitchToTextSection(getSectionForFunction(*F).c_str(), F); 791 792 switch (F->getLinkage()) { 793 default: assert(0 && "Unknown linkage type!"); 794 case Function::InternalLinkage: // Symbols default to internal. 795 break; 796 case Function::ExternalLinkage: 797 O << "\t.globl\t" << CurrentFnName << "\n"; 798 break; 799 case Function::WeakLinkage: 800 case Function::LinkOnceLinkage: 801 O << "\t.globl\t" << CurrentFnName << "\n"; 802 O << "\t.weak_definition\t" << CurrentFnName << "\n"; 803 break; 804 } 805 806 if (F->hasHiddenVisibility()) 807 if (const char *Directive = TAI->getHiddenDirective()) 808 O << Directive << CurrentFnName << "\n"; 809 810 EmitAlignment(4, F); 811 O << CurrentFnName << ":\n"; 812 813 // Emit pre-function debug information. 814 DW.BeginFunction(&MF); 815 816 // Print out code for the function. 817 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 818 I != E; ++I) { 819 // Print a label for the basic block. 820 if (I != MF.begin()) { 821 printBasicBlockLabel(I, true); 822 O << '\n'; 823 } 824 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 825 II != E; ++II) { 826 // Print the assembly for the instruction. 827 O << "\t"; 828 printMachineInstruction(II); 829 } 830 } 831 832 // Print out jump tables referenced by the function. 833 EmitJumpTableInfo(MF.getJumpTableInfo(), MF); 834 835 // Emit post-function debug information. 836 DW.EndFunction(); 837 838 // We didn't modify anything. 839 return false; 840} 841 842 843bool DarwinAsmPrinter::doInitialization(Module &M) { 844 static const char *CPUDirectives[] = { 845 "ppc", 846 "ppc601", 847 "ppc602", 848 "ppc603", 849 "ppc7400", 850 "ppc750", 851 "ppc970", 852 "ppc64" 853 }; 854 855 unsigned Directive = Subtarget.getDarwinDirective(); 856 if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970) 857 Directive = PPC::DIR_970; 858 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 859 Directive = PPC::DIR_7400; 860 if (Subtarget.isPPC64() && Directive < PPC::DIR_970) 861 Directive = PPC::DIR_64; 862 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 863 O << "\t.machine " << CPUDirectives[Directive] << "\n"; 864 865 bool Result = AsmPrinter::doInitialization(M); 866 867 // Darwin wants symbols to be quoted if they have complex names. 868 Mang->setUseQuotes(true); 869 870 // Prime text sections so they are adjacent. This reduces the likelihood a 871 // large data or debug section causes a branch to exceed 16M limit. 872 SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced," 873 "pure_instructions"); 874 if (TM.getRelocationModel() == Reloc::PIC_) { 875 SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," 876 "pure_instructions,32"); 877 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 878 SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," 879 "pure_instructions,16"); 880 } 881 SwitchToTextSection(TAI->getTextSection()); 882 883 // Emit initial debug information. 884 DW.BeginModule(&M); 885 return Result; 886} 887 888bool DarwinAsmPrinter::doFinalization(Module &M) { 889 const TargetData *TD = TM.getTargetData(); 890 891 // Print out module-level global variables here. 892 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 893 I != E; ++I) { 894 if (!I->hasInitializer()) continue; // External global require no code 895 896 // Check to see if this is a special global used by LLVM, if so, emit it. 897 if (EmitSpecialLLVMGlobal(I)) { 898 if (TM.getRelocationModel() == Reloc::Static) { 899 if (I->getName() == "llvm.global_ctors") 900 O << ".reference .constructors_used\n"; 901 else if (I->getName() == "llvm.global_dtors") 902 O << ".reference .destructors_used\n"; 903 } 904 continue; 905 } 906 907 std::string name = Mang->getValueName(I); 908 909 if (I->hasHiddenVisibility()) 910 if (const char *Directive = TAI->getHiddenDirective()) 911 O << Directive << name << "\n"; 912 913 Constant *C = I->getInitializer(); 914 const Type *Type = C->getType(); 915 unsigned Size = TD->getABITypeSize(Type); 916 unsigned Align = TD->getPreferredAlignmentLog(I); 917 918 if (C->isNullValue() && /* FIXME: Verify correct */ 919 !I->hasSection() && 920 (I->hasInternalLinkage() || I->hasWeakLinkage() || 921 I->hasLinkOnceLinkage() || I->hasExternalLinkage())) { 922 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 923 if (I->hasExternalLinkage()) { 924 O << "\t.globl " << name << '\n'; 925 O << "\t.zerofill __DATA, __common, " << name << ", " 926 << Size << ", " << Align; 927 } else if (I->hasInternalLinkage()) { 928 SwitchToDataSection("\t.data", I); 929 O << TAI->getLCOMMDirective() << name << "," << Size << "," << Align; 930 } else { 931 SwitchToDataSection("\t.data", I); 932 O << ".comm " << name << "," << Size; 933 // Darwin 9 and above support aligned common data. 934 if (Subtarget.isDarwin9()) 935 O << "," << Align; 936 } 937 O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n"; 938 } else { 939 switch (I->getLinkage()) { 940 case GlobalValue::LinkOnceLinkage: 941 case GlobalValue::WeakLinkage: 942 O << "\t.globl " << name << '\n' 943 << "\t.weak_definition " << name << '\n'; 944 SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); 945 break; 946 case GlobalValue::AppendingLinkage: 947 // FIXME: appending linkage variables should go into a section of 948 // their name or something. For now, just emit them as external. 949 case GlobalValue::ExternalLinkage: 950 // If external or appending, declare as a global symbol 951 O << "\t.globl " << name << "\n"; 952 // FALL THROUGH 953 case GlobalValue::InternalLinkage: 954 if (I->isConstant()) { 955 const ConstantArray *CVA = dyn_cast<ConstantArray>(C); 956 if (TAI->getCStringSection() && CVA && CVA->isCString()) { 957 SwitchToDataSection(TAI->getCStringSection(), I); 958 break; 959 } 960 } 961 962 if (!I->isConstant()) 963 SwitchToDataSection(TAI->getDataSection(), I); 964 else { 965 // Read-only data. 966 bool HasReloc = C->ContainsRelocations(); 967 if (HasReloc && 968 TM.getRelocationModel() != Reloc::Static) 969 SwitchToDataSection("\t.const_data\n"); 970 else if (!HasReloc && Size == 4 && 971 TAI->getFourByteConstantSection()) 972 SwitchToDataSection(TAI->getFourByteConstantSection(), I); 973 else if (!HasReloc && Size == 8 && 974 TAI->getEightByteConstantSection()) 975 SwitchToDataSection(TAI->getEightByteConstantSection(), I); 976 else if (!HasReloc && Size == 16 && 977 TAI->getSixteenByteConstantSection()) 978 SwitchToDataSection(TAI->getSixteenByteConstantSection(), I); 979 else if (TAI->getReadOnlySection()) 980 SwitchToDataSection(TAI->getReadOnlySection(), I); 981 else 982 SwitchToDataSection(TAI->getDataSection(), I); 983 } 984 break; 985 default: 986 cerr << "Unknown linkage type!"; 987 abort(); 988 } 989 990 EmitAlignment(Align, I); 991 O << name << ":\t\t\t\t" << TAI->getCommentString() << " '" 992 << I->getName() << "'\n"; 993 994 // If the initializer is a extern weak symbol, remember to emit the weak 995 // reference! 996 if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 997 if (GV->hasExternalWeakLinkage()) 998 ExtWeakSymbols.insert(GV); 999 1000 EmitGlobalConstant(C); 1001 O << '\n'; 1002 } 1003 } 1004 1005 bool isPPC64 = TD->getPointerSizeInBits() == 64; 1006 1007 // Output stubs for dynamically-linked functions 1008 if (TM.getRelocationModel() == Reloc::PIC_) { 1009 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 1010 i != e; ++i) { 1011 SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," 1012 "pure_instructions,32"); 1013 EmitAlignment(4); 1014 O << "L" << *i << "$stub:\n"; 1015 O << "\t.indirect_symbol " << *i << "\n"; 1016 O << "\tmflr r0\n"; 1017 O << "\tbcl 20,31,L0$" << *i << "\n"; 1018 O << "L0$" << *i << ":\n"; 1019 O << "\tmflr r11\n"; 1020 O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n"; 1021 O << "\tmtlr r0\n"; 1022 if (isPPC64) 1023 O << "\tldu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 1024 else 1025 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 1026 O << "\tmtctr r12\n"; 1027 O << "\tbctr\n"; 1028 SwitchToDataSection(".lazy_symbol_pointer"); 1029 O << "L" << *i << "$lazy_ptr:\n"; 1030 O << "\t.indirect_symbol " << *i << "\n"; 1031 if (isPPC64) 1032 O << "\t.quad dyld_stub_binding_helper\n"; 1033 else 1034 O << "\t.long dyld_stub_binding_helper\n"; 1035 } 1036 } else { 1037 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 1038 i != e; ++i) { 1039 SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," 1040 "pure_instructions,16"); 1041 EmitAlignment(4); 1042 O << "L" << *i << "$stub:\n"; 1043 O << "\t.indirect_symbol " << *i << "\n"; 1044 O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n"; 1045 if (isPPC64) 1046 O << "\tldu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; 1047 else 1048 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; 1049 O << "\tmtctr r12\n"; 1050 O << "\tbctr\n"; 1051 SwitchToDataSection(".lazy_symbol_pointer"); 1052 O << "L" << *i << "$lazy_ptr:\n"; 1053 O << "\t.indirect_symbol " << *i << "\n"; 1054 if (isPPC64) 1055 O << "\t.quad dyld_stub_binding_helper\n"; 1056 else 1057 O << "\t.long dyld_stub_binding_helper\n"; 1058 } 1059 } 1060 1061 O << "\n"; 1062 1063 if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI) { 1064 // Add the (possibly multiple) personalities to the set of global values. 1065 const std::vector<Function *>& Personalities = MMI->getPersonalities(); 1066 1067 for (std::vector<Function *>::const_iterator I = Personalities.begin(), 1068 E = Personalities.end(); I != E; ++I) 1069 if (*I) GVStubs.insert("_" + (*I)->getName()); 1070 } 1071 1072 // Output stubs for external and common global variables. 1073 if (!GVStubs.empty()) { 1074 SwitchToDataSection(".non_lazy_symbol_pointer"); 1075 for (std::set<std::string>::iterator I = GVStubs.begin(), 1076 E = GVStubs.end(); I != E; ++I) { 1077 O << "L" << *I << "$non_lazy_ptr:\n"; 1078 O << "\t.indirect_symbol " << *I << "\n"; 1079 if (isPPC64) 1080 O << "\t.quad\t0\n"; 1081 else 1082 O << "\t.long\t0\n"; 1083 1084 } 1085 } 1086 1087 // Emit initial debug information. 1088 DW.EndModule(); 1089 1090 // Funny Darwin hack: This flag tells the linker that no global symbols 1091 // contain code that falls through to other global symbols (e.g. the obvious 1092 // implementation of multiple entry points). If this doesn't occur, the 1093 // linker can safely perform dead code stripping. Since LLVM never generates 1094 // code that does this, it is always safe to set. 1095 O << "\t.subsections_via_symbols\n"; 1096 1097 return AsmPrinter::doFinalization(M); 1098} 1099 1100 1101 1102/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1103/// for a MachineFunction to the given output stream, in a format that the 1104/// Darwin assembler can deal with. 1105/// 1106FunctionPass *llvm::createPPCAsmPrinterPass(std::ostream &o, 1107 PPCTargetMachine &tm) { 1108 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 1109 1110 if (Subtarget->isDarwin()) { 1111 return new DarwinAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1112 } else { 1113 return new LinuxAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1114 } 1115} 1116 1117