1 //===-- SystemZAsmPrinter.cpp - SystemZ 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 // Streams SystemZ assembly language and associated data, in the form of 10 // MCInsts and MCExprs respectively. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "SystemZAsmPrinter.h" 15 #include "MCTargetDesc/SystemZInstPrinter.h" 16 #include "SystemZConstantPoolValue.h" 17 #include "SystemZMCInstLower.h" 18 #include "TargetInfo/SystemZTargetInfo.h" 19 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 20 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 21 #include "llvm/IR/Mangler.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInstBuilder.h" 24 #include "llvm/MC/MCStreamer.h" 25 #include "llvm/Support/TargetRegistry.h" 26 27 using namespace llvm; 28 29 // Return an RI instruction like MI with opcode Opcode, but with the 30 // GR64 register operands turned into GR32s. 31 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 32 if (MI->isCompare()) 33 return MCInstBuilder(Opcode) 34 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 35 .addImm(MI->getOperand(1).getImm()); 36 else 37 return MCInstBuilder(Opcode) 38 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 39 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 40 .addImm(MI->getOperand(2).getImm()); 41 } 42 43 // Return an RI instruction like MI with opcode Opcode, but with the 44 // GR64 register operands turned into GRH32s. 45 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 46 if (MI->isCompare()) 47 return MCInstBuilder(Opcode) 48 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 49 .addImm(MI->getOperand(1).getImm()); 50 else 51 return MCInstBuilder(Opcode) 52 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 53 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 54 .addImm(MI->getOperand(2).getImm()); 55 } 56 57 // Return an RI instruction like MI with opcode Opcode, but with the 58 // R2 register turned into a GR64. 59 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 60 return MCInstBuilder(Opcode) 61 .addReg(MI->getOperand(0).getReg()) 62 .addReg(MI->getOperand(1).getReg()) 63 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 64 .addImm(MI->getOperand(3).getImm()) 65 .addImm(MI->getOperand(4).getImm()) 66 .addImm(MI->getOperand(5).getImm()); 67 } 68 69 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { 70 StringRef Name = "__tls_get_offset"; 71 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 72 MCSymbolRefExpr::VK_PLT, 73 Context); 74 } 75 76 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { 77 StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 78 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 79 MCSymbolRefExpr::VK_None, 80 Context); 81 } 82 83 // MI is an instruction that accepts an optional alignment hint, 84 // and which was already lowered to LoweredMI. If the alignment 85 // of the original memory operand is known, update LoweredMI to 86 // an instruction with the corresponding hint set. 87 static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, 88 unsigned Opcode) { 89 if (!MI->hasOneMemOperand()) 90 return; 91 const MachineMemOperand *MMO = *MI->memoperands_begin(); 92 unsigned AlignmentHint = 0; 93 if (MMO->getAlignment() >= 16) 94 AlignmentHint = 4; 95 else if (MMO->getAlignment() >= 8) 96 AlignmentHint = 3; 97 if (AlignmentHint == 0) 98 return; 99 100 LoweredMI.setOpcode(Opcode); 101 LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); 102 } 103 104 // MI loads the high part of a vector from memory. Return an instruction 105 // that uses replicating vector load Opcode to do the same thing. 106 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { 107 return MCInstBuilder(Opcode) 108 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 109 .addReg(MI->getOperand(1).getReg()) 110 .addImm(MI->getOperand(2).getImm()) 111 .addReg(MI->getOperand(3).getReg()); 112 } 113 114 // MI stores the high part of a vector to memory. Return an instruction 115 // that uses elemental vector store Opcode to do the same thing. 116 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { 117 return MCInstBuilder(Opcode) 118 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 119 .addReg(MI->getOperand(1).getReg()) 120 .addImm(MI->getOperand(2).getImm()) 121 .addReg(MI->getOperand(3).getReg()) 122 .addImm(0); 123 } 124 125 void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { 126 SystemZMCInstLower Lower(MF->getContext(), *this); 127 MCInst LoweredMI; 128 switch (MI->getOpcode()) { 129 case SystemZ::Return: 130 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 131 break; 132 133 case SystemZ::CondReturn: 134 LoweredMI = MCInstBuilder(SystemZ::BCR) 135 .addImm(MI->getOperand(0).getImm()) 136 .addImm(MI->getOperand(1).getImm()) 137 .addReg(SystemZ::R14D); 138 break; 139 140 case SystemZ::CRBReturn: 141 LoweredMI = MCInstBuilder(SystemZ::CRB) 142 .addReg(MI->getOperand(0).getReg()) 143 .addReg(MI->getOperand(1).getReg()) 144 .addImm(MI->getOperand(2).getImm()) 145 .addReg(SystemZ::R14D) 146 .addImm(0); 147 break; 148 149 case SystemZ::CGRBReturn: 150 LoweredMI = MCInstBuilder(SystemZ::CGRB) 151 .addReg(MI->getOperand(0).getReg()) 152 .addReg(MI->getOperand(1).getReg()) 153 .addImm(MI->getOperand(2).getImm()) 154 .addReg(SystemZ::R14D) 155 .addImm(0); 156 break; 157 158 case SystemZ::CIBReturn: 159 LoweredMI = MCInstBuilder(SystemZ::CIB) 160 .addReg(MI->getOperand(0).getReg()) 161 .addImm(MI->getOperand(1).getImm()) 162 .addImm(MI->getOperand(2).getImm()) 163 .addReg(SystemZ::R14D) 164 .addImm(0); 165 break; 166 167 case SystemZ::CGIBReturn: 168 LoweredMI = MCInstBuilder(SystemZ::CGIB) 169 .addReg(MI->getOperand(0).getReg()) 170 .addImm(MI->getOperand(1).getImm()) 171 .addImm(MI->getOperand(2).getImm()) 172 .addReg(SystemZ::R14D) 173 .addImm(0); 174 break; 175 176 case SystemZ::CLRBReturn: 177 LoweredMI = MCInstBuilder(SystemZ::CLRB) 178 .addReg(MI->getOperand(0).getReg()) 179 .addReg(MI->getOperand(1).getReg()) 180 .addImm(MI->getOperand(2).getImm()) 181 .addReg(SystemZ::R14D) 182 .addImm(0); 183 break; 184 185 case SystemZ::CLGRBReturn: 186 LoweredMI = MCInstBuilder(SystemZ::CLGRB) 187 .addReg(MI->getOperand(0).getReg()) 188 .addReg(MI->getOperand(1).getReg()) 189 .addImm(MI->getOperand(2).getImm()) 190 .addReg(SystemZ::R14D) 191 .addImm(0); 192 break; 193 194 case SystemZ::CLIBReturn: 195 LoweredMI = MCInstBuilder(SystemZ::CLIB) 196 .addReg(MI->getOperand(0).getReg()) 197 .addImm(MI->getOperand(1).getImm()) 198 .addImm(MI->getOperand(2).getImm()) 199 .addReg(SystemZ::R14D) 200 .addImm(0); 201 break; 202 203 case SystemZ::CLGIBReturn: 204 LoweredMI = MCInstBuilder(SystemZ::CLGIB) 205 .addReg(MI->getOperand(0).getReg()) 206 .addImm(MI->getOperand(1).getImm()) 207 .addImm(MI->getOperand(2).getImm()) 208 .addReg(SystemZ::R14D) 209 .addImm(0); 210 break; 211 212 case SystemZ::CallBRASL: 213 LoweredMI = MCInstBuilder(SystemZ::BRASL) 214 .addReg(SystemZ::R14D) 215 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 216 break; 217 218 case SystemZ::CallBASR: 219 LoweredMI = MCInstBuilder(SystemZ::BASR) 220 .addReg(SystemZ::R14D) 221 .addReg(MI->getOperand(0).getReg()); 222 break; 223 224 case SystemZ::CallJG: 225 LoweredMI = MCInstBuilder(SystemZ::JG) 226 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 227 break; 228 229 case SystemZ::CallBRCL: 230 LoweredMI = MCInstBuilder(SystemZ::BRCL) 231 .addImm(MI->getOperand(0).getImm()) 232 .addImm(MI->getOperand(1).getImm()) 233 .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 234 break; 235 236 case SystemZ::CallBR: 237 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); 238 break; 239 240 case SystemZ::CallBCR: 241 LoweredMI = MCInstBuilder(SystemZ::BCR) 242 .addImm(MI->getOperand(0).getImm()) 243 .addImm(MI->getOperand(1).getImm()) 244 .addReg(SystemZ::R1D); 245 break; 246 247 case SystemZ::CRBCall: 248 LoweredMI = MCInstBuilder(SystemZ::CRB) 249 .addReg(MI->getOperand(0).getReg()) 250 .addReg(MI->getOperand(1).getReg()) 251 .addImm(MI->getOperand(2).getImm()) 252 .addReg(SystemZ::R1D) 253 .addImm(0); 254 break; 255 256 case SystemZ::CGRBCall: 257 LoweredMI = MCInstBuilder(SystemZ::CGRB) 258 .addReg(MI->getOperand(0).getReg()) 259 .addReg(MI->getOperand(1).getReg()) 260 .addImm(MI->getOperand(2).getImm()) 261 .addReg(SystemZ::R1D) 262 .addImm(0); 263 break; 264 265 case SystemZ::CIBCall: 266 LoweredMI = MCInstBuilder(SystemZ::CIB) 267 .addReg(MI->getOperand(0).getReg()) 268 .addImm(MI->getOperand(1).getImm()) 269 .addImm(MI->getOperand(2).getImm()) 270 .addReg(SystemZ::R1D) 271 .addImm(0); 272 break; 273 274 case SystemZ::CGIBCall: 275 LoweredMI = MCInstBuilder(SystemZ::CGIB) 276 .addReg(MI->getOperand(0).getReg()) 277 .addImm(MI->getOperand(1).getImm()) 278 .addImm(MI->getOperand(2).getImm()) 279 .addReg(SystemZ::R1D) 280 .addImm(0); 281 break; 282 283 case SystemZ::CLRBCall: 284 LoweredMI = MCInstBuilder(SystemZ::CLRB) 285 .addReg(MI->getOperand(0).getReg()) 286 .addReg(MI->getOperand(1).getReg()) 287 .addImm(MI->getOperand(2).getImm()) 288 .addReg(SystemZ::R1D) 289 .addImm(0); 290 break; 291 292 case SystemZ::CLGRBCall: 293 LoweredMI = MCInstBuilder(SystemZ::CLGRB) 294 .addReg(MI->getOperand(0).getReg()) 295 .addReg(MI->getOperand(1).getReg()) 296 .addImm(MI->getOperand(2).getImm()) 297 .addReg(SystemZ::R1D) 298 .addImm(0); 299 break; 300 301 case SystemZ::CLIBCall: 302 LoweredMI = MCInstBuilder(SystemZ::CLIB) 303 .addReg(MI->getOperand(0).getReg()) 304 .addImm(MI->getOperand(1).getImm()) 305 .addImm(MI->getOperand(2).getImm()) 306 .addReg(SystemZ::R1D) 307 .addImm(0); 308 break; 309 310 case SystemZ::CLGIBCall: 311 LoweredMI = MCInstBuilder(SystemZ::CLGIB) 312 .addReg(MI->getOperand(0).getReg()) 313 .addImm(MI->getOperand(1).getImm()) 314 .addImm(MI->getOperand(2).getImm()) 315 .addReg(SystemZ::R1D) 316 .addImm(0); 317 break; 318 319 case SystemZ::TLS_GDCALL: 320 LoweredMI = MCInstBuilder(SystemZ::BRASL) 321 .addReg(SystemZ::R14D) 322 .addExpr(getTLSGetOffset(MF->getContext())) 323 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 324 break; 325 326 case SystemZ::TLS_LDCALL: 327 LoweredMI = MCInstBuilder(SystemZ::BRASL) 328 .addReg(SystemZ::R14D) 329 .addExpr(getTLSGetOffset(MF->getContext())) 330 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 331 break; 332 333 case SystemZ::GOT: 334 LoweredMI = MCInstBuilder(SystemZ::LARL) 335 .addReg(MI->getOperand(0).getReg()) 336 .addExpr(getGlobalOffsetTable(MF->getContext())); 337 break; 338 339 case SystemZ::IILF64: 340 LoweredMI = MCInstBuilder(SystemZ::IILF) 341 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 342 .addImm(MI->getOperand(2).getImm()); 343 break; 344 345 case SystemZ::IIHF64: 346 LoweredMI = MCInstBuilder(SystemZ::IIHF) 347 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 348 .addImm(MI->getOperand(2).getImm()); 349 break; 350 351 case SystemZ::RISBHH: 352 case SystemZ::RISBHL: 353 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 354 break; 355 356 case SystemZ::RISBLH: 357 case SystemZ::RISBLL: 358 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 359 break; 360 361 case SystemZ::VLVGP32: 362 LoweredMI = MCInstBuilder(SystemZ::VLVGP) 363 .addReg(MI->getOperand(0).getReg()) 364 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 365 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 366 break; 367 368 case SystemZ::VLR32: 369 case SystemZ::VLR64: 370 LoweredMI = MCInstBuilder(SystemZ::VLR) 371 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 372 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 373 break; 374 375 case SystemZ::VL: 376 Lower.lower(MI, LoweredMI); 377 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 378 break; 379 380 case SystemZ::VST: 381 Lower.lower(MI, LoweredMI); 382 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 383 break; 384 385 case SystemZ::VLM: 386 Lower.lower(MI, LoweredMI); 387 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 388 break; 389 390 case SystemZ::VSTM: 391 Lower.lower(MI, LoweredMI); 392 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 393 break; 394 395 case SystemZ::VL32: 396 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 397 break; 398 399 case SystemZ::VL64: 400 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 401 break; 402 403 case SystemZ::VST32: 404 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 405 break; 406 407 case SystemZ::VST64: 408 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 409 break; 410 411 case SystemZ::LFER: 412 LoweredMI = MCInstBuilder(SystemZ::VLGVF) 413 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 414 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 415 .addReg(0).addImm(0); 416 break; 417 418 case SystemZ::LEFR: 419 LoweredMI = MCInstBuilder(SystemZ::VLVGF) 420 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 421 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 422 .addReg(MI->getOperand(1).getReg()) 423 .addReg(0).addImm(0); 424 break; 425 426 #define LOWER_LOW(NAME) \ 427 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 428 429 LOWER_LOW(IILL); 430 LOWER_LOW(IILH); 431 LOWER_LOW(TMLL); 432 LOWER_LOW(TMLH); 433 LOWER_LOW(NILL); 434 LOWER_LOW(NILH); 435 LOWER_LOW(NILF); 436 LOWER_LOW(OILL); 437 LOWER_LOW(OILH); 438 LOWER_LOW(OILF); 439 LOWER_LOW(XILF); 440 441 #undef LOWER_LOW 442 443 #define LOWER_HIGH(NAME) \ 444 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 445 446 LOWER_HIGH(IIHL); 447 LOWER_HIGH(IIHH); 448 LOWER_HIGH(TMHL); 449 LOWER_HIGH(TMHH); 450 LOWER_HIGH(NIHL); 451 LOWER_HIGH(NIHH); 452 LOWER_HIGH(NIHF); 453 LOWER_HIGH(OIHL); 454 LOWER_HIGH(OIHH); 455 LOWER_HIGH(OIHF); 456 LOWER_HIGH(XIHF); 457 458 #undef LOWER_HIGH 459 460 case SystemZ::Serialize: 461 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 462 LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 463 .addImm(14).addReg(SystemZ::R0D); 464 else 465 LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 466 .addImm(15).addReg(SystemZ::R0D); 467 break; 468 469 // Emit nothing here but a comment if we can. 470 case SystemZ::MemBarrier: 471 OutStreamer->emitRawComment("MEMBARRIER"); 472 return; 473 474 // We want to emit "j .+2" for traps, jumping to the relative immediate field 475 // of the jump instruction, which is an illegal instruction. We cannot emit a 476 // "." symbol, so create and emit a temp label before the instruction and use 477 // that instead. 478 case SystemZ::Trap: { 479 MCSymbol *DotSym = OutContext.createTempSymbol(); 480 OutStreamer->EmitLabel(DotSym); 481 482 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 483 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 484 LoweredMI = MCInstBuilder(SystemZ::J) 485 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 486 } 487 break; 488 489 // Conditional traps will create a branch on condition instruction that jumps 490 // to the relative immediate field of the jump instruction. (eg. "jo .+2") 491 case SystemZ::CondTrap: { 492 MCSymbol *DotSym = OutContext.createTempSymbol(); 493 OutStreamer->EmitLabel(DotSym); 494 495 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 496 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 497 LoweredMI = MCInstBuilder(SystemZ::BRC) 498 .addImm(MI->getOperand(0).getImm()) 499 .addImm(MI->getOperand(1).getImm()) 500 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 501 } 502 break; 503 504 case TargetOpcode::STACKMAP: 505 LowerSTACKMAP(*MI); 506 return; 507 508 case TargetOpcode::PATCHPOINT: 509 LowerPATCHPOINT(*MI, Lower); 510 return; 511 512 default: 513 Lower.lower(MI, LoweredMI); 514 break; 515 } 516 EmitToStreamer(*OutStreamer, LoweredMI); 517 } 518 519 520 // Emit the largest nop instruction smaller than or equal to NumBytes 521 // bytes. Return the size of nop emitted. 522 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 523 unsigned NumBytes, const MCSubtargetInfo &STI) { 524 if (NumBytes < 2) { 525 llvm_unreachable("Zero nops?"); 526 return 0; 527 } 528 else if (NumBytes < 4) { 529 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm) 530 .addImm(0).addReg(SystemZ::R0D), STI); 531 return 2; 532 } 533 else if (NumBytes < 6) { 534 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm) 535 .addImm(0).addReg(0).addImm(0).addReg(0), 536 STI); 537 return 4; 538 } 539 else { 540 MCSymbol *DotSym = OutContext.createTempSymbol(); 541 const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 542 OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm) 543 .addImm(0).addExpr(Dot), STI); 544 OutStreamer.EmitLabel(DotSym); 545 return 6; 546 } 547 } 548 549 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 550 const SystemZInstrInfo *TII = 551 static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 552 553 unsigned NumNOPBytes = MI.getOperand(1).getImm(); 554 555 SM.recordStackMap(MI); 556 assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 557 558 // Scan ahead to trim the shadow. 559 unsigned ShadowBytes = 0; 560 const MachineBasicBlock &MBB = *MI.getParent(); 561 MachineBasicBlock::const_iterator MII(MI); 562 ++MII; 563 while (ShadowBytes < NumNOPBytes) { 564 if (MII == MBB.end() || 565 MII->getOpcode() == TargetOpcode::PATCHPOINT || 566 MII->getOpcode() == TargetOpcode::STACKMAP) 567 break; 568 ShadowBytes += TII->getInstSizeInBytes(*MII); 569 if (MII->isCall()) 570 break; 571 ++MII; 572 } 573 574 // Emit nops. 575 while (ShadowBytes < NumNOPBytes) 576 ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 577 getSubtargetInfo()); 578 } 579 580 // Lower a patchpoint of the form: 581 // [<def>], <id>, <numBytes>, <target>, <numArgs> 582 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 583 SystemZMCInstLower &Lower) { 584 SM.recordPatchPoint(MI); 585 PatchPointOpers Opers(&MI); 586 587 unsigned EncodedBytes = 0; 588 const MachineOperand &CalleeMO = Opers.getCallTarget(); 589 590 if (CalleeMO.isImm()) { 591 uint64_t CallTarget = CalleeMO.getImm(); 592 if (CallTarget) { 593 unsigned ScratchIdx = -1; 594 unsigned ScratchReg = 0; 595 do { 596 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 597 ScratchReg = MI.getOperand(ScratchIdx).getReg(); 598 } while (ScratchReg == SystemZ::R0D); 599 600 // Materialize the call target address 601 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 602 .addReg(ScratchReg) 603 .addImm(CallTarget & 0xFFFFFFFF)); 604 EncodedBytes += 6; 605 if (CallTarget >> 32) { 606 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 607 .addReg(ScratchReg) 608 .addImm(CallTarget >> 32)); 609 EncodedBytes += 6; 610 } 611 612 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 613 .addReg(SystemZ::R14D) 614 .addReg(ScratchReg)); 615 EncodedBytes += 2; 616 } 617 } else if (CalleeMO.isGlobal()) { 618 const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 619 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 620 .addReg(SystemZ::R14D) 621 .addExpr(Expr)); 622 EncodedBytes += 6; 623 } 624 625 // Emit padding. 626 unsigned NumBytes = Opers.getNumPatchBytes(); 627 assert(NumBytes >= EncodedBytes && 628 "Patchpoint can't request size less than the length of a call."); 629 assert((NumBytes - EncodedBytes) % 2 == 0 && 630 "Invalid number of NOP bytes requested!"); 631 while (EncodedBytes < NumBytes) 632 EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 633 getSubtargetInfo()); 634 } 635 636 // Convert a SystemZ-specific constant pool modifier into the associated 637 // MCSymbolRefExpr variant kind. 638 static MCSymbolRefExpr::VariantKind 639 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 640 switch (Modifier) { 641 case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 642 case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 643 case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 644 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 645 } 646 llvm_unreachable("Invalid SystemCPModifier!"); 647 } 648 649 void SystemZAsmPrinter:: 650 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 651 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 652 653 const MCExpr *Expr = 654 MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 655 getModifierVariantKind(ZCPV->getModifier()), 656 OutContext); 657 uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 658 659 OutStreamer->EmitValue(Expr, Size); 660 } 661 662 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 663 const char *ExtraCode, 664 raw_ostream &OS) { 665 if (ExtraCode) 666 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 667 SystemZMCInstLower Lower(MF->getContext(), *this); 668 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 669 SystemZInstPrinter::printOperand(MO, MAI, OS); 670 return false; 671 } 672 673 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 674 unsigned OpNo, 675 const char *ExtraCode, 676 raw_ostream &OS) { 677 SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 678 MI->getOperand(OpNo + 1).getImm(), 679 MI->getOperand(OpNo + 2).getReg(), OS); 680 return false; 681 } 682 683 void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) { 684 emitStackMaps(SM); 685 } 686 687 // Force static initialization. 688 extern "C" void LLVMInitializeSystemZAsmPrinter() { 689 RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 690 } 691