1 //===- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer --------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains a printer that converts from our internal representation 10 // of machine-dependent LLVM code to GAS-format MIPS assembly language. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MipsAsmPrinter.h" 15 #include "MCTargetDesc/MipsABIInfo.h" 16 #include "MCTargetDesc/MipsBaseInfo.h" 17 #include "MCTargetDesc/MipsInstPrinter.h" 18 #include "MCTargetDesc/MipsMCNaCl.h" 19 #include "MCTargetDesc/MipsMCTargetDesc.h" 20 #include "Mips.h" 21 #include "MipsMCInstLower.h" 22 #include "MipsMachineFunction.h" 23 #include "MipsSubtarget.h" 24 #include "MipsTargetMachine.h" 25 #include "MipsTargetStreamer.h" 26 #include "TargetInfo/MipsTargetInfo.h" 27 #include "llvm/ADT/SmallString.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/ADT/Triple.h" 30 #include "llvm/ADT/Twine.h" 31 #include "llvm/BinaryFormat/ELF.h" 32 #include "llvm/CodeGen/MachineBasicBlock.h" 33 #include "llvm/CodeGen/MachineConstantPool.h" 34 #include "llvm/CodeGen/MachineFrameInfo.h" 35 #include "llvm/CodeGen/MachineFunction.h" 36 #include "llvm/CodeGen/MachineInstr.h" 37 #include "llvm/CodeGen/MachineJumpTableInfo.h" 38 #include "llvm/CodeGen/MachineOperand.h" 39 #include "llvm/CodeGen/TargetRegisterInfo.h" 40 #include "llvm/CodeGen/TargetSubtargetInfo.h" 41 #include "llvm/IR/Attributes.h" 42 #include "llvm/IR/BasicBlock.h" 43 #include "llvm/IR/DataLayout.h" 44 #include "llvm/IR/Function.h" 45 #include "llvm/IR/InlineAsm.h" 46 #include "llvm/IR/Instructions.h" 47 #include "llvm/MC/MCContext.h" 48 #include "llvm/MC/MCExpr.h" 49 #include "llvm/MC/MCInst.h" 50 #include "llvm/MC/MCInstBuilder.h" 51 #include "llvm/MC/MCObjectFileInfo.h" 52 #include "llvm/MC/MCSectionELF.h" 53 #include "llvm/MC/MCSymbol.h" 54 #include "llvm/MC/MCSymbolELF.h" 55 #include "llvm/Support/Casting.h" 56 #include "llvm/Support/ErrorHandling.h" 57 #include "llvm/Support/TargetRegistry.h" 58 #include "llvm/Support/raw_ostream.h" 59 #include "llvm/Target/TargetLoweringObjectFile.h" 60 #include "llvm/Target/TargetMachine.h" 61 #include <cassert> 62 #include <cstdint> 63 #include <map> 64 #include <memory> 65 #include <string> 66 #include <vector> 67 68 using namespace llvm; 69 70 #define DEBUG_TYPE "mips-asm-printer" 71 72 extern cl::opt<bool> EmitJalrReloc; 73 74 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const { 75 return static_cast<MipsTargetStreamer &>(*OutStreamer->getTargetStreamer()); 76 } 77 78 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 79 Subtarget = &MF.getSubtarget<MipsSubtarget>(); 80 81 MipsFI = MF.getInfo<MipsFunctionInfo>(); 82 if (Subtarget->inMips16Mode()) 83 for (std::map< 84 const char *, 85 const Mips16HardFloatInfo::FuncSignature *>::const_iterator 86 it = MipsFI->StubsNeeded.begin(); 87 it != MipsFI->StubsNeeded.end(); ++it) { 88 const char *Symbol = it->first; 89 const Mips16HardFloatInfo::FuncSignature *Signature = it->second; 90 if (StubsNeeded.find(Symbol) == StubsNeeded.end()) 91 StubsNeeded[Symbol] = Signature; 92 } 93 MCP = MF.getConstantPool(); 94 95 // In NaCl, all indirect jump targets must be aligned to bundle size. 96 if (Subtarget->isTargetNaCl()) 97 NaClAlignIndirectJumpTargets(MF); 98 99 AsmPrinter::runOnMachineFunction(MF); 100 101 emitXRayTable(); 102 103 return true; 104 } 105 106 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { 107 MCOp = MCInstLowering.LowerOperand(MO); 108 return MCOp.isValid(); 109 } 110 111 #include "MipsGenMCPseudoLowering.inc" 112 113 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM, 114 // JALR, or JALR64 as appropriate for the target. 115 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, 116 const MachineInstr *MI) { 117 bool HasLinkReg = false; 118 bool InMicroMipsMode = Subtarget->inMicroMipsMode(); 119 MCInst TmpInst0; 120 121 if (Subtarget->hasMips64r6()) { 122 // MIPS64r6 should use (JALR64 ZERO_64, $rs) 123 TmpInst0.setOpcode(Mips::JALR64); 124 HasLinkReg = true; 125 } else if (Subtarget->hasMips32r6()) { 126 // MIPS32r6 should use (JALR ZERO, $rs) 127 if (InMicroMipsMode) 128 TmpInst0.setOpcode(Mips::JRC16_MMR6); 129 else { 130 TmpInst0.setOpcode(Mips::JALR); 131 HasLinkReg = true; 132 } 133 } else if (Subtarget->inMicroMipsMode()) 134 // microMIPS should use (JR_MM $rs) 135 TmpInst0.setOpcode(Mips::JR_MM); 136 else { 137 // Everything else should use (JR $rs) 138 TmpInst0.setOpcode(Mips::JR); 139 } 140 141 MCOperand MCOp; 142 143 if (HasLinkReg) { 144 unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO; 145 TmpInst0.addOperand(MCOperand::createReg(ZeroReg)); 146 } 147 148 lowerOperand(MI->getOperand(0), MCOp); 149 TmpInst0.addOperand(MCOp); 150 151 EmitToStreamer(OutStreamer, TmpInst0); 152 } 153 154 // If there is an MO_JALR operand, insert: 155 // 156 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol 157 // tmplabel: 158 // 159 // This is an optimization hint for the linker which may then replace 160 // an indirect call with a direct branch. 161 static void emitDirectiveRelocJalr(const MachineInstr &MI, 162 MCContext &OutContext, 163 TargetMachine &TM, 164 MCStreamer &OutStreamer, 165 const MipsSubtarget &Subtarget) { 166 for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands(); 167 I < E; ++I) { 168 MachineOperand MO = MI.getOperand(I); 169 if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) { 170 MCSymbol *Callee = MO.getMCSymbol(); 171 if (Callee && !Callee->getName().empty()) { 172 MCSymbol *OffsetLabel = OutContext.createTempSymbol(); 173 const MCExpr *OffsetExpr = 174 MCSymbolRefExpr::create(OffsetLabel, OutContext); 175 const MCExpr *CaleeExpr = 176 MCSymbolRefExpr::create(Callee, OutContext); 177 OutStreamer.emitRelocDirective( 178 *OffsetExpr, 179 Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", 180 CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); 181 OutStreamer.emitLabel(OffsetLabel); 182 return; 183 } 184 } 185 } 186 } 187 188 void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) { 189 MipsTargetStreamer &TS = getTargetStreamer(); 190 unsigned Opc = MI->getOpcode(); 191 TS.forbidModuleDirective(); 192 193 if (MI->isDebugValue()) { 194 SmallString<128> Str; 195 raw_svector_ostream OS(Str); 196 197 PrintDebugValueComment(MI, OS); 198 return; 199 } 200 if (MI->isDebugLabel()) 201 return; 202 203 // If we just ended a constant pool, mark it as such. 204 if (InConstantPool && Opc != Mips::CONSTPOOL_ENTRY) { 205 OutStreamer->emitDataRegion(MCDR_DataRegionEnd); 206 InConstantPool = false; 207 } 208 if (Opc == Mips::CONSTPOOL_ENTRY) { 209 // CONSTPOOL_ENTRY - This instruction represents a floating 210 // constant pool in the function. The first operand is the ID# 211 // for this instruction, the second is the index into the 212 // MachineConstantPool that this is, the third is the size in 213 // bytes of this constant pool entry. 214 // The required alignment is specified on the basic block holding this MI. 215 // 216 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 217 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 218 219 // If this is the first entry of the pool, mark it. 220 if (!InConstantPool) { 221 OutStreamer->emitDataRegion(MCDR_DataRegion); 222 InConstantPool = true; 223 } 224 225 OutStreamer->emitLabel(GetCPISymbol(LabelId)); 226 227 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 228 if (MCPE.isMachineConstantPoolEntry()) 229 emitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 230 else 231 emitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal); 232 return; 233 } 234 235 switch (Opc) { 236 case Mips::PATCHABLE_FUNCTION_ENTER: 237 LowerPATCHABLE_FUNCTION_ENTER(*MI); 238 return; 239 case Mips::PATCHABLE_FUNCTION_EXIT: 240 LowerPATCHABLE_FUNCTION_EXIT(*MI); 241 return; 242 case Mips::PATCHABLE_TAIL_CALL: 243 LowerPATCHABLE_TAIL_CALL(*MI); 244 return; 245 } 246 247 if (EmitJalrReloc && 248 (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) { 249 emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget); 250 } 251 252 MachineBasicBlock::const_instr_iterator I = MI->getIterator(); 253 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 254 255 do { 256 // Do any auto-generated pseudo lowerings. 257 if (emitPseudoExpansionLowering(*OutStreamer, &*I)) 258 continue; 259 260 // Skip the BUNDLE pseudo instruction and lower the contents 261 if (I->isBundle()) 262 continue; 263 264 if (I->getOpcode() == Mips::PseudoReturn || 265 I->getOpcode() == Mips::PseudoReturn64 || 266 I->getOpcode() == Mips::PseudoIndirectBranch || 267 I->getOpcode() == Mips::PseudoIndirectBranch64 || 268 I->getOpcode() == Mips::TAILCALLREG || 269 I->getOpcode() == Mips::TAILCALLREG64) { 270 emitPseudoIndirectBranch(*OutStreamer, &*I); 271 continue; 272 } 273 274 // The inMips16Mode() test is not permanent. 275 // Some instructions are marked as pseudo right now which 276 // would make the test fail for the wrong reason but 277 // that will be fixed soon. We need this here because we are 278 // removing another test for this situation downstream in the 279 // callchain. 280 // 281 if (I->isPseudo() && !Subtarget->inMips16Mode() 282 && !isLongBranchPseudo(I->getOpcode())) 283 llvm_unreachable("Pseudo opcode found in emitInstruction()"); 284 285 MCInst TmpInst0; 286 MCInstLowering.Lower(&*I, TmpInst0); 287 EmitToStreamer(*OutStreamer, TmpInst0); 288 } while ((++I != E) && I->isInsideBundle()); // Delay slot check 289 } 290 291 //===----------------------------------------------------------------------===// 292 // 293 // Mips Asm Directives 294 // 295 // -- Frame directive "frame Stackpointer, Stacksize, RARegister" 296 // Describe the stack frame. 297 // 298 // -- Mask directives "(f)mask bitmask, offset" 299 // Tells the assembler which registers are saved and where. 300 // bitmask - contain a little endian bitset indicating which registers are 301 // saved on function prologue (e.g. with a 0x80000000 mask, the 302 // assembler knows the register 31 (RA) is saved at prologue. 303 // offset - the position before stack pointer subtraction indicating where 304 // the first saved register on prologue is located. (e.g. with a 305 // 306 // Consider the following function prologue: 307 // 308 // .frame $fp,48,$ra 309 // .mask 0xc0000000,-8 310 // addiu $sp, $sp, -48 311 // sw $ra, 40($sp) 312 // sw $fp, 36($sp) 313 // 314 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 315 // 30 (FP) are saved at prologue. As the save order on prologue is from 316 // left to right, RA is saved first. A -8 offset means that after the 317 // stack pointer subtration, the first register in the mask (RA) will be 318 // saved at address 48-8=40. 319 // 320 //===----------------------------------------------------------------------===// 321 322 //===----------------------------------------------------------------------===// 323 // Mask directives 324 //===----------------------------------------------------------------------===// 325 326 // Create a bitmask with all callee saved registers for CPU or Floating Point 327 // registers. For CPU registers consider RA, GP and FP for saving if necessary. 328 void MipsAsmPrinter::printSavedRegsBitmask() { 329 // CPU and FPU Saved Registers Bitmasks 330 unsigned CPUBitmask = 0, FPUBitmask = 0; 331 int CPUTopSavedRegOff, FPUTopSavedRegOff; 332 333 // Set the CPU and FPU Bitmasks 334 const MachineFrameInfo &MFI = MF->getFrameInfo(); 335 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 336 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 337 // size of stack area to which FP callee-saved regs are saved. 338 unsigned CPURegSize = TRI->getRegSizeInBits(Mips::GPR32RegClass) / 8; 339 unsigned FGR32RegSize = TRI->getRegSizeInBits(Mips::FGR32RegClass) / 8; 340 unsigned AFGR64RegSize = TRI->getRegSizeInBits(Mips::AFGR64RegClass) / 8; 341 bool HasAFGR64Reg = false; 342 unsigned CSFPRegsSize = 0; 343 344 for (const auto &I : CSI) { 345 unsigned Reg = I.getReg(); 346 unsigned RegNum = TRI->getEncodingValue(Reg); 347 348 // If it's a floating point register, set the FPU Bitmask. 349 // If it's a general purpose register, set the CPU Bitmask. 350 if (Mips::FGR32RegClass.contains(Reg)) { 351 FPUBitmask |= (1 << RegNum); 352 CSFPRegsSize += FGR32RegSize; 353 } else if (Mips::AFGR64RegClass.contains(Reg)) { 354 FPUBitmask |= (3 << RegNum); 355 CSFPRegsSize += AFGR64RegSize; 356 HasAFGR64Reg = true; 357 } else if (Mips::GPR32RegClass.contains(Reg)) 358 CPUBitmask |= (1 << RegNum); 359 } 360 361 // FP Regs are saved right below where the virtual frame pointer points to. 362 FPUTopSavedRegOff = FPUBitmask ? 363 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 364 365 // CPU Regs are saved below FP Regs. 366 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 367 368 MipsTargetStreamer &TS = getTargetStreamer(); 369 // Print CPUBitmask 370 TS.emitMask(CPUBitmask, CPUTopSavedRegOff); 371 372 // Print FPUBitmask 373 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff); 374 } 375 376 //===----------------------------------------------------------------------===// 377 // Frame and Set directives 378 //===----------------------------------------------------------------------===// 379 380 /// Frame Directive 381 void MipsAsmPrinter::emitFrameDirective() { 382 const TargetRegisterInfo &RI = *MF->getSubtarget().getRegisterInfo(); 383 384 Register stackReg = RI.getFrameRegister(*MF); 385 unsigned returnReg = RI.getRARegister(); 386 unsigned stackSize = MF->getFrameInfo().getStackSize(); 387 388 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg); 389 } 390 391 /// Emit Set directives. 392 const char *MipsAsmPrinter::getCurrentABIString() const { 393 switch (static_cast<MipsTargetMachine &>(TM).getABI().GetEnumValue()) { 394 case MipsABIInfo::ABI::O32: return "abi32"; 395 case MipsABIInfo::ABI::N32: return "abiN32"; 396 case MipsABIInfo::ABI::N64: return "abi64"; 397 default: llvm_unreachable("Unknown Mips ABI"); 398 } 399 } 400 401 void MipsAsmPrinter::emitFunctionEntryLabel() { 402 MipsTargetStreamer &TS = getTargetStreamer(); 403 404 // NaCl sandboxing requires that indirect call instructions are masked. 405 // This means that function entry points should be bundle-aligned. 406 if (Subtarget->isTargetNaCl()) 407 emitAlignment(std::max(MF->getAlignment(), MIPS_NACL_BUNDLE_ALIGN)); 408 409 if (Subtarget->inMicroMipsMode()) { 410 TS.emitDirectiveSetMicroMips(); 411 TS.setUsesMicroMips(); 412 TS.updateABIInfo(*Subtarget); 413 } else 414 TS.emitDirectiveSetNoMicroMips(); 415 416 if (Subtarget->inMips16Mode()) 417 TS.emitDirectiveSetMips16(); 418 else 419 TS.emitDirectiveSetNoMips16(); 420 421 TS.emitDirectiveEnt(*CurrentFnSym); 422 OutStreamer->emitLabel(CurrentFnSym); 423 } 424 425 /// EmitFunctionBodyStart - Targets can override this to emit stuff before 426 /// the first basic block in the function. 427 void MipsAsmPrinter::emitFunctionBodyStart() { 428 MipsTargetStreamer &TS = getTargetStreamer(); 429 430 MCInstLowering.Initialize(&MF->getContext()); 431 432 bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked); 433 if (!IsNakedFunction) 434 emitFrameDirective(); 435 436 if (!IsNakedFunction) 437 printSavedRegsBitmask(); 438 439 if (!Subtarget->inMips16Mode()) { 440 TS.emitDirectiveSetNoReorder(); 441 TS.emitDirectiveSetNoMacro(); 442 TS.emitDirectiveSetNoAt(); 443 } 444 } 445 446 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after 447 /// the last basic block in the function. 448 void MipsAsmPrinter::emitFunctionBodyEnd() { 449 MipsTargetStreamer &TS = getTargetStreamer(); 450 451 // There are instruction for this macros, but they must 452 // always be at the function end, and we can't emit and 453 // break with BB logic. 454 if (!Subtarget->inMips16Mode()) { 455 TS.emitDirectiveSetAt(); 456 TS.emitDirectiveSetMacro(); 457 TS.emitDirectiveSetReorder(); 458 } 459 TS.emitDirectiveEnd(CurrentFnSym->getName()); 460 // Make sure to terminate any constant pools that were at the end 461 // of the function. 462 if (!InConstantPool) 463 return; 464 InConstantPool = false; 465 OutStreamer->emitDataRegion(MCDR_DataRegionEnd); 466 } 467 468 void MipsAsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { 469 AsmPrinter::emitBasicBlockEnd(MBB); 470 MipsTargetStreamer &TS = getTargetStreamer(); 471 if (MBB.empty()) 472 TS.emitDirectiveInsn(); 473 } 474 475 /// isBlockOnlyReachableByFallthough - Return true if the basic block has 476 /// exactly one predecessor and the control transfer mechanism between 477 /// the predecessor and this block is a fall-through. 478 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 479 MBB) const { 480 // The predecessor has to be immediately before this block. 481 const MachineBasicBlock *Pred = *MBB->pred_begin(); 482 483 // If the predecessor is a switch statement, assume a jump table 484 // implementation, so it is not a fall through. 485 if (const BasicBlock *bb = Pred->getBasicBlock()) 486 if (isa<SwitchInst>(bb->getTerminator())) 487 return false; 488 489 // If this is a landing pad, it isn't a fall through. If it has no preds, 490 // then nothing falls through to it. 491 if (MBB->isEHPad() || MBB->pred_empty()) 492 return false; 493 494 // If there isn't exactly one predecessor, it can't be a fall through. 495 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 496 ++PI2; 497 498 if (PI2 != MBB->pred_end()) 499 return false; 500 501 // The predecessor has to be immediately before this block. 502 if (!Pred->isLayoutSuccessor(MBB)) 503 return false; 504 505 // If the block is completely empty, then it definitely does fall through. 506 if (Pred->empty()) 507 return true; 508 509 // Otherwise, check the last instruction. 510 // Check if the last terminator is an unconditional branch. 511 MachineBasicBlock::const_iterator I = Pred->end(); 512 while (I != Pred->begin() && !(--I)->isTerminator()) ; 513 514 return !I->isBarrier(); 515 } 516 517 // Print out an operand for an inline asm expression. 518 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 519 const char *ExtraCode, raw_ostream &O) { 520 // Does this asm operand have a single letter operand modifier? 521 if (ExtraCode && ExtraCode[0]) { 522 if (ExtraCode[1] != 0) return true; // Unknown modifier. 523 524 const MachineOperand &MO = MI->getOperand(OpNum); 525 switch (ExtraCode[0]) { 526 default: 527 // See if this is a generic print operand 528 return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O); 529 case 'X': // hex const int 530 if ((MO.getType()) != MachineOperand::MO_Immediate) 531 return true; 532 O << "0x" << Twine::utohexstr(MO.getImm()); 533 return false; 534 case 'x': // hex const int (low 16 bits) 535 if ((MO.getType()) != MachineOperand::MO_Immediate) 536 return true; 537 O << "0x" << Twine::utohexstr(MO.getImm() & 0xffff); 538 return false; 539 case 'd': // decimal const int 540 if ((MO.getType()) != MachineOperand::MO_Immediate) 541 return true; 542 O << MO.getImm(); 543 return false; 544 case 'm': // decimal const int minus 1 545 if ((MO.getType()) != MachineOperand::MO_Immediate) 546 return true; 547 O << MO.getImm() - 1; 548 return false; 549 case 'y': // exact log2 550 if ((MO.getType()) != MachineOperand::MO_Immediate) 551 return true; 552 if (!isPowerOf2_64(MO.getImm())) 553 return true; 554 O << Log2_64(MO.getImm()); 555 return false; 556 case 'z': 557 // $0 if zero, regular printing otherwise 558 if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) { 559 O << "$0"; 560 return false; 561 } 562 // If not, call printOperand as normal. 563 break; 564 case 'D': // Second part of a double word register operand 565 case 'L': // Low order register of a double word register operand 566 case 'M': // High order register of a double word register operand 567 { 568 if (OpNum == 0) 569 return true; 570 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 571 if (!FlagsOP.isImm()) 572 return true; 573 unsigned Flags = FlagsOP.getImm(); 574 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 575 // Number of registers represented by this operand. We are looking 576 // for 2 for 32 bit mode and 1 for 64 bit mode. 577 if (NumVals != 2) { 578 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 579 Register Reg = MO.getReg(); 580 O << '$' << MipsInstPrinter::getRegisterName(Reg); 581 return false; 582 } 583 return true; 584 } 585 586 unsigned RegOp = OpNum; 587 if (!Subtarget->isGP64bit()){ 588 // Endianness reverses which register holds the high or low value 589 // between M and L. 590 switch(ExtraCode[0]) { 591 case 'M': 592 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum; 593 break; 594 case 'L': 595 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1; 596 break; 597 case 'D': // Always the second part 598 RegOp = OpNum + 1; 599 } 600 if (RegOp >= MI->getNumOperands()) 601 return true; 602 const MachineOperand &MO = MI->getOperand(RegOp); 603 if (!MO.isReg()) 604 return true; 605 Register Reg = MO.getReg(); 606 O << '$' << MipsInstPrinter::getRegisterName(Reg); 607 return false; 608 } 609 break; 610 } 611 case 'w': 612 // Print MSA registers for the 'f' constraint 613 // In LLVM, the 'w' modifier doesn't need to do anything. 614 // We can just call printOperand as normal. 615 break; 616 } 617 } 618 619 printOperand(MI, OpNum, O); 620 return false; 621 } 622 623 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 624 unsigned OpNum, 625 const char *ExtraCode, 626 raw_ostream &O) { 627 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands"); 628 const MachineOperand &BaseMO = MI->getOperand(OpNum); 629 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1); 630 assert(BaseMO.isReg() && 631 "Unexpected base pointer for inline asm memory operand."); 632 assert(OffsetMO.isImm() && 633 "Unexpected offset for inline asm memory operand."); 634 int Offset = OffsetMO.getImm(); 635 636 // Currently we are expecting either no ExtraCode or 'D','M','L'. 637 if (ExtraCode) { 638 switch (ExtraCode[0]) { 639 case 'D': 640 Offset += 4; 641 break; 642 case 'M': 643 if (Subtarget->isLittle()) 644 Offset += 4; 645 break; 646 case 'L': 647 if (!Subtarget->isLittle()) 648 Offset += 4; 649 break; 650 default: 651 return true; // Unknown modifier. 652 } 653 } 654 655 O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg()) 656 << ")"; 657 658 return false; 659 } 660 661 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 662 raw_ostream &O) { 663 const MachineOperand &MO = MI->getOperand(opNum); 664 bool closeP = false; 665 666 if (MO.getTargetFlags()) 667 closeP = true; 668 669 switch(MO.getTargetFlags()) { 670 case MipsII::MO_GPREL: O << "%gp_rel("; break; 671 case MipsII::MO_GOT_CALL: O << "%call16("; break; 672 case MipsII::MO_GOT: O << "%got("; break; 673 case MipsII::MO_ABS_HI: O << "%hi("; break; 674 case MipsII::MO_ABS_LO: O << "%lo("; break; 675 case MipsII::MO_HIGHER: O << "%higher("; break; 676 case MipsII::MO_HIGHEST: O << "%highest(("; break; 677 case MipsII::MO_TLSGD: O << "%tlsgd("; break; 678 case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 679 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 680 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 681 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 682 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 683 case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 684 case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 685 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 686 } 687 688 switch (MO.getType()) { 689 case MachineOperand::MO_Register: 690 O << '$' 691 << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 692 break; 693 694 case MachineOperand::MO_Immediate: 695 O << MO.getImm(); 696 break; 697 698 case MachineOperand::MO_MachineBasicBlock: 699 MO.getMBB()->getSymbol()->print(O, MAI); 700 return; 701 702 case MachineOperand::MO_GlobalAddress: 703 PrintSymbolOperand(MO, O); 704 break; 705 706 case MachineOperand::MO_BlockAddress: { 707 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 708 O << BA->getName(); 709 break; 710 } 711 712 case MachineOperand::MO_ConstantPoolIndex: 713 O << getDataLayout().getPrivateGlobalPrefix() << "CPI" 714 << getFunctionNumber() << "_" << MO.getIndex(); 715 if (MO.getOffset()) 716 O << "+" << MO.getOffset(); 717 break; 718 719 default: 720 llvm_unreachable("<unknown operand type>"); 721 } 722 723 if (closeP) O << ")"; 724 } 725 726 void MipsAsmPrinter:: 727 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 728 // Load/Store memory operands -- imm($reg) 729 // If PIC target the target is loaded as the 730 // pattern lw $25,%call16($28) 731 732 // opNum can be invalid if instruction has reglist as operand. 733 // MemOperand is always last operand of instruction (base + offset). 734 switch (MI->getOpcode()) { 735 default: 736 break; 737 case Mips::SWM32_MM: 738 case Mips::LWM32_MM: 739 opNum = MI->getNumOperands() - 2; 740 break; 741 } 742 743 printOperand(MI, opNum+1, O); 744 O << "("; 745 printOperand(MI, opNum, O); 746 O << ")"; 747 } 748 749 void MipsAsmPrinter:: 750 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 751 // when using stack locations for not load/store instructions 752 // print the same way as all normal 3 operand instructions. 753 printOperand(MI, opNum, O); 754 O << ", "; 755 printOperand(MI, opNum+1, O); 756 } 757 758 void MipsAsmPrinter:: 759 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 760 const char *Modifier) { 761 const MachineOperand &MO = MI->getOperand(opNum); 762 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 763 } 764 765 void MipsAsmPrinter:: 766 printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) { 767 for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) { 768 if (i != opNum) O << ", "; 769 printOperand(MI, i, O); 770 } 771 } 772 773 void MipsAsmPrinter::emitStartOfAsmFile(Module &M) { 774 MipsTargetStreamer &TS = getTargetStreamer(); 775 776 // MipsTargetStreamer has an initialization order problem when emitting an 777 // object file directly (see MipsTargetELFStreamer for full details). Work 778 // around it by re-initializing the PIC state here. 779 TS.setPic(OutContext.getObjectFileInfo()->isPositionIndependent()); 780 781 // Compute MIPS architecture attributes based on the default subtarget 782 // that we'd have constructed. Module level directives aren't LTO 783 // clean anyhow. 784 // FIXME: For ifunc related functions we could iterate over and look 785 // for a feature string that doesn't match the default one. 786 const Triple &TT = TM.getTargetTriple(); 787 StringRef CPU = MIPS_MC::selectMipsCPU(TT, TM.getTargetCPU()); 788 StringRef FS = TM.getTargetFeatureString(); 789 const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM); 790 const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, None); 791 792 bool IsABICalls = STI.isABICalls(); 793 const MipsABIInfo &ABI = MTM.getABI(); 794 if (IsABICalls) { 795 TS.emitDirectiveAbiCalls(); 796 // FIXME: This condition should be a lot more complicated that it is here. 797 // Ideally it should test for properties of the ABI and not the ABI 798 // itself. 799 // For the moment, I'm only correcting enough to make MIPS-IV work. 800 if (!isPositionIndependent() && STI.hasSym32()) 801 TS.emitDirectiveOptionPic0(); 802 } 803 804 // Tell the assembler which ABI we are using 805 std::string SectionName = std::string(".mdebug.") + getCurrentABIString(); 806 OutStreamer->SwitchSection( 807 OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, 0)); 808 809 // NaN: At the moment we only support: 810 // 1. .nan legacy (default) 811 // 2. .nan 2008 812 STI.isNaN2008() ? TS.emitDirectiveNaN2008() 813 : TS.emitDirectiveNaNLegacy(); 814 815 // TODO: handle O64 ABI 816 817 TS.updateABIInfo(STI); 818 819 // We should always emit a '.module fp=...' but binutils 2.24 does not accept 820 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or 821 // -mfp64) and omit it otherwise. 822 if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) || 823 STI.useSoftFloat()) 824 TS.emitDirectiveModuleFP(); 825 826 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not 827 // accept it. We therefore emit it when it contradicts the default or an 828 // option has changed the default (i.e. FPXX) and omit it otherwise. 829 if (ABI.IsO32() && (!STI.useOddSPReg() || STI.isABI_FPXX())) 830 TS.emitDirectiveModuleOddSPReg(); 831 832 // Switch to the .text section. 833 OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); 834 } 835 836 void MipsAsmPrinter::emitInlineAsmStart() const { 837 MipsTargetStreamer &TS = getTargetStreamer(); 838 839 // GCC's choice of assembler options for inline assembly code ('at', 'macro' 840 // and 'reorder') is different from LLVM's choice for generated code ('noat', 841 // 'nomacro' and 'noreorder'). 842 // In order to maintain compatibility with inline assembly code which depends 843 // on GCC's assembler options being used, we have to switch to those options 844 // for the duration of the inline assembly block and then switch back. 845 TS.emitDirectiveSetPush(); 846 TS.emitDirectiveSetAt(); 847 TS.emitDirectiveSetMacro(); 848 TS.emitDirectiveSetReorder(); 849 OutStreamer->AddBlankLine(); 850 } 851 852 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 853 const MCSubtargetInfo *EndInfo) const { 854 OutStreamer->AddBlankLine(); 855 getTargetStreamer().emitDirectiveSetPop(); 856 } 857 858 void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) { 859 MCInst I; 860 I.setOpcode(Mips::JAL); 861 I.addOperand( 862 MCOperand::createExpr(MCSymbolRefExpr::create(Symbol, OutContext))); 863 OutStreamer->emitInstruction(I, STI); 864 } 865 866 void MipsAsmPrinter::EmitInstrReg(const MCSubtargetInfo &STI, unsigned Opcode, 867 unsigned Reg) { 868 MCInst I; 869 I.setOpcode(Opcode); 870 I.addOperand(MCOperand::createReg(Reg)); 871 OutStreamer->emitInstruction(I, STI); 872 } 873 874 void MipsAsmPrinter::EmitInstrRegReg(const MCSubtargetInfo &STI, 875 unsigned Opcode, unsigned Reg1, 876 unsigned Reg2) { 877 MCInst I; 878 // 879 // Because of the current td files for Mips32, the operands for MTC1 880 // appear backwards from their normal assembly order. It's not a trivial 881 // change to fix this in the td file so we adjust for it here. 882 // 883 if (Opcode == Mips::MTC1) { 884 unsigned Temp = Reg1; 885 Reg1 = Reg2; 886 Reg2 = Temp; 887 } 888 I.setOpcode(Opcode); 889 I.addOperand(MCOperand::createReg(Reg1)); 890 I.addOperand(MCOperand::createReg(Reg2)); 891 OutStreamer->emitInstruction(I, STI); 892 } 893 894 void MipsAsmPrinter::EmitInstrRegRegReg(const MCSubtargetInfo &STI, 895 unsigned Opcode, unsigned Reg1, 896 unsigned Reg2, unsigned Reg3) { 897 MCInst I; 898 I.setOpcode(Opcode); 899 I.addOperand(MCOperand::createReg(Reg1)); 900 I.addOperand(MCOperand::createReg(Reg2)); 901 I.addOperand(MCOperand::createReg(Reg3)); 902 OutStreamer->emitInstruction(I, STI); 903 } 904 905 void MipsAsmPrinter::EmitMovFPIntPair(const MCSubtargetInfo &STI, 906 unsigned MovOpc, unsigned Reg1, 907 unsigned Reg2, unsigned FPReg1, 908 unsigned FPReg2, bool LE) { 909 if (!LE) { 910 unsigned temp = Reg1; 911 Reg1 = Reg2; 912 Reg2 = temp; 913 } 914 EmitInstrRegReg(STI, MovOpc, Reg1, FPReg1); 915 EmitInstrRegReg(STI, MovOpc, Reg2, FPReg2); 916 } 917 918 void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI, 919 Mips16HardFloatInfo::FPParamVariant PV, 920 bool LE, bool ToFP) { 921 using namespace Mips16HardFloatInfo; 922 923 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1; 924 switch (PV) { 925 case FSig: 926 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12); 927 break; 928 case FFSig: 929 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE); 930 break; 931 case FDSig: 932 EmitInstrRegReg(STI, MovOpc, Mips::A0, Mips::F12); 933 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 934 break; 935 case DSig: 936 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 937 break; 938 case DDSig: 939 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 940 EmitMovFPIntPair(STI, MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 941 break; 942 case DFSig: 943 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 944 EmitInstrRegReg(STI, MovOpc, Mips::A2, Mips::F14); 945 break; 946 case NoSig: 947 return; 948 } 949 } 950 951 void MipsAsmPrinter::EmitSwapFPIntRetval( 952 const MCSubtargetInfo &STI, Mips16HardFloatInfo::FPReturnVariant RV, 953 bool LE) { 954 using namespace Mips16HardFloatInfo; 955 956 unsigned MovOpc = Mips::MFC1; 957 switch (RV) { 958 case FRet: 959 EmitInstrRegReg(STI, MovOpc, Mips::V0, Mips::F0); 960 break; 961 case DRet: 962 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 963 break; 964 case CFRet: 965 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 966 break; 967 case CDRet: 968 EmitMovFPIntPair(STI, MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 969 EmitMovFPIntPair(STI, MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE); 970 break; 971 case NoFPRet: 972 break; 973 } 974 } 975 976 void MipsAsmPrinter::EmitFPCallStub( 977 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) { 978 using namespace Mips16HardFloatInfo; 979 980 MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol)); 981 bool LE = getDataLayout().isLittleEndian(); 982 // Construct a local MCSubtargetInfo here. 983 // This is because the MachineFunction won't exist (but have not yet been 984 // freed) and since we're at the global level we can use the default 985 // constructed subtarget. 986 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( 987 TM.getTargetTriple().str(), TM.getTargetCPU(), 988 TM.getTargetFeatureString())); 989 990 // 991 // .global xxxx 992 // 993 OutStreamer->emitSymbolAttribute(MSymbol, MCSA_Global); 994 const char *RetType; 995 // 996 // make the comment field identifying the return and parameter 997 // types of the floating point stub 998 // # Stub function to call rettype xxxx (params) 999 // 1000 switch (Signature->RetSig) { 1001 case FRet: 1002 RetType = "float"; 1003 break; 1004 case DRet: 1005 RetType = "double"; 1006 break; 1007 case CFRet: 1008 RetType = "complex"; 1009 break; 1010 case CDRet: 1011 RetType = "double complex"; 1012 break; 1013 case NoFPRet: 1014 RetType = ""; 1015 break; 1016 } 1017 const char *Parms; 1018 switch (Signature->ParamSig) { 1019 case FSig: 1020 Parms = "float"; 1021 break; 1022 case FFSig: 1023 Parms = "float, float"; 1024 break; 1025 case FDSig: 1026 Parms = "float, double"; 1027 break; 1028 case DSig: 1029 Parms = "double"; 1030 break; 1031 case DDSig: 1032 Parms = "double, double"; 1033 break; 1034 case DFSig: 1035 Parms = "double, float"; 1036 break; 1037 case NoSig: 1038 Parms = ""; 1039 break; 1040 } 1041 OutStreamer->AddComment("\t# Stub function to call " + Twine(RetType) + " " + 1042 Twine(Symbol) + " (" + Twine(Parms) + ")"); 1043 // 1044 // probably not necessary but we save and restore the current section state 1045 // 1046 OutStreamer->PushSection(); 1047 // 1048 // .section mips16.call.fpxxxx,"ax",@progbits 1049 // 1050 MCSectionELF *M = OutContext.getELFSection( 1051 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS, 1052 ELF::SHF_ALLOC | ELF::SHF_EXECINSTR); 1053 OutStreamer->SwitchSection(M, nullptr); 1054 // 1055 // .align 2 1056 // 1057 OutStreamer->emitValueToAlignment(4); 1058 MipsTargetStreamer &TS = getTargetStreamer(); 1059 // 1060 // .set nomips16 1061 // .set nomicromips 1062 // 1063 TS.emitDirectiveSetNoMips16(); 1064 TS.emitDirectiveSetNoMicroMips(); 1065 // 1066 // .ent __call_stub_fp_xxxx 1067 // .type __call_stub_fp_xxxx,@function 1068 // __call_stub_fp_xxxx: 1069 // 1070 std::string x = "__call_stub_fp_" + std::string(Symbol); 1071 MCSymbolELF *Stub = 1072 cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x))); 1073 TS.emitDirectiveEnt(*Stub); 1074 MCSymbol *MType = 1075 OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol)); 1076 OutStreamer->emitSymbolAttribute(MType, MCSA_ELF_TypeFunction); 1077 OutStreamer->emitLabel(Stub); 1078 1079 // Only handle non-pic for now. 1080 assert(!isPositionIndependent() && 1081 "should not be here if we are compiling pic"); 1082 TS.emitDirectiveSetReorder(); 1083 // 1084 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement 1085 // stubs without raw text but this current patch is for compiler generated 1086 // functions and they all return some value. 1087 // The calling sequence for non pic is different in that case and we need 1088 // to implement %lo and %hi in order to handle the case of no return value 1089 // See the corresponding method in Mips16HardFloat for details. 1090 // 1091 // mov the return address to S2. 1092 // we have no stack space to store it and we are about to make another call. 1093 // We need to make sure that the enclosing function knows to save S2 1094 // This should have already been handled. 1095 // 1096 // Mov $18, $31 1097 1098 EmitInstrRegRegReg(*STI, Mips::OR, Mips::S2, Mips::RA, Mips::ZERO); 1099 1100 EmitSwapFPIntParams(*STI, Signature->ParamSig, LE, true); 1101 1102 // Jal xxxx 1103 // 1104 EmitJal(*STI, MSymbol); 1105 1106 // fix return values 1107 EmitSwapFPIntRetval(*STI, Signature->RetSig, LE); 1108 // 1109 // do the return 1110 // if (Signature->RetSig == NoFPRet) 1111 // llvm_unreachable("should not be any stubs here with no return value"); 1112 // else 1113 EmitInstrReg(*STI, Mips::JR, Mips::S2); 1114 1115 MCSymbol *Tmp = OutContext.createTempSymbol(); 1116 OutStreamer->emitLabel(Tmp); 1117 const MCSymbolRefExpr *E = MCSymbolRefExpr::create(Stub, OutContext); 1118 const MCSymbolRefExpr *T = MCSymbolRefExpr::create(Tmp, OutContext); 1119 const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext); 1120 OutStreamer->emitELFSize(Stub, T_min_E); 1121 TS.emitDirectiveEnd(x); 1122 OutStreamer->PopSection(); 1123 } 1124 1125 void MipsAsmPrinter::emitEndOfAsmFile(Module &M) { 1126 // Emit needed stubs 1127 // 1128 for (std::map< 1129 const char *, 1130 const Mips16HardFloatInfo::FuncSignature *>::const_iterator 1131 it = StubsNeeded.begin(); 1132 it != StubsNeeded.end(); ++it) { 1133 const char *Symbol = it->first; 1134 const Mips16HardFloatInfo::FuncSignature *Signature = it->second; 1135 EmitFPCallStub(Symbol, Signature); 1136 } 1137 // return to the text section 1138 OutStreamer->SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); 1139 } 1140 1141 void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) { 1142 const uint8_t NoopsInSledCount = Subtarget->isGP64bit() ? 15 : 11; 1143 // For mips32 we want to emit the following pattern: 1144 // 1145 // .Lxray_sled_N: 1146 // ALIGN 1147 // B .tmpN 1148 // 11 NOP instructions (44 bytes) 1149 // ADDIU T9, T9, 52 1150 // .tmpN 1151 // 1152 // We need the 44 bytes (11 instructions) because at runtime, we'd 1153 // be patching over the full 48 bytes (12 instructions) with the following 1154 // pattern: 1155 // 1156 // ADDIU SP, SP, -8 1157 // NOP 1158 // SW RA, 4(SP) 1159 // SW T9, 0(SP) 1160 // LUI T9, %hi(__xray_FunctionEntry/Exit) 1161 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit) 1162 // LUI T0, %hi(function_id) 1163 // JALR T9 1164 // ORI T0, T0, %lo(function_id) 1165 // LW T9, 0(SP) 1166 // LW RA, 4(SP) 1167 // ADDIU SP, SP, 8 1168 // 1169 // We add 52 bytes to t9 because we want to adjust the function pointer to 1170 // the actual start of function i.e. the address just after the noop sled. 1171 // We do this because gp displacement relocation is emitted at the start of 1172 // of the function i.e after the nop sled and to correctly calculate the 1173 // global offset table address, t9 must hold the address of the instruction 1174 // containing the gp displacement relocation. 1175 // FIXME: Is this correct for the static relocation model? 1176 // 1177 // For mips64 we want to emit the following pattern: 1178 // 1179 // .Lxray_sled_N: 1180 // ALIGN 1181 // B .tmpN 1182 // 15 NOP instructions (60 bytes) 1183 // .tmpN 1184 // 1185 // We need the 60 bytes (15 instructions) because at runtime, we'd 1186 // be patching over the full 64 bytes (16 instructions) with the following 1187 // pattern: 1188 // 1189 // DADDIU SP, SP, -16 1190 // NOP 1191 // SD RA, 8(SP) 1192 // SD T9, 0(SP) 1193 // LUI T9, %highest(__xray_FunctionEntry/Exit) 1194 // ORI T9, T9, %higher(__xray_FunctionEntry/Exit) 1195 // DSLL T9, T9, 16 1196 // ORI T9, T9, %hi(__xray_FunctionEntry/Exit) 1197 // DSLL T9, T9, 16 1198 // ORI T9, T9, %lo(__xray_FunctionEntry/Exit) 1199 // LUI T0, %hi(function_id) 1200 // JALR T9 1201 // ADDIU T0, T0, %lo(function_id) 1202 // LD T9, 0(SP) 1203 // LD RA, 8(SP) 1204 // DADDIU SP, SP, 16 1205 // 1206 OutStreamer->emitCodeAlignment(4); 1207 auto CurSled = OutContext.createTempSymbol("xray_sled_", true); 1208 OutStreamer->emitLabel(CurSled); 1209 auto Target = OutContext.createTempSymbol(); 1210 1211 // Emit "B .tmpN" instruction, which jumps over the nop sled to the actual 1212 // start of function 1213 const MCExpr *TargetExpr = MCSymbolRefExpr::create( 1214 Target, MCSymbolRefExpr::VariantKind::VK_None, OutContext); 1215 EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BEQ) 1216 .addReg(Mips::ZERO) 1217 .addReg(Mips::ZERO) 1218 .addExpr(TargetExpr)); 1219 1220 for (int8_t I = 0; I < NoopsInSledCount; I++) 1221 EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL) 1222 .addReg(Mips::ZERO) 1223 .addReg(Mips::ZERO) 1224 .addImm(0)); 1225 1226 OutStreamer->emitLabel(Target); 1227 1228 if (!Subtarget->isGP64bit()) { 1229 EmitToStreamer(*OutStreamer, 1230 MCInstBuilder(Mips::ADDiu) 1231 .addReg(Mips::T9) 1232 .addReg(Mips::T9) 1233 .addImm(0x34)); 1234 } 1235 1236 recordSled(CurSled, MI, Kind); 1237 } 1238 1239 void MipsAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI) { 1240 EmitSled(MI, SledKind::FUNCTION_ENTER); 1241 } 1242 1243 void MipsAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) { 1244 EmitSled(MI, SledKind::FUNCTION_EXIT); 1245 } 1246 1247 void MipsAsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) { 1248 EmitSled(MI, SledKind::TAIL_CALL); 1249 } 1250 1251 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 1252 raw_ostream &OS) { 1253 // TODO: implement 1254 } 1255 1256 // Emit .dtprelword or .dtpreldword directive 1257 // and value for debug thread local expression. 1258 void MipsAsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const { 1259 if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) { 1260 if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) { 1261 switch (Size) { 1262 case 4: 1263 OutStreamer->emitDTPRel32Value(MipsExpr->getSubExpr()); 1264 break; 1265 case 8: 1266 OutStreamer->emitDTPRel64Value(MipsExpr->getSubExpr()); 1267 break; 1268 default: 1269 llvm_unreachable("Unexpected size of expression value."); 1270 } 1271 return; 1272 } 1273 } 1274 AsmPrinter::emitDebugValue(Value, Size); 1275 } 1276 1277 // Align all targets of indirect branches on bundle size. Used only if target 1278 // is NaCl. 1279 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) { 1280 // Align all blocks that are jumped to through jump table. 1281 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) { 1282 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables(); 1283 for (unsigned I = 0; I < JT.size(); ++I) { 1284 const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs; 1285 1286 for (unsigned J = 0; J < MBBs.size(); ++J) 1287 MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 1288 } 1289 } 1290 1291 // If basic block address is taken, block can be target of indirect branch. 1292 for (auto &MBB : MF) { 1293 if (MBB.hasAddressTaken()) 1294 MBB.setAlignment(MIPS_NACL_BUNDLE_ALIGN); 1295 } 1296 } 1297 1298 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const { 1299 return (Opcode == Mips::LONG_BRANCH_LUi 1300 || Opcode == Mips::LONG_BRANCH_LUi2Op 1301 || Opcode == Mips::LONG_BRANCH_LUi2Op_64 1302 || Opcode == Mips::LONG_BRANCH_ADDiu 1303 || Opcode == Mips::LONG_BRANCH_ADDiu2Op 1304 || Opcode == Mips::LONG_BRANCH_DADDiu 1305 || Opcode == Mips::LONG_BRANCH_DADDiu2Op); 1306 } 1307 1308 // Force static initialization. 1309 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmPrinter() { 1310 RegisterAsmPrinter<MipsAsmPrinter> X(getTheMipsTarget()); 1311 RegisterAsmPrinter<MipsAsmPrinter> Y(getTheMipselTarget()); 1312 RegisterAsmPrinter<MipsAsmPrinter> A(getTheMips64Target()); 1313 RegisterAsmPrinter<MipsAsmPrinter> B(getTheMips64elTarget()); 1314 } 1315