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/BinaryFormat/ELF.h" 20 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 21 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 22 #include "llvm/IR/Mangler.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCInstBuilder.h" 25 #include "llvm/MC/MCSectionELF.h" 26 #include "llvm/MC/MCStreamer.h" 27 #include "llvm/MC/TargetRegistry.h" 28 29 using namespace llvm; 30 31 // Return an RI instruction like MI with opcode Opcode, but with the 32 // GR64 register operands turned into GR32s. 33 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 34 if (MI->isCompare()) 35 return MCInstBuilder(Opcode) 36 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 37 .addImm(MI->getOperand(1).getImm()); 38 else 39 return MCInstBuilder(Opcode) 40 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 41 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 42 .addImm(MI->getOperand(2).getImm()); 43 } 44 45 // Return an RI instruction like MI with opcode Opcode, but with the 46 // GR64 register operands turned into GRH32s. 47 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 48 if (MI->isCompare()) 49 return MCInstBuilder(Opcode) 50 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 51 .addImm(MI->getOperand(1).getImm()); 52 else 53 return MCInstBuilder(Opcode) 54 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 55 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 56 .addImm(MI->getOperand(2).getImm()); 57 } 58 59 // Return an RI instruction like MI with opcode Opcode, but with the 60 // R2 register turned into a GR64. 61 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 62 return MCInstBuilder(Opcode) 63 .addReg(MI->getOperand(0).getReg()) 64 .addReg(MI->getOperand(1).getReg()) 65 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 66 .addImm(MI->getOperand(3).getImm()) 67 .addImm(MI->getOperand(4).getImm()) 68 .addImm(MI->getOperand(5).getImm()); 69 } 70 71 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { 72 StringRef Name = "__tls_get_offset"; 73 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 74 MCSymbolRefExpr::VK_PLT, 75 Context); 76 } 77 78 static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { 79 StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 80 return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 81 MCSymbolRefExpr::VK_None, 82 Context); 83 } 84 85 // MI is an instruction that accepts an optional alignment hint, 86 // and which was already lowered to LoweredMI. If the alignment 87 // of the original memory operand is known, update LoweredMI to 88 // an instruction with the corresponding hint set. 89 static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, 90 unsigned Opcode) { 91 if (MI->memoperands_empty()) 92 return; 93 94 Align Alignment = Align(16); 95 for (MachineInstr::mmo_iterator MMOI = MI->memoperands_begin(), 96 EE = MI->memoperands_end(); MMOI != EE; ++MMOI) 97 if ((*MMOI)->getAlign() < Alignment) 98 Alignment = (*MMOI)->getAlign(); 99 100 unsigned AlignmentHint = 0; 101 if (Alignment >= Align(16)) 102 AlignmentHint = 4; 103 else if (Alignment >= Align(8)) 104 AlignmentHint = 3; 105 if (AlignmentHint == 0) 106 return; 107 108 LoweredMI.setOpcode(Opcode); 109 LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); 110 } 111 112 // MI loads the high part of a vector from memory. Return an instruction 113 // that uses replicating vector load Opcode to do the same thing. 114 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { 115 return MCInstBuilder(Opcode) 116 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 117 .addReg(MI->getOperand(1).getReg()) 118 .addImm(MI->getOperand(2).getImm()) 119 .addReg(MI->getOperand(3).getReg()); 120 } 121 122 // MI stores the high part of a vector to memory. Return an instruction 123 // that uses elemental vector store Opcode to do the same thing. 124 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { 125 return MCInstBuilder(Opcode) 126 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 127 .addReg(MI->getOperand(1).getReg()) 128 .addImm(MI->getOperand(2).getImm()) 129 .addReg(MI->getOperand(3).getReg()) 130 .addImm(0); 131 } 132 133 // The XPLINK ABI requires that a no-op encoding the call type is emitted after 134 // each call to a subroutine. This information can be used by the called 135 // function to determine its entry point, e.g. for generating a backtrace. The 136 // call type is encoded as a register number in the bcr instruction. See 137 // enumeration CallType for the possible values. 138 void SystemZAsmPrinter::emitCallInformation(CallType CT) { 139 EmitToStreamer(*OutStreamer, 140 MCInstBuilder(SystemZ::BCRAsm) 141 .addImm(0) 142 .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)])); 143 } 144 145 void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { 146 SystemZMCInstLower Lower(MF->getContext(), *this); 147 MCInst LoweredMI; 148 switch (MI->getOpcode()) { 149 case SystemZ::Return: 150 LoweredMI = MCInstBuilder(SystemZ::BR) 151 .addReg(SystemZ::R14D); 152 break; 153 154 case SystemZ::Return_XPLINK: 155 LoweredMI = MCInstBuilder(SystemZ::B) 156 .addReg(SystemZ::R7D) 157 .addImm(2) 158 .addReg(0); 159 break; 160 161 case SystemZ::CondReturn: 162 LoweredMI = MCInstBuilder(SystemZ::BCR) 163 .addImm(MI->getOperand(0).getImm()) 164 .addImm(MI->getOperand(1).getImm()) 165 .addReg(SystemZ::R14D); 166 break; 167 168 case SystemZ::CondReturn_XPLINK: 169 LoweredMI = MCInstBuilder(SystemZ::BC) 170 .addImm(MI->getOperand(0).getImm()) 171 .addImm(MI->getOperand(1).getImm()) 172 .addReg(SystemZ::R7D) 173 .addImm(2) 174 .addReg(0); 175 break; 176 177 case SystemZ::CRBReturn: 178 LoweredMI = MCInstBuilder(SystemZ::CRB) 179 .addReg(MI->getOperand(0).getReg()) 180 .addReg(MI->getOperand(1).getReg()) 181 .addImm(MI->getOperand(2).getImm()) 182 .addReg(SystemZ::R14D) 183 .addImm(0); 184 break; 185 186 case SystemZ::CGRBReturn: 187 LoweredMI = MCInstBuilder(SystemZ::CGRB) 188 .addReg(MI->getOperand(0).getReg()) 189 .addReg(MI->getOperand(1).getReg()) 190 .addImm(MI->getOperand(2).getImm()) 191 .addReg(SystemZ::R14D) 192 .addImm(0); 193 break; 194 195 case SystemZ::CIBReturn: 196 LoweredMI = MCInstBuilder(SystemZ::CIB) 197 .addReg(MI->getOperand(0).getReg()) 198 .addImm(MI->getOperand(1).getImm()) 199 .addImm(MI->getOperand(2).getImm()) 200 .addReg(SystemZ::R14D) 201 .addImm(0); 202 break; 203 204 case SystemZ::CGIBReturn: 205 LoweredMI = MCInstBuilder(SystemZ::CGIB) 206 .addReg(MI->getOperand(0).getReg()) 207 .addImm(MI->getOperand(1).getImm()) 208 .addImm(MI->getOperand(2).getImm()) 209 .addReg(SystemZ::R14D) 210 .addImm(0); 211 break; 212 213 case SystemZ::CLRBReturn: 214 LoweredMI = MCInstBuilder(SystemZ::CLRB) 215 .addReg(MI->getOperand(0).getReg()) 216 .addReg(MI->getOperand(1).getReg()) 217 .addImm(MI->getOperand(2).getImm()) 218 .addReg(SystemZ::R14D) 219 .addImm(0); 220 break; 221 222 case SystemZ::CLGRBReturn: 223 LoweredMI = MCInstBuilder(SystemZ::CLGRB) 224 .addReg(MI->getOperand(0).getReg()) 225 .addReg(MI->getOperand(1).getReg()) 226 .addImm(MI->getOperand(2).getImm()) 227 .addReg(SystemZ::R14D) 228 .addImm(0); 229 break; 230 231 case SystemZ::CLIBReturn: 232 LoweredMI = MCInstBuilder(SystemZ::CLIB) 233 .addReg(MI->getOperand(0).getReg()) 234 .addImm(MI->getOperand(1).getImm()) 235 .addImm(MI->getOperand(2).getImm()) 236 .addReg(SystemZ::R14D) 237 .addImm(0); 238 break; 239 240 case SystemZ::CLGIBReturn: 241 LoweredMI = MCInstBuilder(SystemZ::CLGIB) 242 .addReg(MI->getOperand(0).getReg()) 243 .addImm(MI->getOperand(1).getImm()) 244 .addImm(MI->getOperand(2).getImm()) 245 .addReg(SystemZ::R14D) 246 .addImm(0); 247 break; 248 249 case SystemZ::CallBRASL_XPLINK64: 250 EmitToStreamer(*OutStreamer, 251 MCInstBuilder(SystemZ::BRASL) 252 .addReg(SystemZ::R7D) 253 .addExpr(Lower.getExpr(MI->getOperand(0), 254 MCSymbolRefExpr::VK_PLT))); 255 emitCallInformation(CallType::BRASL7); 256 return; 257 258 case SystemZ::CallBASR_XPLINK64: 259 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 260 .addReg(SystemZ::R7D) 261 .addReg(MI->getOperand(0).getReg())); 262 emitCallInformation(CallType::BASR76); 263 return; 264 265 case SystemZ::CallBASR_STACKEXT: 266 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 267 .addReg(SystemZ::R3D) 268 .addReg(MI->getOperand(0).getReg())); 269 emitCallInformation(CallType::BASR33); 270 return; 271 272 case SystemZ::CallBRASL: 273 LoweredMI = MCInstBuilder(SystemZ::BRASL) 274 .addReg(SystemZ::R14D) 275 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 276 break; 277 278 case SystemZ::CallBASR: 279 LoweredMI = MCInstBuilder(SystemZ::BASR) 280 .addReg(SystemZ::R14D) 281 .addReg(MI->getOperand(0).getReg()); 282 break; 283 284 case SystemZ::CallJG: 285 LoweredMI = MCInstBuilder(SystemZ::JG) 286 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 287 break; 288 289 case SystemZ::CallBRCL: 290 LoweredMI = MCInstBuilder(SystemZ::BRCL) 291 .addImm(MI->getOperand(0).getImm()) 292 .addImm(MI->getOperand(1).getImm()) 293 .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 294 break; 295 296 case SystemZ::CallBR: 297 LoweredMI = MCInstBuilder(SystemZ::BR) 298 .addReg(MI->getOperand(0).getReg()); 299 break; 300 301 case SystemZ::CallBCR: 302 LoweredMI = MCInstBuilder(SystemZ::BCR) 303 .addImm(MI->getOperand(0).getImm()) 304 .addImm(MI->getOperand(1).getImm()) 305 .addReg(MI->getOperand(2).getReg()); 306 break; 307 308 case SystemZ::CRBCall: 309 LoweredMI = MCInstBuilder(SystemZ::CRB) 310 .addReg(MI->getOperand(0).getReg()) 311 .addReg(MI->getOperand(1).getReg()) 312 .addImm(MI->getOperand(2).getImm()) 313 .addReg(MI->getOperand(3).getReg()) 314 .addImm(0); 315 break; 316 317 case SystemZ::CGRBCall: 318 LoweredMI = MCInstBuilder(SystemZ::CGRB) 319 .addReg(MI->getOperand(0).getReg()) 320 .addReg(MI->getOperand(1).getReg()) 321 .addImm(MI->getOperand(2).getImm()) 322 .addReg(MI->getOperand(3).getReg()) 323 .addImm(0); 324 break; 325 326 case SystemZ::CIBCall: 327 LoweredMI = MCInstBuilder(SystemZ::CIB) 328 .addReg(MI->getOperand(0).getReg()) 329 .addImm(MI->getOperand(1).getImm()) 330 .addImm(MI->getOperand(2).getImm()) 331 .addReg(MI->getOperand(3).getReg()) 332 .addImm(0); 333 break; 334 335 case SystemZ::CGIBCall: 336 LoweredMI = MCInstBuilder(SystemZ::CGIB) 337 .addReg(MI->getOperand(0).getReg()) 338 .addImm(MI->getOperand(1).getImm()) 339 .addImm(MI->getOperand(2).getImm()) 340 .addReg(MI->getOperand(3).getReg()) 341 .addImm(0); 342 break; 343 344 case SystemZ::CLRBCall: 345 LoweredMI = MCInstBuilder(SystemZ::CLRB) 346 .addReg(MI->getOperand(0).getReg()) 347 .addReg(MI->getOperand(1).getReg()) 348 .addImm(MI->getOperand(2).getImm()) 349 .addReg(MI->getOperand(3).getReg()) 350 .addImm(0); 351 break; 352 353 case SystemZ::CLGRBCall: 354 LoweredMI = MCInstBuilder(SystemZ::CLGRB) 355 .addReg(MI->getOperand(0).getReg()) 356 .addReg(MI->getOperand(1).getReg()) 357 .addImm(MI->getOperand(2).getImm()) 358 .addReg(MI->getOperand(3).getReg()) 359 .addImm(0); 360 break; 361 362 case SystemZ::CLIBCall: 363 LoweredMI = MCInstBuilder(SystemZ::CLIB) 364 .addReg(MI->getOperand(0).getReg()) 365 .addImm(MI->getOperand(1).getImm()) 366 .addImm(MI->getOperand(2).getImm()) 367 .addReg(MI->getOperand(3).getReg()) 368 .addImm(0); 369 break; 370 371 case SystemZ::CLGIBCall: 372 LoweredMI = MCInstBuilder(SystemZ::CLGIB) 373 .addReg(MI->getOperand(0).getReg()) 374 .addImm(MI->getOperand(1).getImm()) 375 .addImm(MI->getOperand(2).getImm()) 376 .addReg(MI->getOperand(3).getReg()) 377 .addImm(0); 378 break; 379 380 case SystemZ::TLS_GDCALL: 381 LoweredMI = MCInstBuilder(SystemZ::BRASL) 382 .addReg(SystemZ::R14D) 383 .addExpr(getTLSGetOffset(MF->getContext())) 384 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 385 break; 386 387 case SystemZ::TLS_LDCALL: 388 LoweredMI = MCInstBuilder(SystemZ::BRASL) 389 .addReg(SystemZ::R14D) 390 .addExpr(getTLSGetOffset(MF->getContext())) 391 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 392 break; 393 394 case SystemZ::GOT: 395 LoweredMI = MCInstBuilder(SystemZ::LARL) 396 .addReg(MI->getOperand(0).getReg()) 397 .addExpr(getGlobalOffsetTable(MF->getContext())); 398 break; 399 400 case SystemZ::IILF64: 401 LoweredMI = MCInstBuilder(SystemZ::IILF) 402 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 403 .addImm(MI->getOperand(2).getImm()); 404 break; 405 406 case SystemZ::IIHF64: 407 LoweredMI = MCInstBuilder(SystemZ::IIHF) 408 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 409 .addImm(MI->getOperand(2).getImm()); 410 break; 411 412 case SystemZ::RISBHH: 413 case SystemZ::RISBHL: 414 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 415 break; 416 417 case SystemZ::RISBLH: 418 case SystemZ::RISBLL: 419 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 420 break; 421 422 case SystemZ::VLVGP32: 423 LoweredMI = MCInstBuilder(SystemZ::VLVGP) 424 .addReg(MI->getOperand(0).getReg()) 425 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 426 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 427 break; 428 429 case SystemZ::VLR32: 430 case SystemZ::VLR64: 431 LoweredMI = MCInstBuilder(SystemZ::VLR) 432 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 433 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 434 break; 435 436 case SystemZ::VL: 437 Lower.lower(MI, LoweredMI); 438 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 439 break; 440 441 case SystemZ::VST: 442 Lower.lower(MI, LoweredMI); 443 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 444 break; 445 446 case SystemZ::VLM: 447 Lower.lower(MI, LoweredMI); 448 lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 449 break; 450 451 case SystemZ::VSTM: 452 Lower.lower(MI, LoweredMI); 453 lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 454 break; 455 456 case SystemZ::VL32: 457 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 458 break; 459 460 case SystemZ::VL64: 461 LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 462 break; 463 464 case SystemZ::VST32: 465 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 466 break; 467 468 case SystemZ::VST64: 469 LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 470 break; 471 472 case SystemZ::LFER: 473 LoweredMI = MCInstBuilder(SystemZ::VLGVF) 474 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 475 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 476 .addReg(0).addImm(0); 477 break; 478 479 case SystemZ::LEFR: 480 LoweredMI = MCInstBuilder(SystemZ::VLVGF) 481 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 482 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 483 .addReg(MI->getOperand(1).getReg()) 484 .addReg(0).addImm(0); 485 break; 486 487 #define LOWER_LOW(NAME) \ 488 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 489 490 LOWER_LOW(IILL); 491 LOWER_LOW(IILH); 492 LOWER_LOW(TMLL); 493 LOWER_LOW(TMLH); 494 LOWER_LOW(NILL); 495 LOWER_LOW(NILH); 496 LOWER_LOW(NILF); 497 LOWER_LOW(OILL); 498 LOWER_LOW(OILH); 499 LOWER_LOW(OILF); 500 LOWER_LOW(XILF); 501 502 #undef LOWER_LOW 503 504 #define LOWER_HIGH(NAME) \ 505 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 506 507 LOWER_HIGH(IIHL); 508 LOWER_HIGH(IIHH); 509 LOWER_HIGH(TMHL); 510 LOWER_HIGH(TMHH); 511 LOWER_HIGH(NIHL); 512 LOWER_HIGH(NIHH); 513 LOWER_HIGH(NIHF); 514 LOWER_HIGH(OIHL); 515 LOWER_HIGH(OIHH); 516 LOWER_HIGH(OIHF); 517 LOWER_HIGH(XIHF); 518 519 #undef LOWER_HIGH 520 521 case SystemZ::Serialize: 522 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 523 LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 524 .addImm(14).addReg(SystemZ::R0D); 525 else 526 LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 527 .addImm(15).addReg(SystemZ::R0D); 528 break; 529 530 // Emit nothing here but a comment if we can. 531 case SystemZ::MemBarrier: 532 OutStreamer->emitRawComment("MEMBARRIER"); 533 return; 534 535 // We want to emit "j .+2" for traps, jumping to the relative immediate field 536 // of the jump instruction, which is an illegal instruction. We cannot emit a 537 // "." symbol, so create and emit a temp label before the instruction and use 538 // that instead. 539 case SystemZ::Trap: { 540 MCSymbol *DotSym = OutContext.createTempSymbol(); 541 OutStreamer->emitLabel(DotSym); 542 543 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 544 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 545 LoweredMI = MCInstBuilder(SystemZ::J) 546 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 547 } 548 break; 549 550 // Conditional traps will create a branch on condition instruction that jumps 551 // to the relative immediate field of the jump instruction. (eg. "jo .+2") 552 case SystemZ::CondTrap: { 553 MCSymbol *DotSym = OutContext.createTempSymbol(); 554 OutStreamer->emitLabel(DotSym); 555 556 const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 557 const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 558 LoweredMI = MCInstBuilder(SystemZ::BRC) 559 .addImm(MI->getOperand(0).getImm()) 560 .addImm(MI->getOperand(1).getImm()) 561 .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 562 } 563 break; 564 565 case TargetOpcode::FENTRY_CALL: 566 LowerFENTRY_CALL(*MI, Lower); 567 return; 568 569 case TargetOpcode::STACKMAP: 570 LowerSTACKMAP(*MI); 571 return; 572 573 case TargetOpcode::PATCHPOINT: 574 LowerPATCHPOINT(*MI, Lower); 575 return; 576 577 case SystemZ::EXRL_Pseudo: { 578 unsigned TargetInsOpc = MI->getOperand(0).getImm(); 579 Register LenMinus1Reg = MI->getOperand(1).getReg(); 580 Register DestReg = MI->getOperand(2).getReg(); 581 int64_t DestDisp = MI->getOperand(3).getImm(); 582 Register SrcReg = MI->getOperand(4).getReg(); 583 int64_t SrcDisp = MI->getOperand(5).getImm(); 584 585 SystemZTargetStreamer *TS = getTargetStreamer(); 586 MCSymbol *DotSym = nullptr; 587 MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg) 588 .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp); 589 SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget()); 590 SystemZTargetStreamer::EXRLT2SymMap::iterator I = 591 TS->EXRLTargets2Sym.find(ET_STI); 592 if (I != TS->EXRLTargets2Sym.end()) 593 DotSym = I->second; 594 else 595 TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol(); 596 const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 597 EmitToStreamer( 598 *OutStreamer, 599 MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot)); 600 return; 601 } 602 603 default: 604 Lower.lower(MI, LoweredMI); 605 break; 606 } 607 EmitToStreamer(*OutStreamer, LoweredMI); 608 } 609 610 // Emit the largest nop instruction smaller than or equal to NumBytes 611 // bytes. Return the size of nop emitted. 612 static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 613 unsigned NumBytes, const MCSubtargetInfo &STI) { 614 if (NumBytes < 2) { 615 llvm_unreachable("Zero nops?"); 616 return 0; 617 } 618 else if (NumBytes < 4) { 619 OutStreamer.emitInstruction( 620 MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI); 621 return 2; 622 } 623 else if (NumBytes < 6) { 624 OutStreamer.emitInstruction( 625 MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0), 626 STI); 627 return 4; 628 } 629 else { 630 MCSymbol *DotSym = OutContext.createTempSymbol(); 631 const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 632 OutStreamer.emitLabel(DotSym); 633 OutStreamer.emitInstruction( 634 MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI); 635 return 6; 636 } 637 } 638 639 void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, 640 SystemZMCInstLower &Lower) { 641 MCContext &Ctx = MF->getContext(); 642 if (MF->getFunction().hasFnAttribute("mrecord-mcount")) { 643 MCSymbol *DotSym = OutContext.createTempSymbol(); 644 OutStreamer->PushSection(); 645 OutStreamer->SwitchSection( 646 Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC)); 647 OutStreamer->emitSymbolValue(DotSym, 8); 648 OutStreamer->PopSection(); 649 OutStreamer->emitLabel(DotSym); 650 } 651 652 if (MF->getFunction().hasFnAttribute("mnop-mcount")) { 653 EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); 654 return; 655 } 656 657 MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); 658 const MCSymbolRefExpr *Op = 659 MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); 660 OutStreamer->emitInstruction( 661 MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op), 662 getSubtargetInfo()); 663 } 664 665 void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 666 const SystemZInstrInfo *TII = 667 static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 668 669 unsigned NumNOPBytes = MI.getOperand(1).getImm(); 670 671 auto &Ctx = OutStreamer->getContext(); 672 MCSymbol *MILabel = Ctx.createTempSymbol(); 673 OutStreamer->emitLabel(MILabel); 674 675 SM.recordStackMap(*MILabel, MI); 676 assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 677 678 // Scan ahead to trim the shadow. 679 unsigned ShadowBytes = 0; 680 const MachineBasicBlock &MBB = *MI.getParent(); 681 MachineBasicBlock::const_iterator MII(MI); 682 ++MII; 683 while (ShadowBytes < NumNOPBytes) { 684 if (MII == MBB.end() || 685 MII->getOpcode() == TargetOpcode::PATCHPOINT || 686 MII->getOpcode() == TargetOpcode::STACKMAP) 687 break; 688 ShadowBytes += TII->getInstSizeInBytes(*MII); 689 if (MII->isCall()) 690 break; 691 ++MII; 692 } 693 694 // Emit nops. 695 while (ShadowBytes < NumNOPBytes) 696 ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 697 getSubtargetInfo()); 698 } 699 700 // Lower a patchpoint of the form: 701 // [<def>], <id>, <numBytes>, <target>, <numArgs> 702 void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 703 SystemZMCInstLower &Lower) { 704 auto &Ctx = OutStreamer->getContext(); 705 MCSymbol *MILabel = Ctx.createTempSymbol(); 706 OutStreamer->emitLabel(MILabel); 707 708 SM.recordPatchPoint(*MILabel, MI); 709 PatchPointOpers Opers(&MI); 710 711 unsigned EncodedBytes = 0; 712 const MachineOperand &CalleeMO = Opers.getCallTarget(); 713 714 if (CalleeMO.isImm()) { 715 uint64_t CallTarget = CalleeMO.getImm(); 716 if (CallTarget) { 717 unsigned ScratchIdx = -1; 718 unsigned ScratchReg = 0; 719 do { 720 ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 721 ScratchReg = MI.getOperand(ScratchIdx).getReg(); 722 } while (ScratchReg == SystemZ::R0D); 723 724 // Materialize the call target address 725 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 726 .addReg(ScratchReg) 727 .addImm(CallTarget & 0xFFFFFFFF)); 728 EncodedBytes += 6; 729 if (CallTarget >> 32) { 730 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 731 .addReg(ScratchReg) 732 .addImm(CallTarget >> 32)); 733 EncodedBytes += 6; 734 } 735 736 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 737 .addReg(SystemZ::R14D) 738 .addReg(ScratchReg)); 739 EncodedBytes += 2; 740 } 741 } else if (CalleeMO.isGlobal()) { 742 const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 743 EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 744 .addReg(SystemZ::R14D) 745 .addExpr(Expr)); 746 EncodedBytes += 6; 747 } 748 749 // Emit padding. 750 unsigned NumBytes = Opers.getNumPatchBytes(); 751 assert(NumBytes >= EncodedBytes && 752 "Patchpoint can't request size less than the length of a call."); 753 assert((NumBytes - EncodedBytes) % 2 == 0 && 754 "Invalid number of NOP bytes requested!"); 755 while (EncodedBytes < NumBytes) 756 EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 757 getSubtargetInfo()); 758 } 759 760 // Convert a SystemZ-specific constant pool modifier into the associated 761 // MCSymbolRefExpr variant kind. 762 static MCSymbolRefExpr::VariantKind 763 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 764 switch (Modifier) { 765 case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 766 case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 767 case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 768 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 769 } 770 llvm_unreachable("Invalid SystemCPModifier!"); 771 } 772 773 void SystemZAsmPrinter::emitMachineConstantPoolValue( 774 MachineConstantPoolValue *MCPV) { 775 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 776 777 const MCExpr *Expr = 778 MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 779 getModifierVariantKind(ZCPV->getModifier()), 780 OutContext); 781 uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 782 783 OutStreamer->emitValue(Expr, Size); 784 } 785 786 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 787 const char *ExtraCode, 788 raw_ostream &OS) { 789 const MCRegisterInfo &MRI = *TM.getMCRegisterInfo(); 790 const MachineOperand &MO = MI->getOperand(OpNo); 791 MCOperand MCOp; 792 if (ExtraCode) { 793 if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() && 794 SystemZ::GR128BitRegClass.contains(MO.getReg())) 795 MCOp = 796 MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64)); 797 else 798 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 799 } else { 800 SystemZMCInstLower Lower(MF->getContext(), *this); 801 MCOp = Lower.lowerOperand(MO); 802 } 803 SystemZInstPrinter::printOperand(MCOp, MAI, OS); 804 return false; 805 } 806 807 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 808 unsigned OpNo, 809 const char *ExtraCode, 810 raw_ostream &OS) { 811 SystemZInstPrinter:: 812 printAddress(MAI, MI->getOperand(OpNo).getReg(), 813 MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()), 814 MI->getOperand(OpNo + 2).getReg(), OS); 815 return false; 816 } 817 818 void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { 819 emitStackMaps(SM); 820 } 821 822 void SystemZAsmPrinter::emitFunctionBodyEnd() { 823 if (TM.getTargetTriple().isOSzOS()) { 824 // Emit symbol for the end of function if the z/OS target streamer 825 // is used. This is needed to calculate the size of the function. 826 MCSymbol *FnEndSym = createTempSymbol("func_end"); 827 OutStreamer->emitLabel(FnEndSym); 828 829 OutStreamer->PushSection(); 830 OutStreamer->SwitchSection(getObjFileLowering().getPPA1Section()); 831 emitPPA1(FnEndSym); 832 OutStreamer->PopSection(); 833 834 CurrentFnPPA1Sym = nullptr; 835 CurrentFnEPMarkerSym = nullptr; 836 } 837 } 838 839 static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg, 840 bool StackProtector, bool FPRMask, bool VRMask) { 841 enum class PPA1Flag1 : uint8_t { 842 DSA64Bit = (0x80 >> 0), 843 VarArg = (0x80 >> 7), 844 LLVM_MARK_AS_BITMASK_ENUM(DSA64Bit) 845 }; 846 enum class PPA1Flag2 : uint8_t { 847 ExternalProcedure = (0x80 >> 0), 848 STACKPROTECTOR = (0x80 >> 3), 849 LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure) 850 }; 851 enum class PPA1Flag3 : uint8_t { 852 FPRMask = (0x80 >> 2), 853 LLVM_MARK_AS_BITMASK_ENUM(FPRMask) 854 }; 855 enum class PPA1Flag4 : uint8_t { 856 EPMOffsetPresent = (0x80 >> 0), 857 VRMask = (0x80 >> 2), 858 ProcedureNamePresent = (0x80 >> 7), 859 LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent) 860 }; 861 862 // Declare optional section flags that can be modified. 863 auto Flags1 = PPA1Flag1(0); 864 auto Flags2 = PPA1Flag2::ExternalProcedure; 865 auto Flags3 = PPA1Flag3(0); 866 auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent; 867 868 Flags1 |= PPA1Flag1::DSA64Bit; 869 870 if (VarArg) 871 Flags1 |= PPA1Flag1::VarArg; 872 873 if (StackProtector) 874 Flags2 |= PPA1Flag2::STACKPROTECTOR; 875 876 // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in. 877 if (FPRMask) 878 Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag. 879 880 if (VRMask) 881 Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag. 882 883 OutStreamer->AddComment("PPA1 Flags 1"); 884 if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit) 885 OutStreamer->AddComment(" Bit 0: 1 = 64-bit DSA"); 886 else 887 OutStreamer->AddComment(" Bit 0: 0 = 32-bit DSA"); 888 if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg) 889 OutStreamer->AddComment(" Bit 7: 1 = Vararg function"); 890 OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1. 891 892 OutStreamer->AddComment("PPA1 Flags 2"); 893 if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure) 894 OutStreamer->AddComment(" Bit 0: 1 = External procedure"); 895 if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR) 896 OutStreamer->AddComment(" Bit 3: 1 = STACKPROTECT is enabled"); 897 else 898 OutStreamer->AddComment(" Bit 3: 0 = STACKPROTECT is not enabled"); 899 OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2. 900 901 OutStreamer->AddComment("PPA1 Flags 3"); 902 if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask) 903 OutStreamer->AddComment(" Bit 2: 1 = FP Reg Mask is in optional area"); 904 OutStreamer->emitInt8( 905 static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections). 906 907 OutStreamer->AddComment("PPA1 Flags 4"); 908 if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask) 909 OutStreamer->AddComment(" Bit 2: 1 = Vector Reg Mask is in optional area"); 910 OutStreamer->emitInt8(static_cast<uint8_t>( 911 Flags4)); // Flags 4 (optional sections, always emit these). 912 } 913 914 void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) { 915 const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo(); 916 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); 917 const auto TargetHasVector = Subtarget.hasVector(); 918 919 const SystemZMachineFunctionInfo *ZFI = 920 MF->getInfo<SystemZMachineFunctionInfo>(); 921 const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>( 922 Subtarget.getFrameLowering()); 923 const MachineFrameInfo &MFFrame = MF->getFrameInfo(); 924 925 // Get saved GPR/FPR/VPR masks. 926 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo(); 927 uint16_t SavedGPRMask = 0; 928 uint16_t SavedFPRMask = 0; 929 uint8_t SavedVRMask = 0; 930 int64_t OffsetFPR = 0; 931 int64_t OffsetVR = 0; 932 const int64_t TopOfStack = 933 MFFrame.getOffsetAdjustment() + MFFrame.getStackSize(); 934 935 // Loop over the spilled registers. The CalleeSavedInfo can't be used because 936 // it does not contain all spilled registers. 937 for (unsigned I = ZFI->getSpillGPRRegs().LowGPR, 938 E = ZFI->getSpillGPRRegs().HighGPR; 939 I && E && I <= E; ++I) { 940 unsigned V = TRI->getEncodingValue((Register)I); 941 assert(V < 16 && "GPR index out of range"); 942 SavedGPRMask |= 1 << (15 - V); 943 } 944 945 for (auto &CS : CSI) { 946 unsigned Reg = CS.getReg(); 947 unsigned I = TRI->getEncodingValue(Reg); 948 949 if (SystemZ::FP64BitRegClass.contains(Reg)) { 950 assert(I < 16 && "FPR index out of range"); 951 SavedFPRMask |= 1 << (15 - I); 952 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx()); 953 if (Temp < OffsetFPR) 954 OffsetFPR = Temp; 955 } else if (SystemZ::VR128BitRegClass.contains(Reg)) { 956 assert(I >= 16 && I <= 23 && "VPR index out of range"); 957 unsigned BitNum = I - 16; 958 SavedVRMask |= 1 << (7 - BitNum); 959 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx()); 960 if (Temp < OffsetVR) 961 OffsetVR = Temp; 962 } 963 } 964 965 // Adjust the offset. 966 OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0; 967 OffsetVR += (OffsetVR < 0) ? TopOfStack : 0; 968 969 // Get alloca register. 970 uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF)); 971 uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0; 972 assert(AllocaReg < 16 && "Can't have alloca register larger than 15"); 973 (void)AllocaReg; 974 975 // Build FPR save area offset. 976 uint32_t FrameAndFPROffset = 0; 977 if (SavedFPRMask) { 978 uint64_t FPRSaveAreaOffset = OffsetFPR; 979 assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range"); 980 981 FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits. 982 FrameAndFPROffset |= FrameReg << 28; // Put into top 4 bits. 983 } 984 985 // Build VR save area offset. 986 uint32_t FrameAndVROffset = 0; 987 if (TargetHasVector && SavedVRMask) { 988 uint64_t VRSaveAreaOffset = OffsetVR; 989 assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range"); 990 991 FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits. 992 FrameAndVROffset |= FrameReg << 28; // Put into top 4 bits. 993 } 994 995 // Emit PPA1 section. 996 OutStreamer->AddComment("PPA1"); 997 OutStreamer->emitLabel(CurrentFnPPA1Sym); 998 OutStreamer->AddComment("Version"); 999 OutStreamer->emitInt8(0x02); // Version. 1000 OutStreamer->AddComment("LE Signature X'CE'"); 1001 OutStreamer->emitInt8(0xCE); // CEL signature. 1002 OutStreamer->AddComment("Saved GPR Mask"); 1003 OutStreamer->emitInt16(SavedGPRMask); 1004 1005 emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(), 1006 MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0, 1007 TargetHasVector && SavedVRMask != 0); 1008 1009 OutStreamer->AddComment("Length/4 of Parms"); 1010 OutStreamer->emitInt16( 1011 static_cast<uint16_t>(MFFrame.getMaxCallFrameSize() / 4)); // Parms/4. 1012 OutStreamer->AddComment("Length of Code"); 1013 OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4); 1014 1015 // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3). 1016 if (SavedFPRMask) { 1017 OutStreamer->AddComment("FPR mask"); 1018 OutStreamer->emitInt16(SavedFPRMask); 1019 OutStreamer->AddComment("AR mask"); 1020 OutStreamer->emitInt16(0); // AR Mask, unused currently. 1021 OutStreamer->AddComment("FPR Save Area Locator"); 1022 OutStreamer->AddComment(Twine(" Bit 0-3: Register R") 1023 .concat(utostr(FrameAndFPROffset >> 28)) 1024 .str()); 1025 OutStreamer->AddComment(Twine(" Bit 4-31: Offset ") 1026 .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF)) 1027 .str()); 1028 OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with 1029 // register to add value to 1030 // (alloca reg). 1031 } 1032 1033 // Emit saved VR mask to VR save area. 1034 if (TargetHasVector && SavedVRMask) { 1035 OutStreamer->AddComment("VR mask"); 1036 OutStreamer->emitInt8(SavedVRMask); 1037 OutStreamer->emitInt8(0); // Reserved. 1038 OutStreamer->emitInt16(0); // Also reserved. 1039 OutStreamer->AddComment("VR Save Area Locator"); 1040 OutStreamer->AddComment(Twine(" Bit 0-3: Register R") 1041 .concat(utostr(FrameAndVROffset >> 28)) 1042 .str()); 1043 OutStreamer->AddComment(Twine(" Bit 4-31: Offset ") 1044 .concat(utostr(FrameAndVROffset & 0x0FFFFFFF)) 1045 .str()); 1046 OutStreamer->emitInt32(FrameAndVROffset); 1047 } 1048 1049 // Emit offset to entry point optional section (0x80 of flags 4). 1050 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym, 1051 4); 1052 } 1053 1054 void SystemZAsmPrinter::emitFunctionEntryLabel() { 1055 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); 1056 1057 if (Subtarget.getTargetTriple().isOSzOS()) { 1058 MCContext &OutContext = OutStreamer->getContext(); 1059 1060 // Save information for later use. 1061 std::string N(MF->getFunction().hasName() 1062 ? Twine(MF->getFunction().getName()).concat("_").str() 1063 : ""); 1064 1065 CurrentFnEPMarkerSym = 1066 OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true); 1067 CurrentFnPPA1Sym = 1068 OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true); 1069 1070 // EntryPoint Marker 1071 const MachineFrameInfo &MFFrame = MF->getFrameInfo(); 1072 bool IsUsingAlloca = MFFrame.hasVarSizedObjects(); 1073 1074 // Set Flags 1075 uint8_t Flags = 0; 1076 if (IsUsingAlloca) 1077 Flags |= 0x04; 1078 1079 uint32_t DSASize = MFFrame.getStackSize(); 1080 1081 // Combine into top 27 bits of DSASize and bottom 5 bits of Flags. 1082 uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5 1083 DSAAndFlags |= Flags; 1084 1085 // Emit entry point marker section. 1086 OutStreamer->AddComment("XPLINK Routine Layout Entry"); 1087 OutStreamer->emitLabel(CurrentFnEPMarkerSym); 1088 OutStreamer->AddComment("Eyecatcher 0x00C300C500C500"); 1089 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher. 1090 OutStreamer->AddComment("Mark Type C'1'"); 1091 OutStreamer->emitInt8(0xF1); // Mark Type. 1092 OutStreamer->AddComment("Offset to PPA1"); 1093 OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym, 1094 4); 1095 if (OutStreamer->isVerboseAsm()) { 1096 OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize)); 1097 OutStreamer->AddComment("Entry Flags"); 1098 if (Flags & 0x04) 1099 OutStreamer->AddComment(" Bit 2: 1 = Uses alloca"); 1100 else 1101 OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca"); 1102 } 1103 OutStreamer->emitInt32(DSAAndFlags); 1104 } 1105 1106 AsmPrinter::emitFunctionEntryLabel(); 1107 } 1108 1109 // Force static initialization. 1110 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() { 1111 RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 1112 } 1113