Rename LoadX to LoadExt.
[oota-llvm.git] / lib / Target / PIC16 / PIC16InstrInfo.cpp
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"
16 #include "llvm/Function.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "PIC16GenInstrInfo.inc"
21 #include <cstdio>
22
23 using namespace llvm;
24
25 // FIXME: Add the subtarget support on this constructor.
26 PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm)
27   : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)),
28     TM(tm), RI(*this) {}
29
30 static bool isZeroImm(const MachineOperand &op) {
31   return op.isImm() && op.getImm() == 0;
32 }
33
34
35 /// isLoadFromStackSlot - If the specified machine instruction is a direct
36 /// load from a stack slot, return the virtual or physical register number of
37 /// the destination along with the FrameIndex of the loaded stack slot.  If
38 /// not, return 0.  This predicate must return 0 if the instruction has
39 /// any side effects other than loading from the stack slot.
40 unsigned PIC16InstrInfo::
41 isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const 
42 {
43   if (MI->getOpcode() == PIC16::MOVF) {
44     if ((MI->getOperand(2).isFI()) && // is a stack slot
45         (MI->getOperand(1).isImm()) &&  // the imm is zero
46         (isZeroImm(MI->getOperand(1)))) {
47       FrameIndex = MI->getOperand(2).getIndex();
48       return MI->getOperand(0).getReg();
49     }
50   }
51
52   return 0;
53 }
54
55 /// isStoreToStackSlot - If the specified machine instruction is a direct
56 /// store to a stack slot, return the virtual or physical register number of
57 /// the source reg along with the FrameIndex of the loaded stack slot.  If
58 /// not, return 0.  This predicate must return 0 if the instruction has
59 /// any side effects other than storing to the stack slot.
60 unsigned PIC16InstrInfo::
61 isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const 
62 {
63   if (MI->getOpcode() == PIC16::MOVWF) {
64     if ((MI->getOperand(0).isFI()) && // is a stack slot
65         (MI->getOperand(1).isImm()) &&  // the imm is zero
66         (isZeroImm(MI->getOperand(1)))) {
67       FrameIndex = MI->getOperand(0).getIndex();
68       return MI->getOperand(2).getReg();
69     }
70   }
71   return 0;
72 }
73
74 void PIC16InstrInfo::
75 storeRegToStackSlot(MachineBasicBlock &MBB,
76                     MachineBasicBlock::iterator I,
77                     unsigned SrcReg, bool isKill, int FI,
78                     const TargetRegisterClass *RC) const {
79   const Function *Func = MBB.getParent()->getFunction();
80   const std::string FuncName = Func->getName();
81
82   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
83   sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI);
84
85   if (RC == PIC16::CPURegsRegisterClass) {
86     //src is always WREG. 
87     BuildMI(MBB, I, this->get(PIC16::MOVWF))
88         .addReg(SrcReg,false,false,true,true)
89         .addExternalSymbol(tmpName)   // the current printer expects 3 operands,
90         .addExternalSymbol(tmpName);  // all we need is actually one, 
91                                       // so we repeat.
92   }
93   else
94     assert(0 && "Can't store this register to stack slot");
95 }
96
97 void PIC16InstrInfo::
98 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
99                      unsigned DestReg, int FI,
100                      const TargetRegisterClass *RC) const 
101 {
102   const Function *Func = MBB.getParent()->getFunction();
103   const std::string FuncName = Func->getName();
104
105   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
106   sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI);
107
108   if (RC == PIC16::CPURegsRegisterClass)
109     BuildMI(MBB, I, this->get(PIC16::MOVF), DestReg)
110       .addExternalSymbol(tmpName)   // the current printer expects 3 operands,
111       .addExternalSymbol(tmpName);  // all we need is actually one,so we repeat.
112   else
113     assert(0 && "Can't load this register from stack slot");
114 }
115
116 /// InsertBranch - Insert a branch into the end of the specified
117 /// MachineBasicBlock.  This operands to this method are the same as those
118 /// returned by AnalyzeBranch.  This is invoked in cases where AnalyzeBranch
119 /// returns success and when an unconditional branch (TBB is non-null, FBB is
120 /// null, Cond is empty) needs to be inserted. It returns the number of
121 /// instructions inserted.
122 unsigned PIC16InstrInfo::
123 InsertBranch(MachineBasicBlock &MBB, 
124              MachineBasicBlock *TBB, MachineBasicBlock *FBB,
125              const SmallVectorImpl<MachineOperand> &Cond) const
126 {
127   // Shouldn't be a fall through.
128   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
129
130   if (FBB == 0) { // One way branch.
131     if (Cond.empty()) {
132       // Unconditional branch?
133       BuildMI(&MBB, get(PIC16::GOTO)).addMBB(TBB);
134     } 
135     return 1;
136   }
137
138   // FIXME: If the there are some conditions specified then conditional branch 
139   // should be generated.
140   // For the time being no instruction is being generated therefore 
141   // returning NULL.
142   return 0;
143 }
144