| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 1 | //===- PIC16InstrInfo.cpp - PIC16 Instruction Information -----------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file contains the PIC16 implementation of the TargetInstrInfo class. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "PIC16.h" | 
|  | 15 | #include "PIC16InstrInfo.h" | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 16 | #include "PIC16TargetMachine.h" | 
|  | 17 | #include "PIC16GenInstrInfo.inc" | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 18 | #include "llvm/Function.h" | 
|  | 19 | #include "llvm/ADT/STLExtras.h" | 
|  | 20 | #include "llvm/CodeGen/MachineFunction.h" | 
|  | 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 22 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Duncan Sands | 71ecd67 | 2008-11-28 10:20:03 +0000 | [diff] [blame] | 23 | #include <cstdio> | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 24 |  | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 25 |  | 
|  | 26 | using namespace llvm; | 
|  | 27 |  | 
| Sanjiv Gupta | 7fc6027 | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 28 | // FIXME: Add the subtarget support on this constructor. | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 29 | PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm) | 
|  | 30 | : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)), | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 31 | TM(tm), | 
|  | 32 | RegInfo(*this, *TM.getSubtargetImpl()) {} | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 33 |  | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 34 |  | 
|  | 35 | /// isStoreToStackSlot - If the specified machine instruction is a direct | 
|  | 36 | /// store to a stack slot, return the virtual or physical register number of | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 37 | /// the source reg along with the FrameIndex of the loaded stack slot. | 
|  | 38 | /// If not, return 0.  This predicate must return 0 if the instruction has | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 39 | /// any side effects other than storing to the stack slot. | 
| Sanjiv Gupta | 5c63cf8 | 2008-11-19 11:27:59 +0000 | [diff] [blame] | 40 | unsigned PIC16InstrInfo::isStoreToStackSlot(const MachineInstr *MI, | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 41 | int &FrameIndex) const { | 
|  | 42 | if (MI->getOpcode() == PIC16::movwf | 
|  | 43 | && MI->getOperand(0).isReg() | 
|  | 44 | && MI->getOperand(1).isSymbol()) { | 
|  | 45 | FrameIndex = MI->getOperand(1).getIndex(); | 
|  | 46 | return MI->getOperand(0).getReg(); | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 47 | } | 
|  | 48 | return 0; | 
|  | 49 | } | 
|  | 50 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 51 | /// isLoadFromStackSlot - If the specified machine instruction is a direct | 
|  | 52 | /// load from a stack slot, return the virtual or physical register number of | 
|  | 53 | /// the dest reg along with the FrameIndex of the stack slot. | 
|  | 54 | /// If not, return 0.  This predicate must return 0 if the instruction has | 
|  | 55 | /// any side effects other than storing to the stack slot. | 
| Sanjiv Gupta | 5c63cf8 | 2008-11-19 11:27:59 +0000 | [diff] [blame] | 56 | unsigned PIC16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 57 | int &FrameIndex) const { | 
|  | 58 | if (MI->getOpcode() == PIC16::movf | 
|  | 59 | && MI->getOperand(0).isReg() | 
|  | 60 | && MI->getOperand(1).isSymbol()) { | 
|  | 61 | FrameIndex = MI->getOperand(1).getIndex(); | 
|  | 62 | return MI->getOperand(0).getReg(); | 
|  | 63 | } | 
|  | 64 | return 0; | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 |  | 
|  | 68 | void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, | 
|  | 69 | MachineBasicBlock::iterator I, | 
|  | 70 | unsigned SrcReg, bool isKill, int FI, | 
|  | 71 | const TargetRegisterClass *RC) const { | 
| Sanjiv Gupta | 0b08df8 | 2009-04-06 10:54:50 +0000 | [diff] [blame] | 72 | PIC16TargetLowering *PTLI = TM.getTargetLowering(); | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 73 | DebugLoc DL = DebugLoc::getUnknownLoc(); | 
|  | 74 | if (I != MBB.end()) DL = I->getDebugLoc(); | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 75 |  | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 76 | const Function *Func = MBB.getParent()->getFunction(); | 
|  | 77 | const std::string FuncName = Func->getName(); | 
|  | 78 |  | 
|  | 79 | char *tmpName = new char [strlen(FuncName.c_str()) +  6]; | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 80 | sprintf(tmpName, "%s.tmp", FuncName.c_str()); | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 81 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 82 | // On the order of operands here: think "movwf SrcReg, tmp_slot, offset". | 
|  | 83 | if (RC == PIC16::GPRRegisterClass) { | 
|  | 84 | //MachineFunction &MF = *MBB.getParent(); | 
|  | 85 | //MachineRegisterInfo &RI = MF.getRegInfo(); | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 86 | BuildMI(MBB, I, DL, get(PIC16::movwf)) | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 87 | .addReg(SrcReg, false, false, isKill) | 
| Sanjiv Gupta | 638f400 | 2009-04-10 15:10:14 +0000 | [diff] [blame] | 88 | .addImm(PTLI->GetTmpOffsetForFI(FI, 1)) | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 89 | .addExternalSymbol(tmpName) | 
|  | 90 | .addImm(1); // Emit banksel for it. | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 91 | } | 
| Sanjiv Gupta | 638f400 | 2009-04-10 15:10:14 +0000 | [diff] [blame] | 92 | else if (RC == PIC16::FSR16RegisterClass) { | 
|  | 93 | // This is a 16-bit register and the frameindex given by llvm is of | 
|  | 94 | // size two here. Break this index N into two zero based indexes and | 
|  | 95 | // put one into the map. The second one is always obtained by adding 1 | 
|  | 96 | // to the first zero based index. In fact it is going to use 3 slots | 
|  | 97 | // as saving FSRs corrupts W also and hence we need to save/restore W also. | 
|  | 98 |  | 
|  | 99 | unsigned opcode = (SrcReg == PIC16::FSR0) ? PIC16::save_fsr0 | 
|  | 100 | : PIC16::save_fsr1; | 
|  | 101 | BuildMI(MBB, I, DL, get(opcode)) | 
|  | 102 | .addReg(SrcReg, false, false, isKill) | 
|  | 103 | .addImm(PTLI->GetTmpOffsetForFI(FI, 3)) | 
|  | 104 | .addExternalSymbol(tmpName) | 
|  | 105 | .addImm(1); // Emit banksel for it. | 
|  | 106 | } | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 107 | else | 
|  | 108 | assert(0 && "Can't store this register to stack slot"); | 
|  | 109 | } | 
|  | 110 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 111 | void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, | 
|  | 112 | MachineBasicBlock::iterator I, | 
|  | 113 | unsigned DestReg, int FI, | 
|  | 114 | const TargetRegisterClass *RC) const { | 
| Sanjiv Gupta | 0b08df8 | 2009-04-06 10:54:50 +0000 | [diff] [blame] | 115 | PIC16TargetLowering *PTLI = TM.getTargetLowering(); | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 116 | DebugLoc DL = DebugLoc::getUnknownLoc(); | 
|  | 117 | if (I != MBB.end()) DL = I->getDebugLoc(); | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 118 |  | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 119 | const Function *Func = MBB.getParent()->getFunction(); | 
|  | 120 | const std::string FuncName = Func->getName(); | 
|  | 121 |  | 
|  | 122 | char *tmpName = new char [strlen(FuncName.c_str()) +  6]; | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 123 | sprintf(tmpName, "%s.tmp", FuncName.c_str()); | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 124 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 125 | // On the order of operands here: think "movf FrameIndex, W". | 
|  | 126 | if (RC == PIC16::GPRRegisterClass) { | 
|  | 127 | //MachineFunction &MF = *MBB.getParent(); | 
|  | 128 | //MachineRegisterInfo &RI = MF.getRegInfo(); | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 129 | BuildMI(MBB, I, DL, get(PIC16::movf), DestReg) | 
| Sanjiv Gupta | 638f400 | 2009-04-10 15:10:14 +0000 | [diff] [blame] | 130 | .addImm(PTLI->GetTmpOffsetForFI(FI, 1)) | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 131 | .addExternalSymbol(tmpName) | 
|  | 132 | .addImm(1); // Emit banksel for it. | 
|  | 133 | } | 
| Sanjiv Gupta | 638f400 | 2009-04-10 15:10:14 +0000 | [diff] [blame] | 134 | else if (RC == PIC16::FSR16RegisterClass) { | 
|  | 135 | // This is a 16-bit register and the frameindex given by llvm is of | 
|  | 136 | // size two here. Break this index N into two zero based indexes and | 
|  | 137 | // put one into the map. The second one is always obtained by adding 1 | 
|  | 138 | // to the first zero based index. In fact it is going to use 3 slots | 
|  | 139 | // as saving FSRs corrupts W also and hence we need to save/restore W also. | 
|  | 140 |  | 
|  | 141 | unsigned opcode = (DestReg == PIC16::FSR0) ? PIC16::restore_fsr0 | 
|  | 142 | : PIC16::restore_fsr1; | 
|  | 143 | BuildMI(MBB, I, DL, get(opcode), DestReg) | 
|  | 144 | .addImm(PTLI->GetTmpOffsetForFI(FI, 3)) | 
|  | 145 | .addExternalSymbol(tmpName) | 
|  | 146 | .addImm(1); // Emit banksel for it. | 
|  | 147 | } | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 148 | else | 
|  | 149 | assert(0 && "Can't load this register from stack slot"); | 
|  | 150 | } | 
|  | 151 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 152 | bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB, | 
|  | 153 | MachineBasicBlock::iterator I, | 
|  | 154 | unsigned DestReg, unsigned SrcReg, | 
|  | 155 | const TargetRegisterClass *DestRC, | 
|  | 156 | const TargetRegisterClass *SrcRC) const { | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 157 | DebugLoc DL = DebugLoc::getUnknownLoc(); | 
|  | 158 | if (I != MBB.end()) DL = I->getDebugLoc(); | 
|  | 159 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 160 | if (DestRC == PIC16::FSR16RegisterClass) { | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 161 | BuildMI(MBB, I, DL, get(PIC16::copy_fsr), DestReg).addReg(SrcReg); | 
| Sanjiv Gupta | 45da8b7 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 162 | return true; | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 163 | } | 
|  | 164 |  | 
| Sanjiv Gupta | 45da8b7 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 165 | if (DestRC == PIC16::GPRRegisterClass) { | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 166 | BuildMI(MBB, I, DL, get(PIC16::copy_w), DestReg).addReg(SrcReg); | 
| Sanjiv Gupta | 45da8b7 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 167 | return true; | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | // Not yet supported. | 
|  | 171 | return false; | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 172 | } | 
|  | 173 |  | 
|  | 174 | bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI, | 
| Sanjiv Gupta | 335ea6c | 2009-01-21 09:02:46 +0000 | [diff] [blame] | 175 | unsigned &SrcReg, unsigned &DestReg, | 
|  | 176 | unsigned &SrcSubIdx, unsigned &DstSubIdx) const { | 
|  | 177 | SrcSubIdx = DstSubIdx = 0; // No sub-registers. | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 178 |  | 
| Sanjiv Gupta | 45da8b7 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 179 | if (MI.getOpcode() == PIC16::copy_fsr | 
|  | 180 | || MI.getOpcode() == PIC16::copy_w) { | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 181 | DestReg = MI.getOperand(0).getReg(); | 
|  | 182 | SrcReg = MI.getOperand(1).getReg(); | 
|  | 183 | return true; | 
|  | 184 | } | 
| Sanjiv Gupta | 45da8b7 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 185 |  | 
| Sanjiv Gupta | 2ae21ee | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 186 | return false; | 
| Sanjiv Gupta | 4394c23 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 187 | } | 
|  | 188 |  |