SparcAsmPrinter.cpp revision b8df7c22131368abd3e7d6e0e4b0fc6ee74f8427
1//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===// 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//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to GAS-format Sparc V8 assembly language. 12// 13//===----------------------------------------------------------------------===// 14 15#include "SparcV8.h" 16#include "SparcV8InstrInfo.h" 17#include "llvm/Constants.h" 18#include "llvm/DerivedTypes.h" 19#include "llvm/Module.h" 20#include "llvm/Assembly/Writer.h" 21#include "llvm/CodeGen/MachineFunctionPass.h" 22#include "llvm/CodeGen/MachineConstantPool.h" 23#include "llvm/CodeGen/MachineInstr.h" 24#include "llvm/Target/TargetMachine.h" 25#include "llvm/Support/Mangler.h" 26#include "llvm/ADT/Statistic.h" 27#include "llvm/ADT/StringExtras.h" 28#include "llvm/Support/CommandLine.h" 29#include "llvm/Support/MathExtras.h" 30#include <cctype> 31using namespace llvm; 32 33namespace { 34 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 35 36 struct V8Printer : public MachineFunctionPass { 37 /// Output stream on which we're printing assembly code. 38 /// 39 std::ostream &O; 40 41 /// Target machine description which we query for reg. names, data 42 /// layout, etc. 43 /// 44 TargetMachine &TM; 45 46 /// Name-mangler for global names. 47 /// 48 Mangler *Mang; 49 50 V8Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { } 51 52 /// We name each basic block in a Function with a unique number, so 53 /// that we can consistently refer to them later. This is cleared 54 /// at the beginning of each call to runOnMachineFunction(). 55 /// 56 typedef std::map<const Value *, unsigned> ValueMapTy; 57 ValueMapTy NumberForBB; 58 59 /// Cache of mangled name for current function. This is 60 /// recalculated at the beginning of each call to 61 /// runOnMachineFunction(). 62 /// 63 std::string CurrentFnName; 64 65 virtual const char *getPassName() const { 66 return "SparcV8 Assembly Printer"; 67 } 68 69 void emitConstantValueOnly(const Constant *CV); 70 void emitGlobalConstant(const Constant *CV); 71 void printConstantPool(MachineConstantPool *MCP); 72 void printOperand(const MachineInstr *MI, int opNum); 73 void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true); 74 void printMachineInstruction(const MachineInstr *MI); 75 bool runOnMachineFunction(MachineFunction &F); 76 bool doInitialization(Module &M); 77 bool doFinalization(Module &M); 78 }; 79} // end of anonymous namespace 80 81/// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8 82/// assembly code for a MachineFunction to the given output stream, 83/// using the given target machine description. This should work 84/// regardless of whether the function is in SSA form. 85/// 86FunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o, 87 TargetMachine &tm) { 88 return new V8Printer(o, tm); 89} 90 91/// toOctal - Convert the low order bits of X into an octal digit. 92/// 93static inline char toOctal(int X) { 94 return (X&7)+'0'; 95} 96 97/// getAsCString - Return the specified array as a C compatible 98/// string, only if the predicate isStringCompatible is true. 99/// 100static void printAsCString(std::ostream &O, const ConstantArray *CVA) { 101 assert(CVA->isString() && "Array is not string compatible!"); 102 103 O << "\""; 104 for (unsigned i = 0; i != CVA->getNumOperands(); ++i) { 105 unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue(); 106 107 if (C == '"') { 108 O << "\\\""; 109 } else if (C == '\\') { 110 O << "\\\\"; 111 } else if (isprint(C)) { 112 O << C; 113 } else { 114 switch(C) { 115 case '\b': O << "\\b"; break; 116 case '\f': O << "\\f"; break; 117 case '\n': O << "\\n"; break; 118 case '\r': O << "\\r"; break; 119 case '\t': O << "\\t"; break; 120 default: 121 O << '\\'; 122 O << toOctal(C >> 6); 123 O << toOctal(C >> 3); 124 O << toOctal(C >> 0); 125 break; 126 } 127 } 128 } 129 O << "\""; 130} 131 132// Print out the specified constant, without a storage class. Only the 133// constants valid in constant expressions can occur here. 134void V8Printer::emitConstantValueOnly(const Constant *CV) { 135 if (CV->isNullValue() || isa<UndefValue> (CV)) 136 O << "0"; 137 else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) { 138 assert(CB == ConstantBool::True); 139 O << "1"; 140 } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) 141 if (((CI->getValue() << 32) >> 32) == CI->getValue()) 142 O << CI->getValue(); 143 else 144 O << (unsigned long long)CI->getValue(); 145 else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) 146 O << CI->getValue(); 147 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) 148 // This is a constant address for a global variable or function. Use the 149 // name of the variable or function as the address value. 150 O << Mang->getValueName(GV); 151 else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { 152 const TargetData &TD = TM.getTargetData(); 153 switch(CE->getOpcode()) { 154 case Instruction::GetElementPtr: { 155 // generate a symbolic expression for the byte address 156 const Constant *ptrVal = CE->getOperand(0); 157 std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end()); 158 if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) { 159 O << "("; 160 emitConstantValueOnly(ptrVal); 161 O << ") + " << Offset; 162 } else { 163 emitConstantValueOnly(ptrVal); 164 } 165 break; 166 } 167 case Instruction::Cast: { 168 // Support only non-converting or widening casts for now, that is, ones 169 // that do not involve a change in value. This assertion is really gross, 170 // and may not even be a complete check. 171 Constant *Op = CE->getOperand(0); 172 const Type *OpTy = Op->getType(), *Ty = CE->getType(); 173 174 // Pointers on ILP32 machines can be losslessly converted back and 175 // forth into 32-bit or wider integers, regardless of signedness. 176 assert(((isa<PointerType>(OpTy) 177 && (Ty == Type::LongTy || Ty == Type::ULongTy 178 || Ty == Type::IntTy || Ty == Type::UIntTy)) 179 || (isa<PointerType>(Ty) 180 && (OpTy == Type::LongTy || OpTy == Type::ULongTy 181 || OpTy == Type::IntTy || OpTy == Type::UIntTy)) 182 || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) 183 && OpTy->isLosslesslyConvertibleTo(Ty)))) 184 && "FIXME: Don't yet support this kind of constant cast expr"); 185 O << "("; 186 emitConstantValueOnly(Op); 187 O << ")"; 188 break; 189 } 190 case Instruction::Add: 191 O << "("; 192 emitConstantValueOnly(CE->getOperand(0)); 193 O << ") + ("; 194 emitConstantValueOnly(CE->getOperand(1)); 195 O << ")"; 196 break; 197 default: 198 assert(0 && "Unsupported operator!"); 199 } 200 } else { 201 assert(0 && "Unknown constant value!"); 202 } 203} 204 205// Print a constant value or values, with the appropriate storage class as a 206// prefix. 207void V8Printer::emitGlobalConstant(const Constant *CV) { 208 const TargetData &TD = TM.getTargetData(); 209 210 if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { 211 if (CVA->isString()) { 212 O << "\t.ascii\t"; 213 printAsCString(O, CVA); 214 O << "\n"; 215 } else { // Not a string. Print the values in successive locations 216 for (unsigned i = 0, e = CVA->getNumOperands(); i != e; i++) 217 emitGlobalConstant(CVA->getOperand(i)); 218 } 219 return; 220 } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { 221 // Print the fields in successive locations. Pad to align if needed! 222 const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType()); 223 unsigned sizeSoFar = 0; 224 for (unsigned i = 0, e = CVS->getNumOperands(); i != e; i++) { 225 const Constant* field = CVS->getOperand(i); 226 227 // Check if padding is needed and insert one or more 0s. 228 unsigned fieldSize = TD.getTypeSize(field->getType()); 229 unsigned padSize = ((i == e-1? cvsLayout->StructSize 230 : cvsLayout->MemberOffsets[i+1]) 231 - cvsLayout->MemberOffsets[i]) - fieldSize; 232 sizeSoFar += fieldSize + padSize; 233 234 // Now print the actual field value 235 emitGlobalConstant(field); 236 237 // Insert the field padding unless it's zero bytes... 238 if (padSize) 239 O << "\t.skip\t " << padSize << "\n"; 240 } 241 assert(sizeSoFar == cvsLayout->StructSize && 242 "Layout of constant struct may be incorrect!"); 243 return; 244 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { 245 // FP Constants are printed as integer constants to avoid losing 246 // precision... 247 double Val = CFP->getValue(); 248 switch (CFP->getType()->getTypeID()) { 249 default: assert(0 && "Unknown floating point type!"); 250 case Type::FloatTyID: { 251 O << ".long\t" << FloatToBits(Val) << "\t! float " << Val << "\n"; 252 return; 253 } 254 case Type::DoubleTyID: { 255 O << ".word\t0x" << std::hex << (DoubleToBits(Val) >> 32) << std::dec << "\t! double " << Val << "\n"; 256 O << ".word\t0x" << std::hex << (DoubleToBits(Val) & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n"; 257 return; 258 } 259 } 260 } else if (isa<UndefValue> (CV)) { 261 unsigned size = TD.getTypeSize (CV->getType ()); 262 O << "\t.skip\t " << size << "\n"; 263 return; 264 } else if (isa<ConstantAggregateZero> (CV)) { 265 unsigned size = TD.getTypeSize (CV->getType ()); 266 for (unsigned i = 0; i < size; ++i) 267 O << "\t.byte 0\n"; 268 return; 269 } 270 271 const Type *type = CV->getType(); 272 O << "\t"; 273 switch (type->getTypeID()) { 274 case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID: 275 O << ".byte"; 276 break; 277 case Type::UShortTyID: case Type::ShortTyID: 278 O << ".half"; 279 break; 280 case Type::FloatTyID: case Type::PointerTyID: 281 case Type::UIntTyID: case Type::IntTyID: 282 O << ".word"; 283 break; 284 case Type::DoubleTyID: 285 case Type::ULongTyID: case Type::LongTyID: 286 O << ".xword"; 287 break; 288 default: 289 assert (0 && "Can't handle printing this type of thing"); 290 break; 291 } 292 O << "\t"; 293 emitConstantValueOnly(CV); 294 O << "\n"; 295} 296 297/// printConstantPool - Print to the current output stream assembly 298/// representations of the constants in the constant pool MCP. This is 299/// used to print out constants which have been "spilled to memory" by 300/// the code generator. 301/// 302void V8Printer::printConstantPool(MachineConstantPool *MCP) { 303 const std::vector<Constant*> &CP = MCP->getConstants(); 304 const TargetData &TD = TM.getTargetData(); 305 306 if (CP.empty()) return; 307 308 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 309 O << "\t.section \".rodata\"\n"; 310 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) 311 << "\n"; 312 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t!" 313 << *CP[i] << "\n"; 314 emitGlobalConstant(CP[i]); 315 } 316} 317 318/// runOnMachineFunction - This uses the printMachineInstruction() 319/// method to print assembly for each instruction. 320/// 321bool V8Printer::runOnMachineFunction(MachineFunction &MF) { 322 // BBNumber is used here so that a given Printer will never give two 323 // BBs the same name. (If you have a better way, please let me know!) 324 static unsigned BBNumber = 0; 325 326 O << "\n\n"; 327 // What's my mangled name? 328 CurrentFnName = Mang->getValueName(MF.getFunction()); 329 330 // Print out constants referenced by the function 331 printConstantPool(MF.getConstantPool()); 332 333 // Print out labels for the function. 334 O << "\t.text\n"; 335 O << "\t.align 16\n"; 336 O << "\t.globl\t" << CurrentFnName << "\n"; 337 O << "\t.type\t" << CurrentFnName << ", #function\n"; 338 O << CurrentFnName << ":\n"; 339 340 // Number each basic block so that we can consistently refer to them 341 // in PC-relative references. 342 NumberForBB.clear(); 343 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 344 I != E; ++I) { 345 NumberForBB[I->getBasicBlock()] = BBNumber++; 346 } 347 348 // Print out code for the function. 349 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 350 I != E; ++I) { 351 // Print a label for the basic block. 352 O << ".LBB" << Mang->getValueName(MF.getFunction ()) 353 << "_" << I->getNumber () << ":\t! " 354 << I->getBasicBlock ()->getName () << "\n"; 355 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 356 II != E; ++II) { 357 // Print the assembly for the instruction. 358 O << "\t"; 359 printMachineInstruction(II); 360 } 361 } 362 363 // We didn't modify anything. 364 return false; 365} 366 367void V8Printer::printOperand(const MachineInstr *MI, int opNum) { 368 const MachineOperand &MO = MI->getOperand (opNum); 369 const MRegisterInfo &RI = *TM.getRegisterInfo(); 370 bool CloseParen = false; 371 if (MI->getOpcode() == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) { 372 O << "%hi("; 373 CloseParen = true; 374 } else if (MI->getOpcode() ==V8::ORri &&!MO.isRegister() &&!MO.isImmediate()) 375 { 376 O << "%lo("; 377 CloseParen = true; 378 } 379 switch (MO.getType()) { 380 case MachineOperand::MO_VirtualRegister: 381 if (Value *V = MO.getVRegValueOrNull()) { 382 O << "<" << V->getName() << ">"; 383 break; 384 } 385 // FALLTHROUGH 386 case MachineOperand::MO_MachineRegister: 387 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 388 O << "%" << LowercaseString (RI.get(MO.getReg()).Name); 389 else 390 O << "%reg" << MO.getReg(); 391 break; 392 393 case MachineOperand::MO_SignExtendedImmed: 394 case MachineOperand::MO_UnextendedImmed: 395 O << (int)MO.getImmedValue(); 396 break; 397 case MachineOperand::MO_MachineBasicBlock: { 398 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 399 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 400 << "_" << MBBOp->getNumber () << "\t! " 401 << MBBOp->getBasicBlock ()->getName (); 402 return; 403 } 404 case MachineOperand::MO_PCRelativeDisp: 405 std::cerr << "Shouldn't use addPCDisp() when building SparcV8 MachineInstrs"; 406 abort (); 407 return; 408 case MachineOperand::MO_GlobalAddress: 409 O << Mang->getValueName(MO.getGlobal()); 410 break; 411 case MachineOperand::MO_ExternalSymbol: 412 O << MO.getSymbolName(); 413 break; 414 case MachineOperand::MO_ConstantPoolIndex: 415 O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); 416 break; 417 default: 418 O << "<unknown operand type>"; abort (); break; 419 } 420 if (CloseParen) O << ")"; 421} 422 423static bool isLoadInstruction (const MachineInstr *MI) { 424 switch (MI->getOpcode ()) { 425 case V8::LDSB: 426 case V8::LDSH: 427 case V8::LDUB: 428 case V8::LDUH: 429 case V8::LD: 430 case V8::LDD: 431 case V8::LDFrr: 432 case V8::LDFri: 433 case V8::LDDFrr: 434 case V8::LDDFri: 435 return true; 436 default: 437 return false; 438 } 439} 440 441static bool isStoreInstruction (const MachineInstr *MI) { 442 switch (MI->getOpcode ()) { 443 case V8::STB: 444 case V8::STH: 445 case V8::ST: 446 case V8::STD: 447 case V8::STFrr: 448 case V8::STFri: 449 case V8::STDFrr: 450 case V8::STDFri: 451 return true; 452 default: 453 return false; 454 } 455} 456 457static bool isPseudoInstruction (const MachineInstr *MI) { 458 switch (MI->getOpcode ()) { 459 case V8::PHI: 460 case V8::ADJCALLSTACKUP: 461 case V8::ADJCALLSTACKDOWN: 462 case V8::IMPLICIT_USE: 463 case V8::IMPLICIT_DEF: 464 return true; 465 default: 466 return false; 467 } 468} 469 470/// printBaseOffsetPair - Print two consecutive operands of MI, starting at #i, 471/// which form a base + offset pair (which may have brackets around it, if 472/// brackets is true, or may be in the form base - constant, if offset is a 473/// negative constant). 474/// 475void V8Printer::printBaseOffsetPair (const MachineInstr *MI, int i, 476 bool brackets) { 477 if (brackets) O << "["; 478 printOperand (MI, i); 479 if (MI->getOperand (i + 1).isImmediate()) { 480 int Val = (int) MI->getOperand (i + 1).getImmedValue (); 481 if (Val != 0) { 482 O << ((Val >= 0) ? " + " : " - "); 483 O << ((Val >= 0) ? Val : -Val); 484 } 485 } else { 486 O << " + "; 487 printOperand (MI, i + 1); 488 } 489 if (brackets) O << "]"; 490} 491 492/// printMachineInstruction -- Print out a single SparcV8 LLVM instruction 493/// MI in GAS syntax to the current output stream. 494/// 495void V8Printer::printMachineInstruction(const MachineInstr *MI) { 496 unsigned Opcode = MI->getOpcode(); 497 const TargetInstrInfo &TII = *TM.getInstrInfo(); 498 const TargetInstrDescriptor &Desc = TII.get(Opcode); 499 500 // If it's a pseudo-instruction, comment it out. 501 if (isPseudoInstruction (MI)) 502 O << "! "; 503 504 O << Desc.Name << " "; 505 506 // Printing memory instructions is a special case. 507 // for loads: %dest = op %base, offset --> op [%base + offset], %dest 508 // for stores: op %base, offset, %src --> op %src, [%base + offset] 509 if (isLoadInstruction (MI)) { 510 printBaseOffsetPair (MI, 1); 511 O << ", "; 512 printOperand (MI, 0); 513 O << "\n"; 514 return; 515 } else if (isStoreInstruction (MI)) { 516 printOperand (MI, 2); 517 O << ", "; 518 printBaseOffsetPair (MI, 0); 519 O << "\n"; 520 return; 521 } else if (Opcode == V8::JMPLrr) { 522 printBaseOffsetPair (MI, 1, false); 523 O << ", "; 524 printOperand (MI, 0); 525 O << "\n"; 526 return; 527 } 528 529 // print non-immediate, non-register-def operands 530 // then print immediate operands 531 // then print register-def operands. 532 std::vector<int> print_order; 533 for (unsigned i = 0; i < MI->getNumOperands (); ++i) 534 if (!(MI->getOperand (i).isImmediate () 535 || (MI->getOperand (i).isRegister () 536 && MI->getOperand (i).isDef ()))) 537 print_order.push_back (i); 538 for (unsigned i = 0; i < MI->getNumOperands (); ++i) 539 if (MI->getOperand (i).isImmediate ()) 540 print_order.push_back (i); 541 for (unsigned i = 0; i < MI->getNumOperands (); ++i) 542 if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ()) 543 print_order.push_back (i); 544 for (unsigned i = 0, e = print_order.size (); i != e; ++i) { 545 printOperand (MI, print_order[i]); 546 if (i != (print_order.size () - 1)) 547 O << ", "; 548 } 549 O << "\n"; 550} 551 552bool V8Printer::doInitialization(Module &M) { 553 Mang = new Mangler(M); 554 return false; // success 555} 556 557// SwitchSection - Switch to the specified section of the executable if we are 558// not already in it! 559// 560static void SwitchSection(std::ostream &OS, std::string &CurSection, 561 const char *NewSection) { 562 if (CurSection != NewSection) { 563 CurSection = NewSection; 564 if (!CurSection.empty()) 565 OS << "\t.section \"" << NewSection << "\"\n"; 566 } 567} 568 569bool V8Printer::doFinalization(Module &M) { 570 const TargetData &TD = TM.getTargetData(); 571 std::string CurSection; 572 573 // Print out module-level global variables here. 574 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) 575 if (I->hasInitializer()) { // External global require no code 576 O << "\n\n"; 577 std::string name = Mang->getValueName(I); 578 Constant *C = I->getInitializer(); 579 unsigned Size = TD.getTypeSize(C->getType()); 580 unsigned Align = TD.getTypeAlignment(C->getType()); 581 582 if (C->isNullValue() && 583 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 584 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 585 SwitchSection(O, CurSection, ".data"); 586 if (I->hasInternalLinkage()) 587 O << "\t.local " << name << "\n"; 588 589 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) 590 << "," << (unsigned)TD.getTypeAlignment(C->getType()); 591 O << "\t\t! "; 592 WriteAsOperand(O, I, true, true, &M); 593 O << "\n"; 594 } else { 595 switch (I->getLinkage()) { 596 case GlobalValue::LinkOnceLinkage: 597 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 598 // Nonnull linkonce -> weak 599 O << "\t.weak " << name << "\n"; 600 SwitchSection(O, CurSection, ""); 601 O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\",@progbits\n"; 602 break; 603 604 case GlobalValue::AppendingLinkage: 605 // FIXME: appending linkage variables should go into a section of 606 // their name or something. For now, just emit them as external. 607 case GlobalValue::ExternalLinkage: 608 // If external or appending, declare as a global symbol 609 O << "\t.globl " << name << "\n"; 610 // FALL THROUGH 611 case GlobalValue::InternalLinkage: 612 if (C->isNullValue()) 613 SwitchSection(O, CurSection, ".bss"); 614 else 615 SwitchSection(O, CurSection, ".data"); 616 break; 617 case GlobalValue::GhostLinkage: 618 std::cerr << "Should not have any unmaterialized functions!\n"; 619 abort(); 620 } 621 622 O << "\t.align " << Align << "\n"; 623 O << "\t.type " << name << ",#object\n"; 624 O << "\t.size " << name << "," << Size << "\n"; 625 O << name << ":\t\t\t\t! "; 626 WriteAsOperand(O, I, true, true, &M); 627 O << " = "; 628 WriteAsOperand(O, C, false, false, &M); 629 O << "\n"; 630 emitGlobalConstant(C); 631 } 632 } 633 634 delete Mang; 635 return false; // success 636} 637