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