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