LLVM API Documentation
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