blob: 7cb2379d1ba6dc345d69da620c0275ace7c0ab21 [file] [log] [blame]
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001//===- 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"
Duncan Sands4520dd22008-10-08 07:23:46 +000021#include <cstdio>
Sanjiv Gupta0e687712008-05-13 09:02:57 +000022
23using namespace llvm;
24
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000025// FIXME: Add the subtarget support on this constructor.
Sanjiv Gupta0e687712008-05-13 09:02:57 +000026PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm)
27 : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)),
28 TM(tm), RI(*this) {}
29
30static bool isZeroImm(const MachineOperand &op) {
Dan Gohmand735b802008-10-03 15:45:36 +000031 return op.isImm() && op.getImm() == 0;
Sanjiv Gupta0e687712008-05-13 09:02:57 +000032}
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.
40unsigned PIC16InstrInfo::
Dan Gohmancbad42c2008-11-18 19:49:32 +000041isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
Sanjiv Gupta0e687712008-05-13 09:02:57 +000042{
43 if (MI->getOpcode() == PIC16::MOVF) {
Dan Gohmand735b802008-10-03 15:45:36 +000044 if ((MI->getOperand(2).isFI()) && // is a stack slot
45 (MI->getOperand(1).isImm()) && // the imm is zero
Sanjiv Gupta0e687712008-05-13 09:02:57 +000046 (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.
60unsigned PIC16InstrInfo::
Dan Gohmancbad42c2008-11-18 19:49:32 +000061isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
Sanjiv Gupta0e687712008-05-13 09:02:57 +000062{
63 if (MI->getOpcode() == PIC16::MOVWF) {
Dan Gohmand735b802008-10-03 15:45:36 +000064 if ((MI->getOperand(0).isFI()) && // is a stack slot
65 (MI->getOperand(1).isImm()) && // the imm is zero
Sanjiv Gupta0e687712008-05-13 09:02:57 +000066 (isZeroImm(MI->getOperand(1)))) {
67 FrameIndex = MI->getOperand(0).getIndex();
68 return MI->getOperand(2).getReg();
69 }
70 }
71 return 0;
72}
73
74void PIC16InstrInfo::
75storeRegToStackSlot(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,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000091 // so we repeat.
Sanjiv Gupta0e687712008-05-13 09:02:57 +000092 }
93 else
94 assert(0 && "Can't store this register to stack slot");
95}
96
97void PIC16InstrInfo::
98loadRegFromStackSlot(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.
122unsigned PIC16InstrInfo::
123InsertBranch(MachineBasicBlock &MBB,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000124 MachineBasicBlock *TBB, MachineBasicBlock *FBB,
Owen Anderson44eb65c2008-08-14 22:49:33 +0000125 const SmallVectorImpl<MachineOperand> &Cond) const
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000126{
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
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000138 // FIXME: If the there are some conditions specified then conditional branch
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000139 // should be generated.
140 // For the time being no instruction is being generated therefore
141 // returning NULL.
142 return 0;
143}
144