aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PIC16/PIC16InstrInfo.cpp
diff options
context:
space:
mode:
authorSanjiv Gupta <sanjiv.gupta@microchip.com>2008-05-13 09:02:57 +0000
committerSanjiv Gupta <sanjiv.gupta@microchip.com>2008-05-13 09:02:57 +0000
commit09bb420cf4975a6a51f7b1d03f029d76d4e9689a (patch)
treecfd4a927ef4bb5bbfabb6694b6214b3bd890ceb2 /lib/Target/PIC16/PIC16InstrInfo.cpp
parent411fc17b569bac71b8d0578174d027663202c203 (diff)
downloadexternal_llvm-09bb420cf4975a6a51f7b1d03f029d76d4e9689a.zip
external_llvm-09bb420cf4975a6a51f7b1d03f029d76d4e9689a.tar.gz
external_llvm-09bb420cf4975a6a51f7b1d03f029d76d4e9689a.tar.bz2
Adding files for Microchip's PIC16 target.
A brief description about PIC16: =============================== PIC16 is an 8-bit microcontroller with only one 8-bit register which is the accumulator. All arithmetic/load/store operations are 8-bit only. The architecture has two address spaces: program and data. The program memory is divided into 2K pages and the data memory is divided into banks of 128 byte, with only 80 usable bytes, resulting in an non-contiguous data memory. It supports direct data memory access (by specifying the address as part of the instruction) and indirect data and program memory access (in an unorthodox fashion which utilize a 16 bit pointer register). Two classes of registers exist: (8-bit class which is only one accumulator) (16-bit class, which contains one or more 16 bit pointer(s)) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51027 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PIC16/PIC16InstrInfo.cpp')
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp
new file mode 100644
index 0000000..ad38382
--- /dev/null
+++ b/lib/Target/PIC16/PIC16InstrInfo.cpp
@@ -0,0 +1,143 @@
+//===- PIC16InstrInfo.cpp - PIC16 Instruction Information -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PIC16 implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PIC16.h"
+#include "PIC16InstrInfo.h"
+#include "llvm/Function.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "PIC16GenInstrInfo.inc"
+
+using namespace llvm;
+
+// TODO: Add the subtarget support on this constructor.
+PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm)
+ : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)),
+ TM(tm), RI(*this) {}
+
+static bool isZeroImm(const MachineOperand &op) {
+ return op.isImmediate() && op.getImm() == 0;
+}
+
+
+/// isLoadFromStackSlot - If the specified machine instruction is a direct
+/// load from a stack slot, return the virtual or physical register number of
+/// the destination along with the FrameIndex of the loaded stack slot. If
+/// not, return 0. This predicate must return 0 if the instruction has
+/// any side effects other than loading from the stack slot.
+unsigned PIC16InstrInfo::
+isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const
+{
+ if (MI->getOpcode() == PIC16::MOVF) {
+ if ((MI->getOperand(2).isFrameIndex()) && // is a stack slot
+ (MI->getOperand(1).isImmediate()) && // the imm is zero
+ (isZeroImm(MI->getOperand(1)))) {
+ FrameIndex = MI->getOperand(2).getIndex();
+ return MI->getOperand(0).getReg();
+ }
+ }
+
+ return 0;
+}
+
+/// isStoreToStackSlot - If the specified machine instruction is a direct
+/// store to a stack slot, return the virtual or physical register number of
+/// the source reg along with the FrameIndex of the loaded stack slot. If
+/// not, return 0. This predicate must return 0 if the instruction has
+/// any side effects other than storing to the stack slot.
+unsigned PIC16InstrInfo::
+isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const
+{
+ if (MI->getOpcode() == PIC16::MOVWF) {
+ if ((MI->getOperand(0).isFrameIndex()) && // is a stack slot
+ (MI->getOperand(1).isImmediate()) && // the imm is zero
+ (isZeroImm(MI->getOperand(1)))) {
+ FrameIndex = MI->getOperand(0).getIndex();
+ return MI->getOperand(2).getReg();
+ }
+ }
+ return 0;
+}
+
+void PIC16InstrInfo::
+storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ unsigned SrcReg, bool isKill, int FI,
+ const TargetRegisterClass *RC) const {
+ const Function *Func = MBB.getParent()->getFunction();
+ const std::string FuncName = Func->getName();
+
+ char *tmpName = new char [strlen(FuncName.c_str()) + 6];
+ sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI);
+
+ if (RC == PIC16::CPURegsRegisterClass) {
+ //src is always WREG.
+ BuildMI(MBB, I, this->get(PIC16::MOVWF))
+ .addReg(SrcReg,false,false,true,true)
+ .addExternalSymbol(tmpName) // the current printer expects 3 operands,
+ .addExternalSymbol(tmpName); // all we need is actually one,
+ // so we repeat.
+ }
+ else
+ assert(0 && "Can't store this register to stack slot");
+}
+
+void PIC16InstrInfo::
+loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+ unsigned DestReg, int FI,
+ const TargetRegisterClass *RC) const
+{
+ const Function *Func = MBB.getParent()->getFunction();
+ const std::string FuncName = Func->getName();
+
+ char *tmpName = new char [strlen(FuncName.c_str()) + 6];
+ sprintf(tmpName, "%s_tmp_%d",FuncName.c_str(),FI);
+
+ if (RC == PIC16::CPURegsRegisterClass)
+ BuildMI(MBB, I, this->get(PIC16::MOVF), DestReg)
+ .addExternalSymbol(tmpName) // the current printer expects 3 operands,
+ .addExternalSymbol(tmpName); // all we need is actually one,so we repeat.
+ else
+ assert(0 && "Can't load this register from stack slot");
+}
+
+/// InsertBranch - Insert a branch into the end of the specified
+/// MachineBasicBlock. This operands to this method are the same as those
+/// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch
+/// returns success and when an unconditional branch (TBB is non-null, FBB is
+/// null, Cond is empty) needs to be inserted. It returns the number of
+/// instructions inserted.
+unsigned PIC16InstrInfo::
+InsertBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ const std::vector<MachineOperand> &Cond) const
+{
+ // Shouldn't be a fall through.
+ assert(TBB && "InsertBranch must not be told to insert a fallthrough");
+
+ if (FBB == 0) { // One way branch.
+ if (Cond.empty()) {
+ // Unconditional branch?
+ BuildMI(&MBB, get(PIC16::GOTO)).addMBB(TBB);
+ }
+ return 1;
+ }
+
+ // TODO: If the there are some conditions specified then conditional branch
+ // should be generated.
+ // For the time being no instruction is being generated therefore
+ // returning NULL.
+ return 0;
+}
+