1 //===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // 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 MIPS assembly language. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #define DEBUG_TYPE "mips-asm-printer" 16 #include "InstPrinter/MipsInstPrinter.h" 17 #include "MCTargetDesc/MipsBaseInfo.h" 18 #include "MCTargetDesc/MipsMCNaCl.h" 19 #include "Mips.h" 20 #include "MipsAsmPrinter.h" 21 #include "MipsInstrInfo.h" 22 #include "MipsMCInstLower.h" 23 #include "MipsTargetStreamer.h" 24 #include "llvm/ADT/SmallString.h" 25 #include "llvm/ADT/StringExtras.h" 26 #include "llvm/ADT/Twine.h" 27 #include "llvm/CodeGen/MachineConstantPool.h" 28 #include "llvm/CodeGen/MachineFrameInfo.h" 29 #include "llvm/CodeGen/MachineFunctionPass.h" 30 #include "llvm/CodeGen/MachineInstr.h" 31 #include "llvm/CodeGen/MachineJumpTableInfo.h" 32 #include "llvm/CodeGen/MachineMemOperand.h" 33 #include "llvm/IR/BasicBlock.h" 34 #include "llvm/IR/DataLayout.h" 35 #include "llvm/IR/InlineAsm.h" 36 #include "llvm/IR/Instructions.h" 37 #include "llvm/IR/Mangler.h" 38 #include "llvm/MC/MCAsmInfo.h" 39 #include "llvm/MC/MCContext.h" 40 #include "llvm/MC/MCELFStreamer.h" 41 #include "llvm/MC/MCExpr.h" 42 #include "llvm/MC/MCInst.h" 43 #include "llvm/MC/MCSection.h" 44 #include "llvm/MC/MCSectionELF.h" 45 #include "llvm/MC/MCSymbol.h" 46 #include "llvm/Support/ELF.h" 47 #include "llvm/Support/TargetRegistry.h" 48 #include "llvm/Support/raw_ostream.h" 49 #include "llvm/Target/TargetLoweringObjectFile.h" 50 #include "llvm/Target/TargetOptions.h" 51 #include <string> 52 53 using namespace llvm; 54 55 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { 56 return static_cast<MipsTargetStreamer &>(*OutStreamer.getTargetStreamer()); 57 } 58 59 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 60 // Initialize TargetLoweringObjectFile. 61 if (Subtarget->allowMixed16_32()) 62 const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 63 .Initialize(OutContext, TM); 64 MipsFI = MF.getInfo<MipsFunctionInfo>(); 65 if (Subtarget->inMips16Mode()) 66 for (std::map< 67 const char *, 68 const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 69 it = MipsFI->StubsNeeded.begin(); 70 it != MipsFI->StubsNeeded.end(); ++it) { 71 const char *Symbol = it->first; 72 const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 73 if (StubsNeeded.find(Symbol) == StubsNeeded.end()) 74 StubsNeeded[Symbol] = Signature; 75 } 76 MCP = MF.getConstantPool(); 77 78 // In NaCl, all indirect jump targets must be aligned to bundle size. 79 if (Subtarget->isTargetNaCl()) 80 NaClAlignIndirectJumpTargets(MF); 81 82 AsmPrinter::runOnMachineFunction(MF); 83 return true; 84 } 85 86 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { 87 MCOp = MCInstLowering.LowerOperand(MO); 88 return MCOp.isValid(); 89 } 90 91 #include "MipsGenMCPseudoLowering.inc" 92 93 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { 94 if (MI->isDebugValue()) { 95 SmallString<128> Str; 96 raw_svector_ostream OS(Str); 97 98 PrintDebugValueComment(MI, OS); 99 return; 100 } 101 102 // If we just ended a constant pool, mark it as such. 103 if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) { 104 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 105 InConstantPool = false; 106 } 107 if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) { 108 // CONSTPOOL_ENTRY - This instruction represents a floating 109 //constant pool in the function. The first operand is the ID# 110 // for this instruction, the second is the index into the 111 // MachineConstantPool that this is, the third is the size in 112 // bytes of this constant pool entry. 113 // The required alignment is specified on the basic block holding this MI. 114 // 115 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 116 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 117 118 // If this is the first entry of the pool, mark it. 119 if (!InConstantPool) { 120 OutStreamer.EmitDataRegion(MCDR_DataRegion); 121 InConstantPool = true; 122 } 123 124 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 125 126 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 127 if (MCPE.isMachineConstantPoolEntry()) 128 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 129 else 130 EmitGlobalConstant(MCPE.Val.ConstVal); 131 return; 132 } 133 134 135 MachineBasicBlock::const_instr_iterator I = MI; 136 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 137 138 do { 139 // Do any auto-generated pseudo lowerings. 140 if (emitPseudoExpansionLowering(OutStreamer, &*I)) 141 continue; 142 143 // The inMips16Mode() test is not permanent. 144 // Some instructions are marked as pseudo right now which 145 // would make the test fail for the wrong reason but 146 // that will be fixed soon. We need this here because we are 147 // removing another test for this situation downstream in the 148 // callchain. 149 // 150 if (I->isPseudo() && !Subtarget->inMips16Mode()) 151 llvm_unreachable("Pseudo opcode found in EmitInstruction()"); 152 153 MCInst TmpInst0; 154 MCInstLowering.Lower(I, TmpInst0); 155 EmitToStreamer(OutStreamer, TmpInst0); 156 } while ((++I != E) && I->isInsideBundle()); // Delay slot check 157 } 158 159 //===----------------------------------------------------------------------===// 160 // 161 // Mips Asm Directives 162 // 163 // -- Frame directive "frame Stackpointer, Stacksize, RARegister" 164 // Describe the stack frame. 165 // 166 // -- Mask directives "(f)mask bitmask, offset" 167 // Tells the assembler which registers are saved and where. 168 // bitmask - contain a little endian bitset indicating which registers are 169 // saved on function prologue (e.g. with a 0x80000000 mask, the 170 // assembler knows the register 31 (RA) is saved at prologue. 171 // offset - the position before stack pointer subtraction indicating where 172 // the first saved register on prologue is located. (e.g. with a 173 // 174 // Consider the following function prologue: 175 // 176 // .frame $fp,48,$ra 177 // .mask 0xc0000000,-8 178 // addiu $sp, $sp, -48 179 // sw $ra, 40($sp) 180 // sw $fp, 36($sp) 181 // 182 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 183 // 30 (FP) are saved at prologue. As the save order on prologue is from 184 // left to right, RA is saved first. A -8 offset means that after the 185 // stack pointer subtration, the first register in the mask (RA) will be 186 // saved at address 48-8=40. 187 // 188 //===----------------------------------------------------------------------===// 189 190 //===----------------------------------------------------------------------===// 191 // Mask directives 192 //===----------------------------------------------------------------------===// 193 194 // Create a bitmask with all callee saved registers for CPU or Floating Point 195 // registers. For CPU registers consider RA, GP and FP for saving if necessary. 196 void MipsAsmPrinter::printSavedRegsBitmask() { 197 // CPU and FPU Saved Registers Bitmasks 198 unsigned CPUBitmask = 0, FPUBitmask = 0; 199 int CPUTopSavedRegOff, FPUTopSavedRegOff; 200 201 // Set the CPU and FPU Bitmasks 202 const MachineFrameInfo *MFI = MF->getFrameInfo(); 203 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 204 // size of stack area to which FP callee-saved regs are saved. 205 unsigned CPURegSize = Mips::GPR32RegClass.getSize(); 206 unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); 207 unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); 208 bool HasAFGR64Reg = false; 209 unsigned CSFPRegsSize = 0; 210 unsigned i, e = CSI.size(); 211 212 // Set FPU Bitmask. 213 for (i = 0; i != e; ++i) { 214 unsigned Reg = CSI[i].getReg(); 215 if (Mips::GPR32RegClass.contains(Reg)) 216 break; 217 218 unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 219 if (Mips::AFGR64RegClass.contains(Reg)) { 220 FPUBitmask |= (3 << RegNum); 221 CSFPRegsSize += AFGR64RegSize; 222 HasAFGR64Reg = true; 223 continue; 224 } 225 226 FPUBitmask |= (1 << RegNum); 227 CSFPRegsSize += FGR32RegSize; 228 } 229 230 // Set CPU Bitmask. 231 for (; i != e; ++i) { 232 unsigned Reg = CSI[i].getReg(); 233 unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 234 CPUBitmask |= (1 << RegNum); 235 } 236 237 // FP Regs are saved right below where the virtual frame pointer points to. 238 FPUTopSavedRegOff = FPUBitmask ? 239 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 240 241 // CPU Regs are saved below FP Regs. 242 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 243 244 MipsTargetStreamer &TS = getTargetStreamer(); 245 // Print CPUBitmask 246 TS.emitMask(CPUBitmask, CPUTopSavedRegOff); 247 248 // Print FPUBitmask 249 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff); 250 } 251 252 //===----------------------------------------------------------------------===// 253 // Frame and Set directives 254 //===----------------------------------------------------------------------===// 255 256 /// Frame Directive 257 void MipsAsmPrinter::emitFrameDirective() { 258 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 259 260 unsigned stackReg = RI.getFrameRegister(*MF); 261 unsigned returnReg = RI.getRARegister(); 262 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 263 264 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg); 265 } 266 267 /// Emit Set directives. 268 const char *MipsAsmPrinter::getCurrentABIString() const { 269 switch (Subtarget->getTargetABI()) { 270 case MipsSubtarget::O32: return "abi32"; 271 case MipsSubtarget::N32: return "abiN32"; 272 case MipsSubtarget::N64: return "abi64"; 273 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 274 default: llvm_unreachable("Unknown Mips ABI"); 275 } 276 } 277 278 void MipsAsmPrinter::EmitFunctionEntryLabel() { 279 MipsTargetStreamer &TS = getTargetStreamer(); 280 281 // NaCl sandboxing requires that indirect call instructions are masked. 282 // This means that function entry points should be bundle-aligned. 283 if (Subtarget->isTargetNaCl()) 284 EmitAlignment(std::max(MF->getAlignment(), MIPS_NACL_BUNDLE_ALIGN)); 285 286 if (Subtarget->inMicroMipsMode()) 287 TS.emitDirectiveSetMicroMips(); 288 else 289 TS.emitDirectiveSetNoMicroMips(); 290 291 if (Subtarget->inMips16Mode()) 292 TS.emitDirectiveSetMips16(); 293 else 294 TS.emitDirectiveSetNoMips16(); 295 296 TS.emitDirectiveEnt(*CurrentFnSym); 297 OutStreamer.EmitLabel(CurrentFnSym); 298 } 299 300 /// EmitFunctionBodyStart - Targets can override this to emit stuff before 301 /// the first basic block in the function. 302 void MipsAsmPrinter::EmitFunctionBodyStart() { 303 MipsTargetStreamer &TS = getTargetStreamer(); 304 305 MCInstLowering.Initialize(&MF->getContext()); 306 307 bool IsNakedFunction = 308 MF->getFunction()-> 309 getAttributes().hasAttribute(AttributeSet::FunctionIndex, 310 Attribute::Naked); 311 if (!IsNakedFunction) 312 emitFrameDirective(); 313 314 if (!IsNakedFunction) 315 printSavedRegsBitmask(); 316 317 if (!Subtarget->inMips16Mode()) { 318 TS.emitDirectiveSetNoReorder(); 319 TS.emitDirectiveSetNoMacro(); 320 TS.emitDirectiveSetNoAt(); 321 } 322 } 323 324 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after 325 /// the last basic block in the function. 326 void MipsAsmPrinter::EmitFunctionBodyEnd() { 327 MipsTargetStreamer &TS = getTargetStreamer(); 328 329 // There are instruction for this macros, but they must 330 // always be at the function end, and we can't emit and 331 // break with BB logic. 332 if (!Subtarget->inMips16Mode()) { 333 TS.emitDirectiveSetAt(); 334 TS.emitDirectiveSetMacro(); 335 TS.emitDirectiveSetReorder(); 336 } 337 TS.emitDirectiveEnd(CurrentFnSym->getName()); 338 // Make sure to terminate any constant pools that were at the end 339 // of the function. 340 if (!InConstantPool) 341 return; 342 InConstantPool = false; 343 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 344 } 345 346 /// isBlockOnlyReachableByFallthough - Return true if the basic block has 347 /// exactly one predecessor and the control transfer mechanism between 348 /// the predecessor and this block is a fall-through. 349 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 350 MBB) const { 351 // The predecessor has to be immediately before this block. 352 const MachineBasicBlock *Pred = *MBB->pred_begin(); 353 354 // If the predecessor is a switch statement, assume a jump table 355 // implementation, so it is not a fall through. 356 if (const BasicBlock *bb = Pred->getBasicBlock()) 357 if (isa<SwitchInst>(bb->getTerminator())) 358 return false; 359 360 // If this is a landing pad, it isn't a fall through. If it has no preds, 361 // then nothing falls through to it. 362 if (MBB->isLandingPad() || MBB->pred_empty()) 363 return false; 364 365 // If there isn't exactly one predecessor, it can't be a fall through. 366 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 367 ++PI2; 368 369 if (PI2 != MBB->pred_end()) 370 return false; 371 372 // The predecessor has to be immediately before this block. 373 if (!Pred->isLayoutSuccessor(MBB)) 374 return false; 375 376 // If the block is completely empty, then it definitely does fall through. 377 if (Pred->empty()) 378 return true; 379 380 // Otherwise, check the last instruction. 381 // Check if the last terminator is an unconditional branch. 382 MachineBasicBlock::const_iterator I = Pred->end(); 383 while (I != Pred->begin() && !(--I)->isTerminator()) ; 384 385 return !I->isBarrier(); 386 } 387 388 // Print out an operand for an inline asm expression. 389 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 390 unsigned AsmVariant,const char *ExtraCode, 391 raw_ostream &O) { 392 // Does this asm operand have a single letter operand modifier? 393 if (ExtraCode && ExtraCode[0]) { 394 if (ExtraCode[1] != 0) return true; // Unknown modifier. 395 396 const MachineOperand &MO = MI->getOperand(OpNum); 397 switch (ExtraCode[0]) { 398 default: 399 // See if this is a generic print operand 400 return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O); 401 case 'X': // hex const int 402 if ((MO.getType()) != MachineOperand::MO_Immediate) 403 return true; 404 O << "0x" << StringRef(utohexstr(MO.getImm())).lower(); 405 return false; 406 case 'x': // hex const int (low 16 bits) 407 if ((MO.getType()) != MachineOperand::MO_Immediate) 408 return true; 409 O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower(); 410 return false; 411 case 'd': // decimal const int 412 if ((MO.getType()) != MachineOperand::MO_Immediate) 413 return true; 414 O << MO.getImm(); 415 return false; 416 case 'm': // decimal const int minus 1 417 if ((MO.getType()) != MachineOperand::MO_Immediate) 418 return true; 419 O << MO.getImm() - 1; 420 return false; 421 case 'z': { 422 // $0 if zero, regular printing otherwise 423 if (MO.getType() != MachineOperand::MO_Immediate) 424 return true; 425 int64_t Val = MO.getImm(); 426 if (Val) 427 O << Val; 428 else 429 O << "$0"; 430 return false; 431 } 432 case 'D': // Second part of a double word register operand 433 case 'L': // Low order register of a double word register operand 434 case 'M': // High order register of a double word register operand 435 { 436 if (OpNum == 0) 437 return true; 438 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 439 if (!FlagsOP.isImm()) 440 return true; 441 unsigned Flags = FlagsOP.getImm(); 442 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 443 // Number of registers represented by this operand. We are looking 444 // for 2 for 32 bit mode and 1 for 64 bit mode. 445 if (NumVals != 2) { 446 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 447 unsigned Reg = MO.getReg(); 448 O << '$' << MipsInstPrinter::getRegisterName(Reg); 449 return false; 450 } 451 return true; 452 } 453 454 unsigned RegOp = OpNum; 455 if (!Subtarget->isGP64bit()){ 456 // Endianess reverses which register holds the high or low value 457 // between M and L. 458 switch(ExtraCode[0]) { 459 case 'M': 460 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum; 461 break; 462 case 'L': 463 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1; 464 break; 465 case 'D': // Always the second part 466 RegOp = OpNum + 1; 467 } 468 if (RegOp >= MI->getNumOperands()) 469 return true; 470 const MachineOperand &MO = MI->getOperand(RegOp); 471 if (!MO.isReg()) 472 return true; 473 unsigned Reg = MO.getReg(); 474 O << '$' << MipsInstPrinter::getRegisterName(Reg); 475 return false; 476 } 477 } 478 case 'w': 479 // Print MSA registers for the 'f' constraint 480 // In LLVM, the 'w' modifier doesn't need to do anything. 481 // We can just call printOperand as normal. 482 break; 483 } 484 } 485 486 printOperand(MI, OpNum, O); 487 return false; 488 } 489 490 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 491 unsigned OpNum, unsigned AsmVariant, 492 const char *ExtraCode, 493 raw_ostream &O) { 494 int Offset = 0; 495 // Currently we are expecting either no ExtraCode or 'D' 496 if (ExtraCode) { 497 if (ExtraCode[0] == 'D') 498 Offset = 4; 499 else 500 return true; // Unknown modifier. 501 } 502 503 const MachineOperand &MO = MI->getOperand(OpNum); 504 assert(MO.isReg() && "unexpected inline asm memory operand"); 505 O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; 506 507 return false; 508 } 509 510 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 511 raw_ostream &O) { 512 const DataLayout *DL = TM.getDataLayout(); 513 const MachineOperand &MO = MI->getOperand(opNum); 514 bool closeP = false; 515 516 if (MO.getTargetFlags()) 517 closeP = true; 518 519 switch(MO.getTargetFlags()) { 520 case MipsII::MO_GPREL: O << "%gp_rel("; break; 521 case MipsII::MO_GOT_CALL: O << "%call16("; break; 522 case MipsII::MO_GOT: O << "%got("; break; 523 case MipsII::MO_ABS_HI: O << "%hi("; break; 524 case MipsII::MO_ABS_LO: O << "%lo("; break; 525 case MipsII::MO_TLSGD: O << "%tlsgd("; break; 526 case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 527 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 528 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 529 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 530 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 531 case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 532 case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 533 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 534 } 535 536 switch (MO.getType()) { 537 case MachineOperand::MO_Register: 538 O << '$' 539 << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 540 break; 541 542 case MachineOperand::MO_Immediate: 543 O << MO.getImm(); 544 break; 545 546 case MachineOperand::MO_MachineBasicBlock: 547 O << *MO.getMBB()->getSymbol(); 548 return; 549 550 case MachineOperand::MO_GlobalAddress: 551 O << *getSymbol(MO.getGlobal()); 552 break; 553 554 case MachineOperand::MO_BlockAddress: { 555 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 556 O << BA->getName(); 557 break; 558 } 559 560 case MachineOperand::MO_ConstantPoolIndex: 561 O << DL->getPrivateGlobalPrefix() << "CPI" 562 << getFunctionNumber() << "_" << MO.getIndex(); 563 if (MO.getOffset()) 564 O << "+" << MO.getOffset(); 565 break; 566 567 default: 568 llvm_unreachable("<unknown operand type>"); 569 } 570 571 if (closeP) O << ")"; 572 } 573 574 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 575 raw_ostream &O) { 576 const MachineOperand &MO = MI->getOperand(opNum); 577 if (MO.isImm()) 578 O << (unsigned short int)MO.getImm(); 579 else 580 printOperand(MI, opNum, O); 581 } 582 583 void MipsAsmPrinter::printUnsignedImm8(const MachineInstr *MI, int opNum, 584 raw_ostream &O) { 585 const MachineOperand &MO = MI->getOperand(opNum); 586 if (MO.isImm()) 587 O << (unsigned short int)(unsigned char)MO.getImm(); 588 else 589 printOperand(MI, opNum, O); 590 } 591 592 void MipsAsmPrinter:: 593 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 594 // Load/Store memory operands -- imm($reg) 595 // If PIC target the target is loaded as the 596 // pattern lw $25,%call16($28) 597 printOperand(MI, opNum+1, O); 598 O << "("; 599 printOperand(MI, opNum, O); 600 O << ")"; 601 } 602 603 void MipsAsmPrinter:: 604 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 605 // when using stack locations for not load/store instructions 606 // print the same way as all normal 3 operand instructions. 607 printOperand(MI, opNum, O); 608 O << ", "; 609 printOperand(MI, opNum+1, O); 610 return; 611 } 612 613 void MipsAsmPrinter:: 614 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 615 const char *Modifier) { 616 const MachineOperand &MO = MI->getOperand(opNum); 617 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 618 } 619 620 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 621 // TODO: Need to add -mabicalls and -mno-abicalls flags. 622 // Currently we assume that -mabicalls is the default. 623 bool IsABICalls = true; 624 if (IsABICalls) { 625 getTargetStreamer().emitDirectiveAbiCalls(); 626 Reloc::Model RM = Subtarget->getRelocationModel(); 627 // FIXME: This condition should be a lot more complicated that it is here. 628 // Ideally it should test for properties of the ABI and not the ABI 629 // itself. 630 // For the moment, I'm only correcting enough to make MIPS-IV work. 631 if (RM == Reloc::Static && !Subtarget->isABI_N64()) 632 getTargetStreamer().emitDirectiveOptionPic0(); 633 } 634 635 // Tell the assembler which ABI we are using 636 std::string SectionName = std::string(".mdebug.") + getCurrentABIString(); 637 OutStreamer.SwitchSection(OutContext.getELFSection( 638 SectionName, ELF::SHT_PROGBITS, 0, SectionKind::getDataRel())); 639 640 // NaN: At the moment we only support: 641 // 1. .nan legacy (default) 642 // 2. .nan 2008 643 Subtarget->isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008() 644 : getTargetStreamer().emitDirectiveNaNLegacy(); 645 646 // TODO: handle O64 ABI 647 648 if (Subtarget->isABI_EABI()) { 649 if (Subtarget->isGP32bit()) 650 OutStreamer.SwitchSection( 651 OutContext.getELFSection(".gcc_compiled_long32", ELF::SHT_PROGBITS, 0, 652 SectionKind::getDataRel())); 653 else 654 OutStreamer.SwitchSection( 655 OutContext.getELFSection(".gcc_compiled_long64", ELF::SHT_PROGBITS, 0, 656 SectionKind::getDataRel())); 657 } 658 } 659 660 void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) { 661 MCInst I; 662 I.setOpcode(Mips::JAL); 663 I.addOperand( 664 MCOperand::CreateExpr(MCSymbolRefExpr::Create(Symbol, OutContext))); 665 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 666 } 667 668 void MipsAsmPrinter::EmitInstrReg(unsigned Opcode, unsigned Reg) { 669 MCInst I; 670 I.setOpcode(Opcode); 671 I.addOperand(MCOperand::CreateReg(Reg)); 672 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 673 } 674 675 void MipsAsmPrinter::EmitInstrRegReg(unsigned Opcode, unsigned Reg1, 676 unsigned Reg2) { 677 MCInst I; 678 // 679 // Because of the current td files for Mips32, the operands for MTC1 680 // appear backwards from their normal assembly order. It's not a trivial 681 // change to fix this in the td file so we adjust for it here. 682 // 683 if (Opcode == Mips::MTC1) { 684 unsigned Temp = Reg1; 685 Reg1 = Reg2; 686 Reg2 = Temp; 687 } 688 I.setOpcode(Opcode); 689 I.addOperand(MCOperand::CreateReg(Reg1)); 690 I.addOperand(MCOperand::CreateReg(Reg2)); 691 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 692 } 693 694 void MipsAsmPrinter::EmitInstrRegRegReg(unsigned Opcode, unsigned Reg1, 695 unsigned Reg2, unsigned Reg3) { 696 MCInst I; 697 I.setOpcode(Opcode); 698 I.addOperand(MCOperand::CreateReg(Reg1)); 699 I.addOperand(MCOperand::CreateReg(Reg2)); 700 I.addOperand(MCOperand::CreateReg(Reg3)); 701 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 702 } 703 704 void MipsAsmPrinter::EmitMovFPIntPair(unsigned MovOpc, unsigned Reg1, 705 unsigned Reg2, unsigned FPReg1, 706 unsigned FPReg2, bool LE) { 707 if (!LE) { 708 unsigned temp = Reg1; 709 Reg1 = Reg2; 710 Reg2 = temp; 711 } 712 EmitInstrRegReg(MovOpc, Reg1, FPReg1); 713 EmitInstrRegReg(MovOpc, Reg2, FPReg2); 714 } 715 716 void MipsAsmPrinter::EmitSwapFPIntParams(Mips16HardFloatInfo::FPParamVariant PV, 717 bool LE, bool ToFP) { 718 using namespace Mips16HardFloatInfo; 719 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1; 720 switch (PV) { 721 case FSig: 722 EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 723 break; 724 case FFSig: 725 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE); 726 break; 727 case FDSig: 728 EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 729 EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 730 break; 731 case DSig: 732 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 733 break; 734 case DDSig: 735 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 736 EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 737 break; 738 case DFSig: 739 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 740 EmitInstrRegReg(MovOpc, Mips::A2, Mips::F14); 741 break; 742 case NoSig: 743 return; 744 } 745 } 746 747 void 748 MipsAsmPrinter::EmitSwapFPIntRetval(Mips16HardFloatInfo::FPReturnVariant RV, 749 bool LE) { 750 using namespace Mips16HardFloatInfo; 751 unsigned MovOpc = Mips::MFC1; 752 switch (RV) { 753 case FRet: 754 EmitInstrRegReg(MovOpc, Mips::V0, Mips::F0); 755 break; 756 case DRet: 757 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 758 break; 759 case CFRet: 760 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 761 break; 762 case CDRet: 763 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 764 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE); 765 break; 766 case NoFPRet: 767 break; 768 } 769 } 770 771 void MipsAsmPrinter::EmitFPCallStub( 772 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) { 773 MCSymbol *MSymbol = OutContext.GetOrCreateSymbol(StringRef(Symbol)); 774 using namespace Mips16HardFloatInfo; 775 bool LE = Subtarget->isLittle(); 776 // 777 // .global xxxx 778 // 779 OutStreamer.EmitSymbolAttribute(MSymbol, MCSA_Global); 780 const char *RetType; 781 // 782 // make the comment field identifying the return and parameter 783 // types of the floating point stub 784 // # Stub function to call rettype xxxx (params) 785 // 786 switch (Signature->RetSig) { 787 case FRet: 788 RetType = "float"; 789 break; 790 case DRet: 791 RetType = "double"; 792 break; 793 case CFRet: 794 RetType = "complex"; 795 break; 796 case CDRet: 797 RetType = "double complex"; 798 break; 799 case NoFPRet: 800 RetType = ""; 801 break; 802 } 803 const char *Parms; 804 switch (Signature->ParamSig) { 805 case FSig: 806 Parms = "float"; 807 break; 808 case FFSig: 809 Parms = "float, float"; 810 break; 811 case FDSig: 812 Parms = "float, double"; 813 break; 814 case DSig: 815 Parms = "double"; 816 break; 817 case DDSig: 818 Parms = "double, double"; 819 break; 820 case DFSig: 821 Parms = "double, float"; 822 break; 823 case NoSig: 824 Parms = ""; 825 break; 826 } 827 OutStreamer.AddComment("\t# Stub function to call " + Twine(RetType) + " " + 828 Twine(Symbol) + " (" + Twine(Parms) + ")"); 829 // 830 // probably not necessary but we save and restore the current section state 831 // 832 OutStreamer.PushSection(); 833 // 834 // .section mips16.call.fpxxxx,"ax",@progbits 835 // 836 const MCSectionELF *M = OutContext.getELFSection( 837 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS, 838 ELF::SHF_ALLOC | ELF::SHF_EXECINSTR, SectionKind::getText()); 839 OutStreamer.SwitchSection(M, 0); 840 // 841 // .align 2 842 // 843 OutStreamer.EmitValueToAlignment(4); 844 MipsTargetStreamer &TS = getTargetStreamer(); 845 // 846 // .set nomips16 847 // .set nomicromips 848 // 849 TS.emitDirectiveSetNoMips16(); 850 TS.emitDirectiveSetNoMicroMips(); 851 // 852 // .ent __call_stub_fp_xxxx 853 // .type __call_stub_fp_xxxx,@function 854 // __call_stub_fp_xxxx: 855 // 856 std::string x = "__call_stub_fp_" + std::string(Symbol); 857 MCSymbol *Stub = OutContext.GetOrCreateSymbol(StringRef(x)); 858 TS.emitDirectiveEnt(*Stub); 859 MCSymbol *MType = 860 OutContext.GetOrCreateSymbol("__call_stub_fp_" + Twine(Symbol)); 861 OutStreamer.EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction); 862 OutStreamer.EmitLabel(Stub); 863 // 864 // we just handle non pic for now. these function will not be 865 // called otherwise. when the full stub generation is moved here 866 // we need to deal with pic. 867 // 868 if (Subtarget->getRelocationModel() == Reloc::PIC_) 869 llvm_unreachable("should not be here if we are compiling pic"); 870 TS.emitDirectiveSetReorder(); 871 // 872 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement 873 // stubs without raw text but this current patch is for compiler generated 874 // functions and they all return some value. 875 // The calling sequence for non pic is different in that case and we need 876 // to implement %lo and %hi in order to handle the case of no return value 877 // See the corresponding method in Mips16HardFloat for details. 878 // 879 // mov the return address to S2. 880 // we have no stack space to store it and we are about to make another call. 881 // We need to make sure that the enclosing function knows to save S2 882 // This should have already been handled. 883 // 884 // Mov $18, $31 885 886 EmitInstrRegRegReg(Mips::ADDu, Mips::S2, Mips::RA, Mips::ZERO); 887 888 EmitSwapFPIntParams(Signature->ParamSig, LE, true); 889 890 // Jal xxxx 891 // 892 EmitJal(MSymbol); 893 894 // fix return values 895 EmitSwapFPIntRetval(Signature->RetSig, LE); 896 // 897 // do the return 898 // if (Signature->RetSig == NoFPRet) 899 // llvm_unreachable("should not be any stubs here with no return value"); 900 // else 901 EmitInstrReg(Mips::JR, Mips::S2); 902 903 MCSymbol *Tmp = OutContext.CreateTempSymbol(); 904 OutStreamer.EmitLabel(Tmp); 905 const MCSymbolRefExpr *E = MCSymbolRefExpr::Create(Stub, OutContext); 906 const MCSymbolRefExpr *T = MCSymbolRefExpr::Create(Tmp, OutContext); 907 const MCExpr *T_min_E = MCBinaryExpr::CreateSub(T, E, OutContext); 908 OutStreamer.EmitELFSize(Stub, T_min_E); 909 TS.emitDirectiveEnd(x); 910 OutStreamer.PopSection(); 911 } 912 913 void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { 914 // Emit needed stubs 915 // 916 for (std::map< 917 const char *, 918 const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 919 it = StubsNeeded.begin(); 920 it != StubsNeeded.end(); ++it) { 921 const char *Symbol = it->first; 922 const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 923 EmitFPCallStub(Symbol, Signature); 924 } 925 // return to the text section 926 OutStreamer.SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); 927 } 928 929 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 930 raw_ostream &OS) { 931 // TODO: implement 932 } 933 934 // Align all targets of indirect branches on bundle size. Used only if target 935 // is NaCl. 936 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) { 937 // Align all blocks that are jumped to through jump table. 938 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) { 939 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables(); 940 for (unsigned I = 0; I < JT.size(); ++I) { 941 const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs; 942 943 for (unsigned J = 0; J < MBBs.size(); ++J) 944 MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 945 } 946 } 947 948 // If basic block address is taken, block can be target of indirect branch. 949 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 950 MBB != E; ++MBB) { 951 if (MBB->hasAddressTaken()) 952 MBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 953 } 954 } 955 956 // Force static initialization. 957 extern "C" void LLVMInitializeMipsAsmPrinter() { 958 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 959 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 960 RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target); 961 RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget); 962 } 963