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