void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); const HexagonRegisterInfo *QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); determineFrameLayout(MF); // Get the number of bytes to allocate from the FrameInfo. int NumBytes = (int) MFI->getStackSize(); // LLVM expects allocframe not to be the first instruction in the // basic block. MachineBasicBlock::iterator InsertPt = MBB.begin(); // // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset. // HexagonMachineFunctionInfo *FuncInfo = MF.getInfo<HexagonMachineFunctionInfo>(); const std::vector<MachineInstr*>& AdjustRegs = FuncInfo->getAllocaAdjustInsts(); for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(), e = AdjustRegs.end(); i != e; ++i) { MachineInstr* MI = *i; assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) && "Expected adjust alloca node"); MachineOperand& MO = MI->getOperand(2); assert(MO.isImm() && "Expected immediate"); MO.setImm(MFI->getMaxCallFrameSize()); } // // Only insert ALLOCFRAME if we need to. // if (hasFP(MF)) { // Check for overflow. // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? const int ALLOCFRAME_MAX = 16384; const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); if (NumBytes >= ALLOCFRAME_MAX) { // Emit allocframe(#0). BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0); // Subtract offset from frame pointer. BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(NumBytes); BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub), QRI->getStackRegister()). addReg(QRI->getStackRegister()). addReg(HEXAGON_RESERVED_REG_1); } else { BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes); } } }
void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo &MMI = MF.getMMI(); MachineBasicBlock::iterator MBBI = MBB.begin(); const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo()); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); determineFrameLayout(MF); // Check if frame moves are needed for EH. bool needsFrameMoves = MMI.hasDebugInfo() || !MF.getFunction()->needsUnwindTableEntry(); // Get the number of bytes to allocate from the FrameInfo. int NumBytes = (int) MFI->getStackSize(); // LLVM expects allocframe not to be the first instruction in the // basic block. MachineBasicBlock::iterator InsertPt = MBB.begin(); // // ALLOCA adjust regs. Iterate over ADJDYNALLOC nodes and change the offset. // HexagonMachineFunctionInfo *FuncInfo = MF.getInfo<HexagonMachineFunctionInfo>(); const std::vector<MachineInstr*>& AdjustRegs = FuncInfo->getAllocaAdjustInsts(); for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(), e = AdjustRegs.end(); i != e; ++i) { MachineInstr* MI = *i; assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) && "Expected adjust alloca node"); MachineOperand& MO = MI->getOperand(2); assert(MO.isImm() && "Expected immediate"); MO.setImm(MFI->getMaxCallFrameSize()); } std::vector<MachineMove> &Moves = MMI.getFrameMoves(); if (needsFrameMoves) { // Advance CFA. DW_CFA_def_cfa unsigned FPReg = QRI->getFrameRegister(); unsigned RAReg = QRI->getRARegister(); MachineLocation Dst(MachineLocation::VirtualFP); MachineLocation Src(FPReg, -8); Moves.push_back(MachineMove(0, Dst, Src)); // R31 = (R31 - #4) MachineLocation LRDst(RAReg, -4); MachineLocation LRSrc(RAReg); Moves.push_back(MachineMove(0, LRDst, LRSrc)); // R30 = (R30 - #8) MachineLocation SPDst(FPReg, -8); MachineLocation SPSrc(FPReg); Moves.push_back(MachineMove(0, SPDst, SPSrc)); } // // Only insert ALLOCFRAME if we need to. // if (hasFP(MF)) { // Check for overflow. // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? const int ALLOCFRAME_MAX = 16384; const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); if (NumBytes >= ALLOCFRAME_MAX) { // Emit allocframe(#0). BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0); // Subtract offset from frame pointer. BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(NumBytes); BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr), QRI->getStackRegister()). addReg(QRI->getStackRegister()). addReg(HEXAGON_RESERVED_REG_1); } else { BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes); } } }