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