1 //===- AArch64FrameLowering.cpp - AArch64 Frame Lowering -------*- C++ -*-====// 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 // This file contains the AArch64 implementation of TargetFrameLowering class. 11 // 12 // On AArch64, stack frames are structured as follows: 13 // 14 // The stack grows downward. 15 // 16 // All of the individual frame areas on the frame below are optional, i.e. it's 17 // possible to create a function so that the particular area isn't present 18 // in the frame. 19 // 20 // At function entry, the "frame" looks as follows: 21 // 22 // | | Higher address 23 // |-----------------------------------| 24 // | | 25 // | arguments passed on the stack | 26 // | | 27 // |-----------------------------------| <- sp 28 // | | Lower address 29 // 30 // 31 // After the prologue has run, the frame has the following general structure. 32 // Note that this doesn't depict the case where a red-zone is used. Also, 33 // technically the last frame area (VLAs) doesn't get created until in the 34 // main function body, after the prologue is run. However, it's depicted here 35 // for completeness. 36 // 37 // | | Higher address 38 // |-----------------------------------| 39 // | | 40 // | arguments passed on the stack | 41 // | | 42 // |-----------------------------------| 43 // | | 44 // | prev_fp, prev_lr | 45 // | (a.k.a. "frame record") | 46 // |-----------------------------------| <- fp(=x29) 47 // | | 48 // | other callee-saved registers | 49 // | | 50 // |-----------------------------------| 51 // |.empty.space.to.make.part.below....| 52 // |.aligned.in.case.it.needs.more.than| (size of this area is unknown at 53 // |.the.standard.16-byte.alignment....| compile time; if present) 54 // |-----------------------------------| 55 // | | 56 // | local variables of fixed size | 57 // | including spill slots | 58 // |-----------------------------------| <- bp(not defined by ABI, 59 // |.variable-sized.local.variables....| LLVM chooses X19) 60 // |.(VLAs)............................| (size of this area is unknown at 61 // |...................................| compile time) 62 // |-----------------------------------| <- sp 63 // | | Lower address 64 // 65 // 66 // To access the data in a frame, at-compile time, a constant offset must be 67 // computable from one of the pointers (fp, bp, sp) to access it. The size 68 // of the areas with a dotted background cannot be computed at compile-time 69 // if they are present, making it required to have all three of fp, bp and 70 // sp to be set up to be able to access all contents in the frame areas, 71 // assuming all of the frame areas are non-empty. 72 // 73 // For most functions, some of the frame areas are empty. For those functions, 74 // it may not be necessary to set up fp or bp: 75 // * A base pointer is definitely needed when there are both VLAs and local 76 // variables with more-than-default alignment requirements. 77 // * A frame pointer is definitely needed when there are local variables with 78 // more-than-default alignment requirements. 79 // 80 // In some cases when a base pointer is not strictly needed, it is generated 81 // anyway when offsets from the frame pointer to access local variables become 82 // so large that the offset can't be encoded in the immediate fields of loads 83 // or stores. 84 // 85 // FIXME: also explain the redzone concept. 86 // FIXME: also explain the concept of reserved call frames. 87 // 88 //===----------------------------------------------------------------------===// 89 90 #include "AArch64FrameLowering.h" 91 #include "AArch64InstrInfo.h" 92 #include "AArch64MachineFunctionInfo.h" 93 #include "AArch64Subtarget.h" 94 #include "AArch64TargetMachine.h" 95 #include "llvm/ADT/Statistic.h" 96 #include "llvm/CodeGen/MachineFrameInfo.h" 97 #include "llvm/CodeGen/MachineFunction.h" 98 #include "llvm/CodeGen/MachineInstrBuilder.h" 99 #include "llvm/CodeGen/MachineModuleInfo.h" 100 #include "llvm/CodeGen/MachineRegisterInfo.h" 101 #include "llvm/CodeGen/RegisterScavenging.h" 102 #include "llvm/IR/DataLayout.h" 103 #include "llvm/IR/Function.h" 104 #include "llvm/Support/CommandLine.h" 105 #include "llvm/Support/Debug.h" 106 #include "llvm/Support/raw_ostream.h" 107 108 using namespace llvm; 109 110 #define DEBUG_TYPE "frame-info" 111 112 static cl::opt<bool> EnableRedZone("aarch64-redzone", 113 cl::desc("enable use of redzone on AArch64"), 114 cl::init(false), cl::Hidden); 115 116 STATISTIC(NumRedZoneFunctions, "Number of functions using red zone"); 117 118 bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const { 119 if (!EnableRedZone) 120 return false; 121 // Don't use the red zone if the function explicitly asks us not to. 122 // This is typically used for kernel code. 123 if (MF.getFunction()->hasFnAttribute(Attribute::NoRedZone)) 124 return false; 125 126 const MachineFrameInfo *MFI = MF.getFrameInfo(); 127 const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 128 unsigned NumBytes = AFI->getLocalStackSize(); 129 130 // Note: currently hasFP() is always true for hasCalls(), but that's an 131 // implementation detail of the current code, not a strict requirement, 132 // so stay safe here and check both. 133 if (MFI->hasCalls() || hasFP(MF) || NumBytes > 128) 134 return false; 135 return true; 136 } 137 138 /// hasFP - Return true if the specified function should have a dedicated frame 139 /// pointer register. 140 bool AArch64FrameLowering::hasFP(const MachineFunction &MF) const { 141 const MachineFrameInfo *MFI = MF.getFrameInfo(); 142 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 143 return (MFI->hasCalls() || MFI->hasVarSizedObjects() || 144 MFI->isFrameAddressTaken() || MFI->hasStackMap() || 145 MFI->hasPatchPoint() || RegInfo->needsStackRealignment(MF)); 146 } 147 148 /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is 149 /// not required, we reserve argument space for call sites in the function 150 /// immediately on entry to the current function. This eliminates the need for 151 /// add/sub sp brackets around call sites. Returns true if the call frame is 152 /// included as part of the stack frame. 153 bool 154 AArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 155 return !MF.getFrameInfo()->hasVarSizedObjects(); 156 } 157 158 void AArch64FrameLowering::eliminateCallFramePseudoInstr( 159 MachineFunction &MF, MachineBasicBlock &MBB, 160 MachineBasicBlock::iterator I) const { 161 const AArch64InstrInfo *TII = 162 static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo()); 163 DebugLoc DL = I->getDebugLoc(); 164 unsigned Opc = I->getOpcode(); 165 bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode(); 166 uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0; 167 168 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 169 if (!TFI->hasReservedCallFrame(MF)) { 170 unsigned Align = getStackAlignment(); 171 172 int64_t Amount = I->getOperand(0).getImm(); 173 Amount = alignTo(Amount, Align); 174 if (!IsDestroy) 175 Amount = -Amount; 176 177 // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it 178 // doesn't have to pop anything), then the first operand will be zero too so 179 // this adjustment is a no-op. 180 if (CalleePopAmount == 0) { 181 // FIXME: in-function stack adjustment for calls is limited to 24-bits 182 // because there's no guaranteed temporary register available. 183 // 184 // ADD/SUB (immediate) has only LSL #0 and LSL #12 available. 185 // 1) For offset <= 12-bit, we use LSL #0 186 // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses 187 // LSL #0, and the other uses LSL #12. 188 // 189 // Most call frames will be allocated at the start of a function so 190 // this is OK, but it is a limitation that needs dealing with. 191 assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large"); 192 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, Amount, TII); 193 } 194 } else if (CalleePopAmount != 0) { 195 // If the calling convention demands that the callee pops arguments from the 196 // stack, we want to add it back if we have a reserved call frame. 197 assert(CalleePopAmount < 0xffffff && "call frame too large"); 198 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, -CalleePopAmount, 199 TII); 200 } 201 MBB.erase(I); 202 } 203 204 void AArch64FrameLowering::emitCalleeSavedFrameMoves( 205 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const { 206 MachineFunction &MF = *MBB.getParent(); 207 MachineFrameInfo *MFI = MF.getFrameInfo(); 208 MachineModuleInfo &MMI = MF.getMMI(); 209 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 210 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 211 DebugLoc DL = MBB.findDebugLoc(MBBI); 212 213 // Add callee saved registers to move list. 214 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 215 if (CSI.empty()) 216 return; 217 218 for (const auto &Info : CSI) { 219 unsigned Reg = Info.getReg(); 220 int64_t Offset = 221 MFI->getObjectOffset(Info.getFrameIdx()) - getOffsetOfLocalArea(); 222 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); 223 unsigned CFIIndex = MMI.addFrameInst( 224 MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset)); 225 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 226 .addCFIIndex(CFIIndex) 227 .setMIFlags(MachineInstr::FrameSetup); 228 } 229 } 230 231 // Find a scratch register that we can use at the start of the prologue to 232 // re-align the stack pointer. We avoid using callee-save registers since they 233 // may appear to be free when this is called from canUseAsPrologue (during 234 // shrink wrapping), but then no longer be free when this is called from 235 // emitPrologue. 236 // 237 // FIXME: This is a bit conservative, since in the above case we could use one 238 // of the callee-save registers as a scratch temp to re-align the stack pointer, 239 // but we would then have to make sure that we were in fact saving at least one 240 // callee-save register in the prologue, which is additional complexity that 241 // doesn't seem worth the benefit. 242 static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) { 243 MachineFunction *MF = MBB->getParent(); 244 245 // If MBB is an entry block, use X9 as the scratch register 246 if (&MF->front() == MBB) 247 return AArch64::X9; 248 249 RegScavenger RS; 250 RS.enterBasicBlock(MBB); 251 252 // Prefer X9 since it was historically used for the prologue scratch reg. 253 if (!RS.isRegUsed(AArch64::X9)) 254 return AArch64::X9; 255 256 // Find a free non callee-save reg. 257 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>(); 258 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); 259 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MF); 260 BitVector CalleeSaveRegs(RegInfo->getNumRegs()); 261 for (unsigned i = 0; CSRegs[i]; ++i) 262 CalleeSaveRegs.set(CSRegs[i]); 263 264 BitVector Available = RS.getRegsAvailable(&AArch64::GPR64RegClass); 265 for (int AvailReg = Available.find_first(); AvailReg != -1; 266 AvailReg = Available.find_next(AvailReg)) 267 if (!CalleeSaveRegs.test(AvailReg)) 268 return AvailReg; 269 270 return AArch64::NoRegister; 271 } 272 273 bool AArch64FrameLowering::canUseAsPrologue( 274 const MachineBasicBlock &MBB) const { 275 const MachineFunction *MF = MBB.getParent(); 276 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB); 277 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>(); 278 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); 279 280 // Don't need a scratch register if we're not going to re-align the stack. 281 if (!RegInfo->needsStackRealignment(*MF)) 282 return true; 283 // Otherwise, we can use any block as long as it has a scratch register 284 // available. 285 return findScratchNonCalleeSaveRegister(TmpMBB) != AArch64::NoRegister; 286 } 287 288 void AArch64FrameLowering::emitPrologue(MachineFunction &MF, 289 MachineBasicBlock &MBB) const { 290 MachineBasicBlock::iterator MBBI = MBB.begin(); 291 const MachineFrameInfo *MFI = MF.getFrameInfo(); 292 const Function *Fn = MF.getFunction(); 293 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); 294 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); 295 const TargetInstrInfo *TII = Subtarget.getInstrInfo(); 296 MachineModuleInfo &MMI = MF.getMMI(); 297 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 298 bool needsFrameMoves = MMI.hasDebugInfo() || Fn->needsUnwindTableEntry(); 299 bool HasFP = hasFP(MF); 300 301 // Debug location must be unknown since the first debug location is used 302 // to determine the end of the prologue. 303 DebugLoc DL; 304 305 // All calls are tail calls in GHC calling conv, and functions have no 306 // prologue/epilogue. 307 if (MF.getFunction()->getCallingConv() == CallingConv::GHC) 308 return; 309 310 int NumBytes = (int)MFI->getStackSize(); 311 if (!AFI->hasStackFrame()) { 312 assert(!HasFP && "unexpected function without stack frame but with FP"); 313 314 // All of the stack allocation is for locals. 315 AFI->setLocalStackSize(NumBytes); 316 317 // Label used to tie together the PROLOG_LABEL and the MachineMoves. 318 MCSymbol *FrameLabel = MMI.getContext().createTempSymbol(); 319 320 // REDZONE: If the stack size is less than 128 bytes, we don't need 321 // to actually allocate. 322 if (NumBytes && !canUseRedZone(MF)) { 323 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII, 324 MachineInstr::FrameSetup); 325 326 // Encode the stack size of the leaf function. 327 unsigned CFIIndex = MMI.addFrameInst( 328 MCCFIInstruction::createDefCfaOffset(FrameLabel, -NumBytes)); 329 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 330 .addCFIIndex(CFIIndex) 331 .setMIFlags(MachineInstr::FrameSetup); 332 } else if (NumBytes) { 333 ++NumRedZoneFunctions; 334 } 335 336 return; 337 } 338 339 // Only set up FP if we actually need to. 340 int FPOffset = 0; 341 if (HasFP) 342 // Frame pointer is fp = sp - 16. 343 FPOffset = AFI->getCalleeSavedStackSize() - 16; 344 345 // Move past the saves of the callee-saved registers. 346 MachineBasicBlock::iterator End = MBB.end(); 347 while (MBBI != End && MBBI->getFlag(MachineInstr::FrameSetup)) 348 ++MBBI; 349 NumBytes -= AFI->getCalleeSavedStackSize(); 350 assert(NumBytes >= 0 && "Negative stack allocation size!?"); 351 if (HasFP) { 352 // Issue sub fp, sp, FPOffset or 353 // mov fp,sp when FPOffset is zero. 354 // Note: All stores of callee-saved registers are marked as "FrameSetup". 355 // This code marks the instruction(s) that set the FP also. 356 emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP, FPOffset, TII, 357 MachineInstr::FrameSetup); 358 } 359 360 // All of the remaining stack allocations are for locals. 361 AFI->setLocalStackSize(NumBytes); 362 363 // Allocate space for the rest of the frame. 364 365 const unsigned Alignment = MFI->getMaxAlignment(); 366 const bool NeedsRealignment = RegInfo->needsStackRealignment(MF); 367 unsigned scratchSPReg = AArch64::SP; 368 if (NumBytes && NeedsRealignment) { 369 scratchSPReg = findScratchNonCalleeSaveRegister(&MBB); 370 assert(scratchSPReg != AArch64::NoRegister); 371 } 372 373 // If we're a leaf function, try using the red zone. 374 if (NumBytes && !canUseRedZone(MF)) 375 // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have 376 // the correct value here, as NumBytes also includes padding bytes, 377 // which shouldn't be counted here. 378 emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP, -NumBytes, TII, 379 MachineInstr::FrameSetup); 380 381 if (NumBytes && NeedsRealignment) { 382 const unsigned NrBitsToZero = countTrailingZeros(Alignment); 383 assert(NrBitsToZero > 1); 384 assert(scratchSPReg != AArch64::SP); 385 386 // SUB X9, SP, NumBytes 387 // -- X9 is temporary register, so shouldn't contain any live data here, 388 // -- free to use. This is already produced by emitFrameOffset above. 389 // AND SP, X9, 0b11111...0000 390 // The logical immediates have a non-trivial encoding. The following 391 // formula computes the encoded immediate with all ones but 392 // NrBitsToZero zero bits as least significant bits. 393 uint32_t andMaskEncoded = 394 (1 <<12) // = N 395 | ((64-NrBitsToZero) << 6) // immr 396 | ((64-NrBitsToZero-1) << 0) // imms 397 ; 398 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP) 399 .addReg(scratchSPReg, RegState::Kill) 400 .addImm(andMaskEncoded); 401 } 402 403 // If we need a base pointer, set it up here. It's whatever the value of the 404 // stack pointer is at this point. Any variable size objects will be allocated 405 // after this, so we can still use the base pointer to reference locals. 406 // 407 // FIXME: Clarify FrameSetup flags here. 408 // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is 409 // needed. 410 if (RegInfo->hasBasePointer(MF)) { 411 TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP, 412 false); 413 } 414 415 if (needsFrameMoves) { 416 const DataLayout &TD = MF.getDataLayout(); 417 const int StackGrowth = -TD.getPointerSize(0); 418 unsigned FramePtr = RegInfo->getFrameRegister(MF); 419 // An example of the prologue: 420 // 421 // .globl __foo 422 // .align 2 423 // __foo: 424 // Ltmp0: 425 // .cfi_startproc 426 // .cfi_personality 155, ___gxx_personality_v0 427 // Leh_func_begin: 428 // .cfi_lsda 16, Lexception33 429 // 430 // stp xa,bx, [sp, -#offset]! 431 // ... 432 // stp x28, x27, [sp, #offset-32] 433 // stp fp, lr, [sp, #offset-16] 434 // add fp, sp, #offset - 16 435 // sub sp, sp, #1360 436 // 437 // The Stack: 438 // +-------------------------------------------+ 439 // 10000 | ........ | ........ | ........ | ........ | 440 // 10004 | ........ | ........ | ........ | ........ | 441 // +-------------------------------------------+ 442 // 10008 | ........ | ........ | ........ | ........ | 443 // 1000c | ........ | ........ | ........ | ........ | 444 // +===========================================+ 445 // 10010 | X28 Register | 446 // 10014 | X28 Register | 447 // +-------------------------------------------+ 448 // 10018 | X27 Register | 449 // 1001c | X27 Register | 450 // +===========================================+ 451 // 10020 | Frame Pointer | 452 // 10024 | Frame Pointer | 453 // +-------------------------------------------+ 454 // 10028 | Link Register | 455 // 1002c | Link Register | 456 // +===========================================+ 457 // 10030 | ........ | ........ | ........ | ........ | 458 // 10034 | ........ | ........ | ........ | ........ | 459 // +-------------------------------------------+ 460 // 10038 | ........ | ........ | ........ | ........ | 461 // 1003c | ........ | ........ | ........ | ........ | 462 // +-------------------------------------------+ 463 // 464 // [sp] = 10030 :: >>initial value<< 465 // sp = 10020 :: stp fp, lr, [sp, #-16]! 466 // fp = sp == 10020 :: mov fp, sp 467 // [sp] == 10020 :: stp x28, x27, [sp, #-16]! 468 // sp == 10010 :: >>final value<< 469 // 470 // The frame pointer (w29) points to address 10020. If we use an offset of 471 // '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24 472 // for w27, and -32 for w28: 473 // 474 // Ltmp1: 475 // .cfi_def_cfa w29, 16 476 // Ltmp2: 477 // .cfi_offset w30, -8 478 // Ltmp3: 479 // .cfi_offset w29, -16 480 // Ltmp4: 481 // .cfi_offset w27, -24 482 // Ltmp5: 483 // .cfi_offset w28, -32 484 485 if (HasFP) { 486 // Define the current CFA rule to use the provided FP. 487 unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true); 488 unsigned CFIIndex = MMI.addFrameInst( 489 MCCFIInstruction::createDefCfa(nullptr, Reg, 2 * StackGrowth)); 490 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 491 .addCFIIndex(CFIIndex) 492 .setMIFlags(MachineInstr::FrameSetup); 493 } else { 494 // Encode the stack size of the leaf function. 495 unsigned CFIIndex = MMI.addFrameInst( 496 MCCFIInstruction::createDefCfaOffset(nullptr, -MFI->getStackSize())); 497 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 498 .addCFIIndex(CFIIndex) 499 .setMIFlags(MachineInstr::FrameSetup); 500 } 501 502 // Now emit the moves for whatever callee saved regs we have (including FP, 503 // LR if those are saved). 504 emitCalleeSavedFrameMoves(MBB, MBBI); 505 } 506 } 507 508 void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, 509 MachineBasicBlock &MBB) const { 510 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 511 MachineFrameInfo *MFI = MF.getFrameInfo(); 512 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); 513 const TargetInstrInfo *TII = Subtarget.getInstrInfo(); 514 DebugLoc DL; 515 bool IsTailCallReturn = false; 516 if (MBB.end() != MBBI) { 517 DL = MBBI->getDebugLoc(); 518 unsigned RetOpcode = MBBI->getOpcode(); 519 IsTailCallReturn = RetOpcode == AArch64::TCRETURNdi || 520 RetOpcode == AArch64::TCRETURNri; 521 } 522 int NumBytes = MFI->getStackSize(); 523 const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 524 525 // All calls are tail calls in GHC calling conv, and functions have no 526 // prologue/epilogue. 527 if (MF.getFunction()->getCallingConv() == CallingConv::GHC) 528 return; 529 530 // Initial and residual are named for consistency with the prologue. Note that 531 // in the epilogue, the residual adjustment is executed first. 532 uint64_t ArgumentPopSize = 0; 533 if (IsTailCallReturn) { 534 MachineOperand &StackAdjust = MBBI->getOperand(1); 535 536 // For a tail-call in a callee-pops-arguments environment, some or all of 537 // the stack may actually be in use for the call's arguments, this is 538 // calculated during LowerCall and consumed here... 539 ArgumentPopSize = StackAdjust.getImm(); 540 } else { 541 // ... otherwise the amount to pop is *all* of the argument space, 542 // conveniently stored in the MachineFunctionInfo by 543 // LowerFormalArguments. This will, of course, be zero for the C calling 544 // convention. 545 ArgumentPopSize = AFI->getArgumentStackToRestore(); 546 } 547 548 // The stack frame should be like below, 549 // 550 // ---------------------- --- 551 // | | | 552 // | BytesInStackArgArea| CalleeArgStackSize 553 // | (NumReusableBytes) | (of tail call) 554 // | | --- 555 // | | | 556 // ---------------------| --- | 557 // | | | | 558 // | CalleeSavedReg | | | 559 // | (CalleeSavedStackSize)| | | 560 // | | | | 561 // ---------------------| | NumBytes 562 // | | StackSize (StackAdjustUp) 563 // | LocalStackSize | | | 564 // | (covering callee | | | 565 // | args) | | | 566 // | | | | 567 // ---------------------- --- --- 568 // 569 // So NumBytes = StackSize + BytesInStackArgArea - CalleeArgStackSize 570 // = StackSize + ArgumentPopSize 571 // 572 // AArch64TargetLowering::LowerCall figures out ArgumentPopSize and keeps 573 // it as the 2nd argument of AArch64ISD::TC_RETURN. 574 575 // Move past the restores of the callee-saved registers. 576 MachineBasicBlock::iterator LastPopI = MBB.getFirstTerminator(); 577 MachineBasicBlock::iterator Begin = MBB.begin(); 578 while (LastPopI != Begin) { 579 --LastPopI; 580 if (!LastPopI->getFlag(MachineInstr::FrameDestroy)) { 581 ++LastPopI; 582 break; 583 } 584 } 585 NumBytes -= AFI->getCalleeSavedStackSize(); 586 assert(NumBytes >= 0 && "Negative stack allocation size!?"); 587 588 if (!hasFP(MF)) { 589 bool RedZone = canUseRedZone(MF); 590 // If this was a redzone leaf function, we don't need to restore the 591 // stack pointer (but we may need to pop stack args for fastcc). 592 if (RedZone && ArgumentPopSize == 0) 593 return; 594 595 bool NoCalleeSaveRestore = AFI->getCalleeSavedStackSize() == 0; 596 int StackRestoreBytes = RedZone ? 0 : NumBytes; 597 if (NoCalleeSaveRestore) 598 StackRestoreBytes += ArgumentPopSize; 599 emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP, 600 StackRestoreBytes, TII, MachineInstr::FrameDestroy); 601 // If we were able to combine the local stack pop with the argument pop, 602 // then we're done. 603 if (NoCalleeSaveRestore || ArgumentPopSize == 0) 604 return; 605 NumBytes = 0; 606 } 607 608 // Restore the original stack pointer. 609 // FIXME: Rather than doing the math here, we should instead just use 610 // non-post-indexed loads for the restores if we aren't actually going to 611 // be able to save any instructions. 612 if (NumBytes || MFI->hasVarSizedObjects()) 613 emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP, 614 -AFI->getCalleeSavedStackSize() + 16, TII, 615 MachineInstr::FrameDestroy); 616 617 // This must be placed after the callee-save restore code because that code 618 // assumes the SP is at the same location as it was after the callee-save save 619 // code in the prologue. 620 if (ArgumentPopSize) 621 emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP, 622 ArgumentPopSize, TII, MachineInstr::FrameDestroy); 623 } 624 625 /// getFrameIndexReference - Provide a base+offset reference to an FI slot for 626 /// debug info. It's the same as what we use for resolving the code-gen 627 /// references for now. FIXME: This can go wrong when references are 628 /// SP-relative and simple call frames aren't used. 629 int AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF, 630 int FI, 631 unsigned &FrameReg) const { 632 return resolveFrameIndexReference(MF, FI, FrameReg); 633 } 634 635 int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF, 636 int FI, unsigned &FrameReg, 637 bool PreferFP) const { 638 const MachineFrameInfo *MFI = MF.getFrameInfo(); 639 const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>( 640 MF.getSubtarget().getRegisterInfo()); 641 const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 642 int FPOffset = MFI->getObjectOffset(FI) + 16; 643 int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize(); 644 bool isFixed = MFI->isFixedObjectIndex(FI); 645 646 // Use frame pointer to reference fixed objects. Use it for locals if 647 // there are VLAs or a dynamically realigned SP (and thus the SP isn't 648 // reliable as a base). Make sure useFPForScavengingIndex() does the 649 // right thing for the emergency spill slot. 650 bool UseFP = false; 651 if (AFI->hasStackFrame()) { 652 // Note: Keeping the following as multiple 'if' statements rather than 653 // merging to a single expression for readability. 654 // 655 // Argument access should always use the FP. 656 if (isFixed) { 657 UseFP = hasFP(MF); 658 } else if (hasFP(MF) && !RegInfo->hasBasePointer(MF) && 659 !RegInfo->needsStackRealignment(MF)) { 660 // Use SP or FP, whichever gives us the best chance of the offset 661 // being in range for direct access. If the FPOffset is positive, 662 // that'll always be best, as the SP will be even further away. 663 // If the FPOffset is negative, we have to keep in mind that the 664 // available offset range for negative offsets is smaller than for 665 // positive ones. If we have variable sized objects, we're stuck with 666 // using the FP regardless, though, as the SP offset is unknown 667 // and we don't have a base pointer available. If an offset is 668 // available via the FP and the SP, use whichever is closest. 669 if (PreferFP || MFI->hasVarSizedObjects() || FPOffset >= 0 || 670 (FPOffset >= -256 && Offset > -FPOffset)) 671 UseFP = true; 672 } 673 } 674 675 assert((isFixed || !RegInfo->needsStackRealignment(MF) || !UseFP) && 676 "In the presence of dynamic stack pointer realignment, " 677 "non-argument objects cannot be accessed through the frame pointer"); 678 679 if (UseFP) { 680 FrameReg = RegInfo->getFrameRegister(MF); 681 return FPOffset; 682 } 683 684 // Use the base pointer if we have one. 685 if (RegInfo->hasBasePointer(MF)) 686 FrameReg = RegInfo->getBaseRegister(); 687 else { 688 FrameReg = AArch64::SP; 689 // If we're using the red zone for this function, the SP won't actually 690 // be adjusted, so the offsets will be negative. They're also all 691 // within range of the signed 9-bit immediate instructions. 692 if (canUseRedZone(MF)) 693 Offset -= AFI->getLocalStackSize(); 694 } 695 696 return Offset; 697 } 698 699 static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) { 700 if (Reg != AArch64::LR) 701 return getKillRegState(true); 702 703 // LR maybe referred to later by an @llvm.returnaddress intrinsic. 704 bool LRLiveIn = MF.getRegInfo().isLiveIn(AArch64::LR); 705 bool LRKill = !(LRLiveIn && MF.getFrameInfo()->isReturnAddressTaken()); 706 return getKillRegState(LRKill); 707 } 708 709 struct RegPairInfo { 710 RegPairInfo() : Reg1(AArch64::NoRegister), Reg2(AArch64::NoRegister) {} 711 unsigned Reg1; 712 unsigned Reg2; 713 int FrameIdx; 714 int Offset; 715 bool IsGPR; 716 bool isPaired() const { return Reg2 != AArch64::NoRegister; } 717 }; 718 719 static void computeCalleeSaveRegisterPairs( 720 MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI, 721 const TargetRegisterInfo *TRI, SmallVectorImpl<RegPairInfo> &RegPairs) { 722 723 if (CSI.empty()) 724 return; 725 726 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 727 MachineFrameInfo *MFI = MF.getFrameInfo(); 728 unsigned Count = CSI.size(); 729 // MachO's compact unwind format relies on all registers being stored in 730 // pairs. 731 assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() || 732 (Count & 1) == 0) && 733 "Odd number of callee-saved regs to spill!"); 734 unsigned Offset = AFI->getCalleeSavedStackSize(); 735 736 for (unsigned i = 0; i < Count; ++i) { 737 RegPairInfo RPI; 738 RPI.Reg1 = CSI[i].getReg(); 739 740 assert(AArch64::GPR64RegClass.contains(RPI.Reg1) || 741 AArch64::FPR64RegClass.contains(RPI.Reg1)); 742 RPI.IsGPR = AArch64::GPR64RegClass.contains(RPI.Reg1); 743 744 // Add the next reg to the pair if it is in the same register class. 745 if (i + 1 < Count) { 746 unsigned NextReg = CSI[i + 1].getReg(); 747 if ((RPI.IsGPR && AArch64::GPR64RegClass.contains(NextReg)) || 748 (!RPI.IsGPR && AArch64::FPR64RegClass.contains(NextReg))) 749 RPI.Reg2 = NextReg; 750 } 751 752 // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI 753 // list to come in sorted by frame index so that we can issue the store 754 // pair instructions directly. Assert if we see anything otherwise. 755 // 756 // The order of the registers in the list is controlled by 757 // getCalleeSavedRegs(), so they will always be in-order, as well. 758 assert((!RPI.isPaired() || 759 (CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx())) && 760 "Out of order callee saved regs!"); 761 762 // MachO's compact unwind format relies on all registers being stored in 763 // adjacent register pairs. 764 assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() || 765 (RPI.isPaired() && 766 ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) || 767 RPI.Reg1 + 1 == RPI.Reg2))) && 768 "Callee-save registers not saved as adjacent register pair!"); 769 770 RPI.FrameIdx = CSI[i].getFrameIdx(); 771 772 if (Count * 8 != AFI->getCalleeSavedStackSize() && !RPI.isPaired()) { 773 // Round up size of non-pair to pair size if we need to pad the 774 // callee-save area to ensure 16-byte alignment. 775 Offset -= 16; 776 assert(MFI->getObjectAlignment(RPI.FrameIdx) <= 16); 777 MFI->setObjectSize(RPI.FrameIdx, 16); 778 } else 779 Offset -= RPI.isPaired() ? 16 : 8; 780 assert(Offset % 8 == 0); 781 RPI.Offset = Offset / 8; 782 assert((RPI.Offset >= -64 && RPI.Offset <= 63) && 783 "Offset out of bounds for LDP/STP immediate"); 784 785 RegPairs.push_back(RPI); 786 if (RPI.isPaired()) 787 ++i; 788 } 789 790 // Align first offset to even 16-byte boundary to avoid additional SP 791 // adjustment instructions. 792 // Last pair offset is size of whole callee-save region for SP 793 // pre-dec/post-inc. 794 RegPairInfo &LastPair = RegPairs.back(); 795 assert(AFI->getCalleeSavedStackSize() % 8 == 0); 796 LastPair.Offset = AFI->getCalleeSavedStackSize() / 8; 797 } 798 799 bool AArch64FrameLowering::spillCalleeSavedRegisters( 800 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 801 const std::vector<CalleeSavedInfo> &CSI, 802 const TargetRegisterInfo *TRI) const { 803 MachineFunction &MF = *MBB.getParent(); 804 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 805 DebugLoc DL; 806 SmallVector<RegPairInfo, 8> RegPairs; 807 808 computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs); 809 810 for (auto RPII = RegPairs.rbegin(), RPIE = RegPairs.rend(); RPII != RPIE; 811 ++RPII) { 812 RegPairInfo RPI = *RPII; 813 unsigned Reg1 = RPI.Reg1; 814 unsigned Reg2 = RPI.Reg2; 815 unsigned StrOpc; 816 817 // Issue sequence of non-sp increment and pi sp spills for cs regs. The 818 // first spill is a pre-increment that allocates the stack. 819 // For example: 820 // stp x22, x21, [sp, #-48]! // addImm(-6) 821 // stp x20, x19, [sp, #16] // addImm(+2) 822 // stp fp, lr, [sp, #32] // addImm(+4) 823 // Rationale: This sequence saves uop updates compared to a sequence of 824 // pre-increment spills like stp xi,xj,[sp,#-16]! 825 // Note: Similar rationale and sequence for restores in epilog. 826 bool BumpSP = RPII == RegPairs.rbegin(); 827 if (RPI.IsGPR) { 828 // For first spill use pre-increment store. 829 if (BumpSP) 830 StrOpc = RPI.isPaired() ? AArch64::STPXpre : AArch64::STRXpre; 831 else 832 StrOpc = RPI.isPaired() ? AArch64::STPXi : AArch64::STRXui; 833 } else { 834 // For first spill use pre-increment store. 835 if (BumpSP) 836 StrOpc = RPI.isPaired() ? AArch64::STPDpre : AArch64::STRDpre; 837 else 838 StrOpc = RPI.isPaired() ? AArch64::STPDi : AArch64::STRDui; 839 } 840 DEBUG(dbgs() << "CSR spill: (" << TRI->getName(Reg1); 841 if (RPI.isPaired()) 842 dbgs() << ", " << TRI->getName(Reg2); 843 dbgs() << ") -> fi#(" << RPI.FrameIdx; 844 if (RPI.isPaired()) 845 dbgs() << ", " << RPI.FrameIdx+1; 846 dbgs() << ")\n"); 847 848 const int Offset = BumpSP ? -RPI.Offset : RPI.Offset; 849 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc)); 850 if (BumpSP) 851 MIB.addReg(AArch64::SP, RegState::Define); 852 853 if (RPI.isPaired()) { 854 MBB.addLiveIn(Reg1); 855 MBB.addLiveIn(Reg2); 856 MIB.addReg(Reg2, getPrologueDeath(MF, Reg2)) 857 .addReg(Reg1, getPrologueDeath(MF, Reg1)) 858 .addReg(AArch64::SP) 859 .addImm(Offset) // [sp, #offset * 8], where factor * 8 is implicit 860 .setMIFlag(MachineInstr::FrameSetup); 861 } else { 862 MBB.addLiveIn(Reg1); 863 MIB.addReg(Reg1, getPrologueDeath(MF, Reg1)) 864 .addReg(AArch64::SP) 865 .addImm(BumpSP ? Offset * 8 : Offset) // pre-inc version is unscaled 866 .setMIFlag(MachineInstr::FrameSetup); 867 } 868 } 869 return true; 870 } 871 872 bool AArch64FrameLowering::restoreCalleeSavedRegisters( 873 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 874 const std::vector<CalleeSavedInfo> &CSI, 875 const TargetRegisterInfo *TRI) const { 876 MachineFunction &MF = *MBB.getParent(); 877 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 878 DebugLoc DL; 879 SmallVector<RegPairInfo, 8> RegPairs; 880 881 if (MI != MBB.end()) 882 DL = MI->getDebugLoc(); 883 884 computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs); 885 886 for (auto RPII = RegPairs.begin(), RPIE = RegPairs.end(); RPII != RPIE; 887 ++RPII) { 888 RegPairInfo RPI = *RPII; 889 unsigned Reg1 = RPI.Reg1; 890 unsigned Reg2 = RPI.Reg2; 891 892 // Issue sequence of non-sp increment and sp-pi restores for cs regs. Only 893 // the last load is sp-pi post-increment and de-allocates the stack: 894 // For example: 895 // ldp fp, lr, [sp, #32] // addImm(+4) 896 // ldp x20, x19, [sp, #16] // addImm(+2) 897 // ldp x22, x21, [sp], #48 // addImm(+6) 898 // Note: see comment in spillCalleeSavedRegisters() 899 unsigned LdrOpc; 900 bool BumpSP = RPII == std::prev(RegPairs.end()); 901 if (RPI.IsGPR) { 902 if (BumpSP) 903 LdrOpc = RPI.isPaired() ? AArch64::LDPXpost : AArch64::LDRXpost; 904 else 905 LdrOpc = RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui; 906 } else { 907 if (BumpSP) 908 LdrOpc = RPI.isPaired() ? AArch64::LDPDpost : AArch64::LDRDpost; 909 else 910 LdrOpc = RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui; 911 } 912 DEBUG(dbgs() << "CSR restore: (" << TRI->getName(Reg1); 913 if (RPI.isPaired()) 914 dbgs() << ", " << TRI->getName(Reg2); 915 dbgs() << ") -> fi#(" << RPI.FrameIdx; 916 if (RPI.isPaired()) 917 dbgs() << ", " << RPI.FrameIdx+1; 918 dbgs() << ")\n"); 919 920 const int Offset = RPI.Offset; 921 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(LdrOpc)); 922 if (BumpSP) 923 MIB.addReg(AArch64::SP, RegState::Define); 924 925 if (RPI.isPaired()) 926 MIB.addReg(Reg2, getDefRegState(true)) 927 .addReg(Reg1, getDefRegState(true)) 928 .addReg(AArch64::SP) 929 .addImm(Offset) // [sp], #offset * 8 or [sp, #offset * 8] 930 // where the factor * 8 is implicit 931 .setMIFlag(MachineInstr::FrameDestroy); 932 else 933 MIB.addReg(Reg1, getDefRegState(true)) 934 .addReg(AArch64::SP) 935 .addImm(BumpSP ? Offset * 8 : Offset) // post-dec version is unscaled 936 .setMIFlag(MachineInstr::FrameDestroy); 937 } 938 return true; 939 } 940 941 void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, 942 BitVector &SavedRegs, 943 RegScavenger *RS) const { 944 // All calls are tail calls in GHC calling conv, and functions have no 945 // prologue/epilogue. 946 if (MF.getFunction()->getCallingConv() == CallingConv::GHC) 947 return; 948 949 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 950 const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>( 951 MF.getSubtarget().getRegisterInfo()); 952 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 953 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); 954 unsigned UnspilledCSGPR = AArch64::NoRegister; 955 unsigned UnspilledCSGPRPaired = AArch64::NoRegister; 956 957 // The frame record needs to be created by saving the appropriate registers 958 if (hasFP(MF)) { 959 SavedRegs.set(AArch64::FP); 960 SavedRegs.set(AArch64::LR); 961 } 962 963 unsigned BasePointerReg = AArch64::NoRegister; 964 if (RegInfo->hasBasePointer(MF)) 965 BasePointerReg = RegInfo->getBaseRegister(); 966 967 bool ExtraCSSpill = false; 968 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF); 969 // Figure out which callee-saved registers to save/restore. 970 for (unsigned i = 0; CSRegs[i]; ++i) { 971 const unsigned Reg = CSRegs[i]; 972 973 // Add the base pointer register to SavedRegs if it is callee-save. 974 if (Reg == BasePointerReg) 975 SavedRegs.set(Reg); 976 977 bool RegUsed = SavedRegs.test(Reg); 978 unsigned PairedReg = CSRegs[i ^ 1]; 979 if (!RegUsed) { 980 if (AArch64::GPR64RegClass.contains(Reg) && 981 !RegInfo->isReservedReg(MF, Reg)) { 982 UnspilledCSGPR = Reg; 983 UnspilledCSGPRPaired = PairedReg; 984 } 985 continue; 986 } 987 988 // MachO's compact unwind format relies on all registers being stored in 989 // pairs. 990 // FIXME: the usual format is actually better if unwinding isn't needed. 991 if (Subtarget.isTargetMachO() && !SavedRegs.test(PairedReg)) { 992 SavedRegs.set(PairedReg); 993 ExtraCSSpill = true; 994 } 995 } 996 997 DEBUG(dbgs() << "*** determineCalleeSaves\nUsed CSRs:"; 998 for (int Reg = SavedRegs.find_first(); Reg != -1; 999 Reg = SavedRegs.find_next(Reg)) 1000 dbgs() << ' ' << PrintReg(Reg, RegInfo); 1001 dbgs() << "\n";); 1002 1003 // If any callee-saved registers are used, the frame cannot be eliminated. 1004 unsigned NumRegsSpilled = SavedRegs.count(); 1005 bool CanEliminateFrame = NumRegsSpilled == 0; 1006 1007 // FIXME: Set BigStack if any stack slot references may be out of range. 1008 // For now, just conservatively guestimate based on unscaled indexing 1009 // range. We'll end up allocating an unnecessary spill slot a lot, but 1010 // realistically that's not a big deal at this stage of the game. 1011 // The CSR spill slots have not been allocated yet, so estimateStackSize 1012 // won't include them. 1013 MachineFrameInfo *MFI = MF.getFrameInfo(); 1014 unsigned CFSize = MFI->estimateStackSize(MF) + 8 * NumRegsSpilled; 1015 DEBUG(dbgs() << "Estimated stack frame size: " << CFSize << " bytes.\n"); 1016 bool BigStack = (CFSize >= 256); 1017 if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) 1018 AFI->setHasStackFrame(true); 1019 1020 // Estimate if we might need to scavenge a register at some point in order 1021 // to materialize a stack offset. If so, either spill one additional 1022 // callee-saved register or reserve a special spill slot to facilitate 1023 // register scavenging. If we already spilled an extra callee-saved register 1024 // above to keep the number of spills even, we don't need to do anything else 1025 // here. 1026 if (BigStack && !ExtraCSSpill) { 1027 if (UnspilledCSGPR != AArch64::NoRegister) { 1028 DEBUG(dbgs() << "Spilling " << PrintReg(UnspilledCSGPR, RegInfo) 1029 << " to get a scratch register.\n"); 1030 SavedRegs.set(UnspilledCSGPR); 1031 // MachO's compact unwind format relies on all registers being stored in 1032 // pairs, so if we need to spill one extra for BigStack, then we need to 1033 // store the pair. 1034 if (Subtarget.isTargetMachO()) 1035 SavedRegs.set(UnspilledCSGPRPaired); 1036 ExtraCSSpill = true; 1037 NumRegsSpilled = SavedRegs.count(); 1038 } 1039 1040 // If we didn't find an extra callee-saved register to spill, create 1041 // an emergency spill slot. 1042 if (!ExtraCSSpill) { 1043 const TargetRegisterClass *RC = &AArch64::GPR64RegClass; 1044 int FI = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), false); 1045 RS->addScavengingFrameIndex(FI); 1046 DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI 1047 << " as the emergency spill slot.\n"); 1048 } 1049 } 1050 1051 // Round up to register pair alignment to avoid additional SP adjustment 1052 // instructions. 1053 AFI->setCalleeSavedStackSize(alignTo(8 * NumRegsSpilled, 16)); 1054 } 1055