LLVM API Documentation

PIC16InstrInfo.cpp

Go to the documentation of this file.
00001 //===- PIC16InstrInfo.cpp - PIC16 Instruction Information -----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source 
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the PIC16 implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "PIC16.h"
00015 #include "PIC16InstrInfo.h"
00016 #include "PIC16TargetMachine.h"
00017 #include "PIC16GenInstrInfo.inc"
00018 #include "llvm/Function.h"
00019 #include "llvm/ADT/STLExtras.h"
00020 #include "llvm/CodeGen/MachineFunction.h"
00021 #include "llvm/CodeGen/MachineInstrBuilder.h"
00022 #include "llvm/CodeGen/MachineRegisterInfo.h"
00023 #include <cstdio>
00024 
00025 
00026 using namespace llvm;
00027 
00028 // FIXME: Add the subtarget support on this constructor.
00029 PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm)
00030   : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)),
00031     TM(tm), 
00032     RegInfo(*this, *TM.getSubtargetImpl()) {}
00033 
00034 
00035 /// isStoreToStackSlot - If the specified machine instruction is a direct
00036 /// store to a stack slot, return the virtual or physical register number of
00037 /// the source reg along with the FrameIndex of the loaded stack slot.  
00038 /// If not, return 0.  This predicate must return 0 if the instruction has
00039 /// any side effects other than storing to the stack slot.
00040 unsigned PIC16InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
00041                                             int &FrameIndex) const {
00042   if (MI->getOpcode() == PIC16::movwf 
00043       && MI->getOperand(0).isReg()
00044       && MI->getOperand(1).isSymbol()) {
00045     FrameIndex = MI->getOperand(1).getIndex();
00046     return MI->getOperand(0).getReg();
00047   }
00048   return 0;
00049 }
00050 
00051 /// isLoadFromStackSlot - If the specified machine instruction is a direct
00052 /// load from a stack slot, return the virtual or physical register number of
00053 /// the dest reg along with the FrameIndex of the stack slot.  
00054 /// If not, return 0.  This predicate must return 0 if the instruction has
00055 /// any side effects other than storing to the stack slot.
00056 unsigned PIC16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
00057                                             int &FrameIndex) const {
00058   if (MI->getOpcode() == PIC16::movf 
00059       && MI->getOperand(0).isReg()
00060       && MI->getOperand(1).isSymbol()) {
00061     FrameIndex = MI->getOperand(1).getIndex();
00062     return MI->getOperand(0).getReg();
00063   }
00064   return 0;
00065 }
00066 
00067 
00068 void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 
00069                                          MachineBasicBlock::iterator I,
00070                                          unsigned SrcReg, bool isKill, int FI,
00071                                          const TargetRegisterClass *RC) const {
00072 
00073   const Function *Func = MBB.getParent()->getFunction();
00074   const std::string FuncName = Func->getName();
00075 
00076   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00077   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00078 
00079   // On the order of operands here: think "movwf SrcReg, tmp_slot, offset".
00080   if (RC == PIC16::GPRRegisterClass) {
00081     //MachineFunction &MF = *MBB.getParent();
00082     //MachineRegisterInfo &RI = MF.getRegInfo();
00083     BuildMI(MBB, I, get(PIC16::movwf))
00084       .addReg(SrcReg, false, false, isKill)
00085       .addImm(FI)
00086       .addExternalSymbol(tmpName)
00087       .addImm(1); // Emit banksel for it.
00088   }
00089   else if (RC == PIC16::FSR16RegisterClass)
00090     assert(0 && "Don't know yet how to store a FSR16 to stack slot");
00091   else
00092     assert(0 && "Can't store this register to stack slot");
00093 }
00094 
00095 void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 
00096                                           MachineBasicBlock::iterator I,
00097                                           unsigned DestReg, int FI,
00098                                           const TargetRegisterClass *RC) const {
00099 
00100   const Function *Func = MBB.getParent()->getFunction();
00101   const std::string FuncName = Func->getName();
00102 
00103   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00104   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00105 
00106   // On the order of operands here: think "movf FrameIndex, W".
00107   if (RC == PIC16::GPRRegisterClass) {
00108     //MachineFunction &MF = *MBB.getParent();
00109     //MachineRegisterInfo &RI = MF.getRegInfo();
00110     BuildMI(MBB, I, get(PIC16::movf), DestReg)
00111       .addImm(FI)
00112       .addExternalSymbol(tmpName)
00113       .addImm(1); // Emit banksel for it.
00114   }
00115   else if (RC == PIC16::FSR16RegisterClass)
00116     assert(0 && "Don't know yet how to load an FSR16 from stack slot");
00117   else
00118     assert(0 && "Can't load this register from stack slot");
00119 }
00120 
00121 bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB,
00122                                    MachineBasicBlock::iterator I,
00123                                    unsigned DestReg, unsigned SrcReg,
00124                                    const TargetRegisterClass *DestRC,
00125                                    const TargetRegisterClass *SrcRC) const {
00126   if (DestRC == PIC16::FSR16RegisterClass) {
00127     BuildMI(MBB, I, get(PIC16::copy_fsr), DestReg).addReg(SrcReg);
00128     return true;
00129   }
00130 
00131   if (DestRC == PIC16::GPRRegisterClass) {
00132     BuildMI(MBB, I, get(PIC16::copy_w), DestReg).addReg(SrcReg);
00133     return true;
00134   }
00135 
00136   // Not yet supported.
00137   return false;
00138 }
00139 
00140 bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI,
00141                                  unsigned &SrcReg, unsigned &DestReg,
00142                                  unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
00143   SrcSubIdx = DstSubIdx = 0; // No sub-registers.
00144 
00145   if (MI.getOpcode() == PIC16::copy_fsr
00146       || MI.getOpcode() == PIC16::copy_w) {
00147     DestReg = MI.getOperand(0).getReg();
00148     SrcReg = MI.getOperand(1).getReg();
00149     return true;
00150   }
00151 
00152   return false;
00153 }
00154