//===- MSP430InstrInfo.cpp - MSP430 Instruction Information ---------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains the MSP430 implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// #include "MSP430.h" #include "MSP430InstrInfo.h" #include "MSP430MachineFunctionInfo.h" #include "MSP430TargetMachine.h" #include "MSP430GenInstrInfo.inc" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" using namespace llvm; MSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm) : TargetInstrInfoImpl(MSP430Insts, array_lengthof(MSP430Insts)), RI(tm, *this), TM(tm) {} void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { DebugLoc DL = DebugLoc::getUnknownLoc(); if (MI != MBB.end()) DL = MI->getDebugLoc(); if (RC == &MSP430::GR16RegClass) BuildMI(MBB, MI, DL, get(MSP430::MOV16mr)) .addFrameIndex(FrameIdx).addImm(0) .addReg(SrcReg, getKillRegState(isKill)); else if (RC == &MSP430::GR8RegClass) BuildMI(MBB, MI, DL, get(MSP430::MOV8mr)) .addFrameIndex(FrameIdx).addImm(0) .addReg(SrcReg, getKillRegState(isKill)); else assert(0 && "Cannot store this register to stack slot!"); } void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const{ DebugLoc DL = DebugLoc::getUnknownLoc(); if (MI != MBB.end()) DL = MI->getDebugLoc(); if (RC == &MSP430::GR16RegClass) BuildMI(MBB, MI, DL, get(MSP430::MOV16rm)) .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0); else if (RC == &MSP430::GR8RegClass) BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0); else assert(0 && "Cannot store this register to stack slot!"); } bool MSP430InstrInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const { DebugLoc DL = DebugLoc::getUnknownLoc(); if (I != MBB.end()) DL = I->getDebugLoc(); if (DestRC == SrcRC) { unsigned Opc; if (DestRC == &MSP430::GR16RegClass) { Opc = MSP430::MOV16rr; } else if (DestRC == &MSP430::GR8RegClass) { Opc = MSP430::MOV8rr; } else { return false; } BuildMI(MBB, I, DL, get(Opc), DestReg).addReg(SrcReg); return true; } return false; } bool MSP430InstrInfo::isMoveInstr(const MachineInstr& MI, unsigned &SrcReg, unsigned &DstReg, unsigned &SrcSubIdx, unsigned &DstSubIdx) const { SrcSubIdx = DstSubIdx = 0; // No sub-registers yet. switch (MI.getOpcode()) { default: return false; case MSP430::MOV8rr: case MSP430::MOV16rr: assert(MI.getNumOperands() >= 2 && MI.getOperand(0).isReg() && MI.getOperand(1).isReg() && "invalid register-register move instruction"); SrcReg = MI.getOperand(1).getReg(); DstReg = MI.getOperand(0).getReg(); return true; } } bool MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI) const { if (CSI.empty()) return false; DebugLoc DL = DebugLoc::getUnknownLoc(); if (MI != MBB.end()) DL = MI->getDebugLoc(); MachineFunction &MF = *MBB.getParent(); MSP430MachineFunctionInfo *MFI = MF.getInfo(); MFI->setCalleeSavedFrameSize(CSI.size() * 2); for (unsigned i = CSI.size(); i != 0; --i) { unsigned Reg = CSI[i-1].getReg(); // Add the callee-saved register as live-in. It's killed at the spill. MBB.addLiveIn(Reg); BuildMI(MBB, MI, DL, get(MSP430::PUSH16r)) .addReg(Reg, RegState::Kill); } return true; } bool MSP430InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI) const { if (CSI.empty()) return false; DebugLoc DL = DebugLoc::getUnknownLoc(); if (MI != MBB.end()) DL = MI->getDebugLoc(); for (unsigned i = 0, e = CSI.size(); i != e; ++i) BuildMI(MBB, MI, DL, get(MSP430::POP16r), CSI[i].getReg()); return true; } unsigned MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond) const { // FIXME this should probably have a DebugLoc operand DebugLoc dl = DebugLoc::getUnknownLoc(); // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "MSP430 branch conditions have one component!"); if (Cond.empty()) { // Unconditional branch? assert(!FBB && "Unconditional branch with multiple successors!"); BuildMI(&MBB, dl, get(MSP430::JMP)).addMBB(TBB); return 1; } // Conditional branch. unsigned Count = 0; assert(0 && "Implement conditional branches!"); return Count; }