10b57cec5SDimitry Andric //===-- AVRInstrInfo.cpp - AVR Instruction Information --------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the AVR implementation of the TargetInstrInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "AVRInstrInfo.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 200b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 210b57cec5SDimitry Andric #include "llvm/IR/Function.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 23349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 250b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #include "AVR.h" 280b57cec5SDimitry Andric #include "AVRMachineFunctionInfo.h" 290b57cec5SDimitry Andric #include "AVRRegisterInfo.h" 300b57cec5SDimitry Andric #include "AVRTargetMachine.h" 310b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCTargetDesc.h" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric #define GET_INSTRINFO_CTOR_DTOR 340b57cec5SDimitry Andric #include "AVRGenInstrInfo.inc" 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric namespace llvm { 370b57cec5SDimitry Andric 3806c3fb27SDimitry Andric AVRInstrInfo::AVRInstrInfo(AVRSubtarget &STI) 3906c3fb27SDimitry Andric : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI(), 4006c3fb27SDimitry Andric STI(STI) {} 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 430b57cec5SDimitry Andric MachineBasicBlock::iterator MI, 44480093f4SDimitry Andric const DebugLoc &DL, MCRegister DestReg, 45480093f4SDimitry Andric MCRegister SrcReg, bool KillSrc) const { 460b57cec5SDimitry Andric const AVRRegisterInfo &TRI = *STI.getRegisterInfo(); 470b57cec5SDimitry Andric unsigned Opc; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) { 5081ad6265SDimitry Andric // If our AVR has `movw`, let's emit that; otherwise let's emit two separate 5181ad6265SDimitry Andric // `mov`s. 525ffd83dbSDimitry Andric if (STI.hasMOVW() && AVR::DREGSMOVWRegClass.contains(DestReg, SrcReg)) { 530b57cec5SDimitry Andric BuildMI(MBB, MI, DL, get(AVR::MOVWRdRr), DestReg) 540b57cec5SDimitry Andric .addReg(SrcReg, getKillRegState(KillSrc)); 550b57cec5SDimitry Andric } else { 565ffd83dbSDimitry Andric Register DestLo, DestHi, SrcLo, SrcHi; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric TRI.splitReg(DestReg, DestLo, DestHi); 590b57cec5SDimitry Andric TRI.splitReg(SrcReg, SrcLo, SrcHi); 600b57cec5SDimitry Andric 6106c3fb27SDimitry Andric // Emit the copies. 6206c3fb27SDimitry Andric // The original instruction was for a register pair, of which only one 6306c3fb27SDimitry Andric // register might have been live. Add 'undef' to satisfy the machine 6406c3fb27SDimitry Andric // verifier, when subreg liveness is enabled. 6506c3fb27SDimitry Andric // TODO: Eliminate these unnecessary copies. 6681ad6265SDimitry Andric if (DestLo == SrcHi) { 6781ad6265SDimitry Andric BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi) 6806c3fb27SDimitry Andric .addReg(SrcHi, getKillRegState(KillSrc) | RegState::Undef); 6981ad6265SDimitry Andric BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo) 7006c3fb27SDimitry Andric .addReg(SrcLo, getKillRegState(KillSrc) | RegState::Undef); 7181ad6265SDimitry Andric } else { 720b57cec5SDimitry Andric BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo) 7306c3fb27SDimitry Andric .addReg(SrcLo, getKillRegState(KillSrc) | RegState::Undef); 740b57cec5SDimitry Andric BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi) 7506c3fb27SDimitry Andric .addReg(SrcHi, getKillRegState(KillSrc) | RegState::Undef); 760b57cec5SDimitry Andric } 7781ad6265SDimitry Andric } 780b57cec5SDimitry Andric } else { 790b57cec5SDimitry Andric if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) { 800b57cec5SDimitry Andric Opc = AVR::MOVRdRr; 810b57cec5SDimitry Andric } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) { 820b57cec5SDimitry Andric Opc = AVR::SPREAD; 830b57cec5SDimitry Andric } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) { 840b57cec5SDimitry Andric Opc = AVR::SPWRITE; 850b57cec5SDimitry Andric } else { 860b57cec5SDimitry Andric llvm_unreachable("Impossible reg-to-reg copy"); 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric BuildMI(MBB, MI, DL, get(Opc), DestReg) 900b57cec5SDimitry Andric .addReg(SrcReg, getKillRegState(KillSrc)); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 94*0fca6ea1SDimitry Andric Register AVRInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 950b57cec5SDimitry Andric int &FrameIndex) const { 960b57cec5SDimitry Andric switch (MI.getOpcode()) { 970b57cec5SDimitry Andric case AVR::LDDRdPtrQ: 980b57cec5SDimitry Andric case AVR::LDDWRdYQ: { //: FIXME: remove this once PR13375 gets fixed 990b57cec5SDimitry Andric if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 1000b57cec5SDimitry Andric MI.getOperand(2).getImm() == 0) { 1010b57cec5SDimitry Andric FrameIndex = MI.getOperand(1).getIndex(); 1020b57cec5SDimitry Andric return MI.getOperand(0).getReg(); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric break; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric default: 1070b57cec5SDimitry Andric break; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric return 0; 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 113*0fca6ea1SDimitry Andric Register AVRInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 1140b57cec5SDimitry Andric int &FrameIndex) const { 1150b57cec5SDimitry Andric switch (MI.getOpcode()) { 1160b57cec5SDimitry Andric case AVR::STDPtrQRr: 1170b57cec5SDimitry Andric case AVR::STDWPtrQRr: { 1180b57cec5SDimitry Andric if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() && 1190b57cec5SDimitry Andric MI.getOperand(1).getImm() == 0) { 1200b57cec5SDimitry Andric FrameIndex = MI.getOperand(0).getIndex(); 1210b57cec5SDimitry Andric return MI.getOperand(2).getReg(); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric break; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric default: 1260b57cec5SDimitry Andric break; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric return 0; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 132bdd1243dSDimitry Andric void AVRInstrInfo::storeRegToStackSlot( 133bdd1243dSDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, 134bdd1243dSDimitry Andric bool isKill, int FrameIndex, const TargetRegisterClass *RC, 135bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, Register VReg) const { 1360b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 1370b57cec5SDimitry Andric AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric AFI->setHasSpills(true); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric MachineMemOperand *MMO = MF.getMachineMemOperand( 1440b57cec5SDimitry Andric MachinePointerInfo::getFixedStack(MF, FrameIndex), 1450b57cec5SDimitry Andric MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex), 1465ffd83dbSDimitry Andric MFI.getObjectAlign(FrameIndex)); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric unsigned Opcode = 0; 1490b57cec5SDimitry Andric if (TRI->isTypeLegalForClass(*RC, MVT::i8)) { 1500b57cec5SDimitry Andric Opcode = AVR::STDPtrQRr; 1510b57cec5SDimitry Andric } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) { 1520b57cec5SDimitry Andric Opcode = AVR::STDWPtrQRr; 1530b57cec5SDimitry Andric } else { 1540b57cec5SDimitry Andric llvm_unreachable("Cannot store this register into a stack slot!"); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 157bdd1243dSDimitry Andric BuildMI(MBB, MI, DebugLoc(), get(Opcode)) 1580b57cec5SDimitry Andric .addFrameIndex(FrameIndex) 1590b57cec5SDimitry Andric .addImm(0) 1600b57cec5SDimitry Andric .addReg(SrcReg, getKillRegState(isKill)) 1610b57cec5SDimitry Andric .addMemOperand(MMO); 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 1650b57cec5SDimitry Andric MachineBasicBlock::iterator MI, 1665ffd83dbSDimitry Andric Register DestReg, int FrameIndex, 1670b57cec5SDimitry Andric const TargetRegisterClass *RC, 168bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, 169bdd1243dSDimitry Andric Register VReg) const { 1700b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 1710b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric MachineMemOperand *MMO = MF.getMachineMemOperand( 1740b57cec5SDimitry Andric MachinePointerInfo::getFixedStack(MF, FrameIndex), 1750b57cec5SDimitry Andric MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), 1765ffd83dbSDimitry Andric MFI.getObjectAlign(FrameIndex)); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric unsigned Opcode = 0; 1790b57cec5SDimitry Andric if (TRI->isTypeLegalForClass(*RC, MVT::i8)) { 1800b57cec5SDimitry Andric Opcode = AVR::LDDRdPtrQ; 1810b57cec5SDimitry Andric } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) { 1820b57cec5SDimitry Andric // Opcode = AVR::LDDWRdPtrQ; 1830b57cec5SDimitry Andric //: FIXME: remove this once PR13375 gets fixed 1840b57cec5SDimitry Andric Opcode = AVR::LDDWRdYQ; 1850b57cec5SDimitry Andric } else { 1860b57cec5SDimitry Andric llvm_unreachable("Cannot load this register from a stack slot!"); 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 189bdd1243dSDimitry Andric BuildMI(MBB, MI, DebugLoc(), get(Opcode), DestReg) 1900b57cec5SDimitry Andric .addFrameIndex(FrameIndex) 1910b57cec5SDimitry Andric .addImm(0) 1920b57cec5SDimitry Andric .addMemOperand(MMO); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric const MCInstrDesc &AVRInstrInfo::getBrCond(AVRCC::CondCodes CC) const { 1960b57cec5SDimitry Andric switch (CC) { 1970b57cec5SDimitry Andric default: 1980b57cec5SDimitry Andric llvm_unreachable("Unknown condition code!"); 1990b57cec5SDimitry Andric case AVRCC::COND_EQ: 2000b57cec5SDimitry Andric return get(AVR::BREQk); 2010b57cec5SDimitry Andric case AVRCC::COND_NE: 2020b57cec5SDimitry Andric return get(AVR::BRNEk); 2030b57cec5SDimitry Andric case AVRCC::COND_GE: 2040b57cec5SDimitry Andric return get(AVR::BRGEk); 2050b57cec5SDimitry Andric case AVRCC::COND_LT: 2060b57cec5SDimitry Andric return get(AVR::BRLTk); 2070b57cec5SDimitry Andric case AVRCC::COND_SH: 2080b57cec5SDimitry Andric return get(AVR::BRSHk); 2090b57cec5SDimitry Andric case AVRCC::COND_LO: 2100b57cec5SDimitry Andric return get(AVR::BRLOk); 2110b57cec5SDimitry Andric case AVRCC::COND_MI: 2120b57cec5SDimitry Andric return get(AVR::BRMIk); 2130b57cec5SDimitry Andric case AVRCC::COND_PL: 2140b57cec5SDimitry Andric return get(AVR::BRPLk); 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric AVRCC::CondCodes AVRInstrInfo::getCondFromBranchOpc(unsigned Opc) const { 2190b57cec5SDimitry Andric switch (Opc) { 2200b57cec5SDimitry Andric default: 2210b57cec5SDimitry Andric return AVRCC::COND_INVALID; 2220b57cec5SDimitry Andric case AVR::BREQk: 2230b57cec5SDimitry Andric return AVRCC::COND_EQ; 2240b57cec5SDimitry Andric case AVR::BRNEk: 2250b57cec5SDimitry Andric return AVRCC::COND_NE; 2260b57cec5SDimitry Andric case AVR::BRSHk: 2270b57cec5SDimitry Andric return AVRCC::COND_SH; 2280b57cec5SDimitry Andric case AVR::BRLOk: 2290b57cec5SDimitry Andric return AVRCC::COND_LO; 2300b57cec5SDimitry Andric case AVR::BRMIk: 2310b57cec5SDimitry Andric return AVRCC::COND_MI; 2320b57cec5SDimitry Andric case AVR::BRPLk: 2330b57cec5SDimitry Andric return AVRCC::COND_PL; 2340b57cec5SDimitry Andric case AVR::BRGEk: 2350b57cec5SDimitry Andric return AVRCC::COND_GE; 2360b57cec5SDimitry Andric case AVR::BRLTk: 2370b57cec5SDimitry Andric return AVRCC::COND_LT; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric AVRCC::CondCodes AVRInstrInfo::getOppositeCondition(AVRCC::CondCodes CC) const { 2420b57cec5SDimitry Andric switch (CC) { 2430b57cec5SDimitry Andric default: 2440b57cec5SDimitry Andric llvm_unreachable("Invalid condition!"); 2450b57cec5SDimitry Andric case AVRCC::COND_EQ: 2460b57cec5SDimitry Andric return AVRCC::COND_NE; 2470b57cec5SDimitry Andric case AVRCC::COND_NE: 2480b57cec5SDimitry Andric return AVRCC::COND_EQ; 2490b57cec5SDimitry Andric case AVRCC::COND_SH: 2500b57cec5SDimitry Andric return AVRCC::COND_LO; 2510b57cec5SDimitry Andric case AVRCC::COND_LO: 2520b57cec5SDimitry Andric return AVRCC::COND_SH; 2530b57cec5SDimitry Andric case AVRCC::COND_GE: 2540b57cec5SDimitry Andric return AVRCC::COND_LT; 2550b57cec5SDimitry Andric case AVRCC::COND_LT: 2560b57cec5SDimitry Andric return AVRCC::COND_GE; 2570b57cec5SDimitry Andric case AVRCC::COND_MI: 2580b57cec5SDimitry Andric return AVRCC::COND_PL; 2590b57cec5SDimitry Andric case AVRCC::COND_PL: 2600b57cec5SDimitry Andric return AVRCC::COND_MI; 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric bool AVRInstrInfo::analyzeBranch(MachineBasicBlock &MBB, 2650b57cec5SDimitry Andric MachineBasicBlock *&TBB, 2660b57cec5SDimitry Andric MachineBasicBlock *&FBB, 2670b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 2680b57cec5SDimitry Andric bool AllowModify) const { 2690b57cec5SDimitry Andric // Start from the bottom of the block and work up, examining the 2700b57cec5SDimitry Andric // terminator instructions. 2710b57cec5SDimitry Andric MachineBasicBlock::iterator I = MBB.end(); 2720b57cec5SDimitry Andric MachineBasicBlock::iterator UnCondBrIter = MBB.end(); 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric while (I != MBB.begin()) { 2750b57cec5SDimitry Andric --I; 2760b57cec5SDimitry Andric if (I->isDebugInstr()) { 2770b57cec5SDimitry Andric continue; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric // Working from the bottom, when we see a non-terminator 2810b57cec5SDimitry Andric // instruction, we're done. 2820b57cec5SDimitry Andric if (!isUnpredicatedTerminator(*I)) { 2830b57cec5SDimitry Andric break; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // A terminator that isn't a branch can't easily be handled 2870b57cec5SDimitry Andric // by this analysis. 2880b57cec5SDimitry Andric if (!I->getDesc().isBranch()) { 2890b57cec5SDimitry Andric return true; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // Handle unconditional branches. 2930b57cec5SDimitry Andric //: TODO: add here jmp 2940b57cec5SDimitry Andric if (I->getOpcode() == AVR::RJMPk) { 2950b57cec5SDimitry Andric UnCondBrIter = I; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric if (!AllowModify) { 2980b57cec5SDimitry Andric TBB = I->getOperand(0).getMBB(); 2990b57cec5SDimitry Andric continue; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric // If the block has any instructions after a JMP, delete them. 30381ad6265SDimitry Andric MBB.erase(std::next(I), MBB.end()); 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric Cond.clear(); 30604eeddc0SDimitry Andric FBB = nullptr; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // Delete the JMP if it's equivalent to a fall-through. 3090b57cec5SDimitry Andric if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 31004eeddc0SDimitry Andric TBB = nullptr; 3110b57cec5SDimitry Andric I->eraseFromParent(); 3120b57cec5SDimitry Andric I = MBB.end(); 3130b57cec5SDimitry Andric UnCondBrIter = MBB.end(); 3140b57cec5SDimitry Andric continue; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric // TBB is used to indicate the unconditinal destination. 3180b57cec5SDimitry Andric TBB = I->getOperand(0).getMBB(); 3190b57cec5SDimitry Andric continue; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric // Handle conditional branches. 3230b57cec5SDimitry Andric AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode()); 3240b57cec5SDimitry Andric if (BranchCode == AVRCC::COND_INVALID) { 3250b57cec5SDimitry Andric return true; // Can't handle indirect branch. 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric // Working from the bottom, handle the first conditional branch. 3290b57cec5SDimitry Andric if (Cond.empty()) { 3300b57cec5SDimitry Andric MachineBasicBlock *TargetBB = I->getOperand(0).getMBB(); 3310b57cec5SDimitry Andric if (AllowModify && UnCondBrIter != MBB.end() && 3320b57cec5SDimitry Andric MBB.isLayoutSuccessor(TargetBB)) { 3330b57cec5SDimitry Andric // If we can modify the code and it ends in something like: 3340b57cec5SDimitry Andric // 3350b57cec5SDimitry Andric // jCC L1 3360b57cec5SDimitry Andric // jmp L2 3370b57cec5SDimitry Andric // L1: 3380b57cec5SDimitry Andric // ... 3390b57cec5SDimitry Andric // L2: 3400b57cec5SDimitry Andric // 3410b57cec5SDimitry Andric // Then we can change this to: 3420b57cec5SDimitry Andric // 3430b57cec5SDimitry Andric // jnCC L2 3440b57cec5SDimitry Andric // L1: 3450b57cec5SDimitry Andric // ... 3460b57cec5SDimitry Andric // L2: 3470b57cec5SDimitry Andric // 3480b57cec5SDimitry Andric // Which is a bit more efficient. 3490b57cec5SDimitry Andric // We conditionally jump to the fall-through block. 3500b57cec5SDimitry Andric BranchCode = getOppositeCondition(BranchCode); 3510b57cec5SDimitry Andric unsigned JNCC = getBrCond(BranchCode).getOpcode(); 3520b57cec5SDimitry Andric MachineBasicBlock::iterator OldInst = I; 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC)) 3550b57cec5SDimitry Andric .addMBB(UnCondBrIter->getOperand(0).getMBB()); 3560b57cec5SDimitry Andric BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk)) 3570b57cec5SDimitry Andric .addMBB(TargetBB); 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric OldInst->eraseFromParent(); 3600b57cec5SDimitry Andric UnCondBrIter->eraseFromParent(); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric // Restart the analysis. 3630b57cec5SDimitry Andric UnCondBrIter = MBB.end(); 3640b57cec5SDimitry Andric I = MBB.end(); 3650b57cec5SDimitry Andric continue; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric FBB = TBB; 3690b57cec5SDimitry Andric TBB = I->getOperand(0).getMBB(); 3700b57cec5SDimitry Andric Cond.push_back(MachineOperand::CreateImm(BranchCode)); 3710b57cec5SDimitry Andric continue; 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric // Handle subsequent conditional branches. Only handle the case where all 3750b57cec5SDimitry Andric // conditional branches branch to the same destination. 3760b57cec5SDimitry Andric assert(Cond.size() == 1); 3770b57cec5SDimitry Andric assert(TBB); 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric // Only handle the case where all conditional branches branch to 3800b57cec5SDimitry Andric // the same destination. 3810b57cec5SDimitry Andric if (TBB != I->getOperand(0).getMBB()) { 3820b57cec5SDimitry Andric return true; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric AVRCC::CondCodes OldBranchCode = (AVRCC::CondCodes)Cond[0].getImm(); 3860b57cec5SDimitry Andric // If the conditions are the same, we can leave them alone. 3870b57cec5SDimitry Andric if (OldBranchCode == BranchCode) { 3880b57cec5SDimitry Andric continue; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric return true; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric return false; 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB, 3980b57cec5SDimitry Andric MachineBasicBlock *TBB, 3990b57cec5SDimitry Andric MachineBasicBlock *FBB, 4000b57cec5SDimitry Andric ArrayRef<MachineOperand> Cond, 401349cc55cSDimitry Andric const DebugLoc &DL, int *BytesAdded) const { 402349cc55cSDimitry Andric if (BytesAdded) 403349cc55cSDimitry Andric *BytesAdded = 0; 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric // Shouldn't be a fall through. 4060b57cec5SDimitry Andric assert(TBB && "insertBranch must not be told to insert a fallthrough"); 4070b57cec5SDimitry Andric assert((Cond.size() == 1 || Cond.size() == 0) && 4080b57cec5SDimitry Andric "AVR branch conditions have one component!"); 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric if (Cond.empty()) { 4110b57cec5SDimitry Andric assert(!FBB && "Unconditional branch with multiple successors!"); 4120b57cec5SDimitry Andric auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB); 4130b57cec5SDimitry Andric if (BytesAdded) 4140b57cec5SDimitry Andric *BytesAdded += getInstSizeInBytes(MI); 4150b57cec5SDimitry Andric return 1; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric // Conditional branch. 4190b57cec5SDimitry Andric unsigned Count = 0; 4200b57cec5SDimitry Andric AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm(); 4210b57cec5SDimitry Andric auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB); 4220b57cec5SDimitry Andric 423349cc55cSDimitry Andric if (BytesAdded) 424349cc55cSDimitry Andric *BytesAdded += getInstSizeInBytes(CondMI); 4250b57cec5SDimitry Andric ++Count; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric if (FBB) { 4280b57cec5SDimitry Andric // Two-way Conditional branch. Insert the second branch. 4290b57cec5SDimitry Andric auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB); 430349cc55cSDimitry Andric if (BytesAdded) 431349cc55cSDimitry Andric *BytesAdded += getInstSizeInBytes(MI); 4320b57cec5SDimitry Andric ++Count; 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric return Count; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB, 4390b57cec5SDimitry Andric int *BytesRemoved) const { 440349cc55cSDimitry Andric if (BytesRemoved) 441349cc55cSDimitry Andric *BytesRemoved = 0; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric MachineBasicBlock::iterator I = MBB.end(); 4440b57cec5SDimitry Andric unsigned Count = 0; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric while (I != MBB.begin()) { 4470b57cec5SDimitry Andric --I; 4480b57cec5SDimitry Andric if (I->isDebugInstr()) { 4490b57cec5SDimitry Andric continue; 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric //: TODO: add here the missing jmp instructions once they are implemented 4520b57cec5SDimitry Andric // like jmp, {e}ijmp, and other cond branches, ... 4530b57cec5SDimitry Andric if (I->getOpcode() != AVR::RJMPk && 4540b57cec5SDimitry Andric getCondFromBranchOpc(I->getOpcode()) == AVRCC::COND_INVALID) { 4550b57cec5SDimitry Andric break; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric // Remove the branch. 459349cc55cSDimitry Andric if (BytesRemoved) 460349cc55cSDimitry Andric *BytesRemoved += getInstSizeInBytes(*I); 4610b57cec5SDimitry Andric I->eraseFromParent(); 4620b57cec5SDimitry Andric I = MBB.end(); 4630b57cec5SDimitry Andric ++Count; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric return Count; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric bool AVRInstrInfo::reverseBranchCondition( 4700b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond) const { 4710b57cec5SDimitry Andric assert(Cond.size() == 1 && "Invalid AVR branch condition!"); 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric AVRCC::CondCodes CC = static_cast<AVRCC::CondCodes>(Cond[0].getImm()); 4740b57cec5SDimitry Andric Cond[0].setImm(getOppositeCondition(CC)); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric return false; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 4800b57cec5SDimitry Andric unsigned Opcode = MI.getOpcode(); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric switch (Opcode) { 4830b57cec5SDimitry Andric // A regular instruction 4840b57cec5SDimitry Andric default: { 4850b57cec5SDimitry Andric const MCInstrDesc &Desc = get(Opcode); 4860b57cec5SDimitry Andric return Desc.getSize(); 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric case TargetOpcode::EH_LABEL: 4890b57cec5SDimitry Andric case TargetOpcode::IMPLICIT_DEF: 4900b57cec5SDimitry Andric case TargetOpcode::KILL: 4910b57cec5SDimitry Andric case TargetOpcode::DBG_VALUE: 4920b57cec5SDimitry Andric return 0; 4930b57cec5SDimitry Andric case TargetOpcode::INLINEASM: 4940b57cec5SDimitry Andric case TargetOpcode::INLINEASM_BR: { 4950b57cec5SDimitry Andric const MachineFunction &MF = *MI.getParent()->getParent(); 496349cc55cSDimitry Andric const AVRTargetMachine &TM = 497349cc55cSDimitry Andric static_cast<const AVRTargetMachine &>(MF.getTarget()); 4980b57cec5SDimitry Andric const TargetInstrInfo &TII = *STI.getInstrInfo(); 4990b57cec5SDimitry Andric return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), 5000b57cec5SDimitry Andric *TM.getMCAsmInfo()); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric MachineBasicBlock * 5060b57cec5SDimitry Andric AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { 5070b57cec5SDimitry Andric switch (MI.getOpcode()) { 5080b57cec5SDimitry Andric default: 5090b57cec5SDimitry Andric llvm_unreachable("unexpected opcode!"); 5100b57cec5SDimitry Andric case AVR::JMPk: 5110b57cec5SDimitry Andric case AVR::CALLk: 5120b57cec5SDimitry Andric case AVR::RCALLk: 5130b57cec5SDimitry Andric case AVR::RJMPk: 5140b57cec5SDimitry Andric case AVR::BREQk: 5150b57cec5SDimitry Andric case AVR::BRNEk: 5160b57cec5SDimitry Andric case AVR::BRSHk: 5170b57cec5SDimitry Andric case AVR::BRLOk: 5180b57cec5SDimitry Andric case AVR::BRMIk: 5190b57cec5SDimitry Andric case AVR::BRPLk: 5200b57cec5SDimitry Andric case AVR::BRGEk: 5210b57cec5SDimitry Andric case AVR::BRLTk: 5220b57cec5SDimitry Andric return MI.getOperand(0).getMBB(); 5230b57cec5SDimitry Andric case AVR::BRBSsk: 5240b57cec5SDimitry Andric case AVR::BRBCsk: 5250b57cec5SDimitry Andric return MI.getOperand(1).getMBB(); 5260b57cec5SDimitry Andric case AVR::SBRCRrB: 5270b57cec5SDimitry Andric case AVR::SBRSRrB: 5280b57cec5SDimitry Andric case AVR::SBICAb: 5290b57cec5SDimitry Andric case AVR::SBISAb: 5300b57cec5SDimitry Andric llvm_unreachable("unimplemented branch instructions"); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp, 5350b57cec5SDimitry Andric int64_t BrOffset) const { 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric switch (BranchOp) { 5380b57cec5SDimitry Andric default: 5390b57cec5SDimitry Andric llvm_unreachable("unexpected opcode!"); 5400b57cec5SDimitry Andric case AVR::JMPk: 5410b57cec5SDimitry Andric case AVR::CALLk: 5425f757f3fSDimitry Andric return STI.hasJMPCALL(); 5430b57cec5SDimitry Andric case AVR::RCALLk: 5440b57cec5SDimitry Andric case AVR::RJMPk: 5450b57cec5SDimitry Andric return isIntN(13, BrOffset); 5460b57cec5SDimitry Andric case AVR::BRBSsk: 5470b57cec5SDimitry Andric case AVR::BRBCsk: 5480b57cec5SDimitry Andric case AVR::BREQk: 5490b57cec5SDimitry Andric case AVR::BRNEk: 5500b57cec5SDimitry Andric case AVR::BRSHk: 5510b57cec5SDimitry Andric case AVR::BRLOk: 5520b57cec5SDimitry Andric case AVR::BRMIk: 5530b57cec5SDimitry Andric case AVR::BRPLk: 5540b57cec5SDimitry Andric case AVR::BRGEk: 5550b57cec5SDimitry Andric case AVR::BRLTk: 5560b57cec5SDimitry Andric return isIntN(7, BrOffset); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 560349cc55cSDimitry Andric void AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, 5610b57cec5SDimitry Andric MachineBasicBlock &NewDestBB, 562349cc55cSDimitry Andric MachineBasicBlock &RestoreBB, 563349cc55cSDimitry Andric const DebugLoc &DL, int64_t BrOffset, 5640b57cec5SDimitry Andric RegScavenger *RS) const { 5650b57cec5SDimitry Andric // This method inserts a *direct* branch (JMP), despite its name. 5660b57cec5SDimitry Andric // LLVM calls this method to fixup unconditional branches; it never calls 5670b57cec5SDimitry Andric // insertBranch or some hypothetical "insertDirectBranch". 5680b57cec5SDimitry Andric // See lib/CodeGen/RegisterRelaxation.cpp for details. 5690b57cec5SDimitry Andric // We end up here when a jump is too long for a RJMP instruction. 57006c3fb27SDimitry Andric if (STI.hasJMPCALL()) 571349cc55cSDimitry Andric BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB); 57206c3fb27SDimitry Andric else 5735f757f3fSDimitry Andric // The RJMP may jump to a far place beyond its legal range. We let the 5745f757f3fSDimitry Andric // linker to report 'out of range' rather than crash, or silently emit 5755f757f3fSDimitry Andric // incorrect assembly code. 5765f757f3fSDimitry Andric BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(&NewDestBB); 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric } // end of namespace llvm 580