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