[llvm-commits] [llvm] r59617 - in /llvm/trunk/lib/Target/PIC16: PIC16.h PIC16.td PIC16AsmPrinter.cpp PIC16CallingConv.td PIC16ConstantPoolValue.cpp PIC16ConstantPoolValue.h PIC16ISelDAGToDAG.cpp PIC16ISelDAGToDAG.h PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrFormats.td PIC16InstrInfo.cpp PIC16InstrInfo.h PIC16InstrInfo.td PIC16RegisterInfo.cpp PIC16RegisterInfo.h PIC16RegisterInfo.td PIC16Subtarget.cpp PIC16Subtarget.h PIC16TargetAsmInfo.cpp PIC16TargetAsmInfo.h PIC16TargetMachine.cpp PIC16TargetMachine.h

Sanjiv Gupta sanjiv.gupta at microchip.com
Wed Nov 19 03:00:58 PST 2008


Author: sgupta
Date: Wed Nov 19 05:00:54 2008
New Revision: 59617

URL: http://llvm.org/viewvc/llvm-project?rev=59617&view=rev
Log:
Added a more function PIC16 backend. However to get this working a patch in
ExpandIntegerOperand (LegalizeIntegerTypes.cpp) is needed which is yet to be reworked and submitted. 

Added:
    llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h
Removed:
    llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td
    llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp
    llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h
Modified:
    llvm/trunk/lib/Target/PIC16/PIC16.h
    llvm/trunk/lib/Target/PIC16/PIC16.td
    llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp
    llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
    llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
    llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td
    llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp
    llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h
    llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td
    llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp
    llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h
    llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td
    llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp
    llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h
    llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
    llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h
    llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp
    llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h

Modified: llvm/trunk/lib/Target/PIC16/PIC16.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16.h Wed Nov 19 05:00:54 2008
@@ -12,14 +12,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef TARGET_PIC16_H
-#define TARGET_PIC16_H
+#ifndef LLVM_TARGET_PIC16_H
+#define LLVM_TARGET_PIC16_H
 
 #include <iosfwd>
 
 namespace llvm {
   class PIC16TargetMachine;
-  class FunctionPassManager;
   class FunctionPass;
   class MachineCodeEmitter;
   class raw_ostream;

Modified: llvm/trunk/lib/Target/PIC16/PIC16.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.td?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16.td Wed Nov 19 05:00:54 2008
@@ -15,30 +15,24 @@
 
 include "../Target.td"
 
-//===----------------------------------------------------------------------===//
-// Descriptions
-//===----------------------------------------------------------------------===//
-
 include "PIC16RegisterInfo.td"
-include "PIC16CallingConv.td"
 include "PIC16InstrInfo.td"
 
-def PIC16InstrInfo : InstrInfo {
-  let TSFlagsFields = [];
-  let TSFlagsShifts = [];
-}
-
-
-
-// Not currently supported, but work as SubtargetFeature placeholder.
-def FeaturePIC16Old : SubtargetFeature<"pic16old", "IsPIC16Old", "true",
-                                       "PIC16 Old ISA Support">;
+//===----------------------------------------------------------------------===//
+// Subtarget Features. 
+//===----------------------------------------------------------------------===//
+def FeatureCooper : SubtargetFeature<"cooper", "IsCooper", "true",
+                                     "PIC16 Cooper ISA Support">;
 
 //===----------------------------------------------------------------------===//
-// PIC16 processors supported.
+// PIC16 supported processors.
 //===----------------------------------------------------------------------===//
 
 def : Processor<"generic", NoItineraries, []>;
+def : Processor<"cooper", NoItineraries, [FeatureCooper]>;
+
+
+def PIC16InstrInfo : InstrInfo {} 
 
 def PIC16 : Target {
   let InstructionSet = PIC16InstrInfo;

Modified: llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16AsmPrinter.cpp Wed Nov 19 05:00:54 2008
@@ -12,194 +12,70 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "asm-printer"
-#include "PIC16.h"
-#include "PIC16TargetMachine.h"
-#include "PIC16ConstantPoolValue.h"
-#include "PIC16InstrInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
+#include "PIC16AsmPrinter.h"
+#include "PIC16TargetAsmInfo.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Function.h"
 #include "llvm/Module.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include <cctype>
+#include "llvm/DerivedTypes.h"
 
 using namespace llvm;
 
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
-namespace {
-  struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
-    PIC16AsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
-      : AsmPrinter(O, TM, T) {
-    }
-
-
-    /// We name each basic block in a Function with a unique number, so
-    /// that we can consistently refer to them later. This is cleared
-    /// at the beginning of each call to runOnMachineFunction().
-    ///
-    typedef std::map<const Value *, unsigned> ValueMapTy;
-    ValueMapTy NumberForBB;
-
-    /// Keeps the set of GlobalValues that require non-lazy-pointers for
-    /// indirect access.
-    std::set<std::string> GVNonLazyPtrs;
-
-    /// Keeps the set of external function GlobalAddresses that the asm
-    /// printer should generate stubs for.
-    std::set<std::string> FnStubs;
-
-    /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
-    bool InCPMode;
-    
-    virtual const char *getPassName() const {
-      return "PIC16 Assembly Printer";
-    }
-
-    void printOperand(const MachineInstr *MI, int opNum,
-                      const char *Modifier = 0);
-
-    void printSOImmOperand(const MachineInstr *MI, int opNum);
-
-    void printAddrModeOperand(const MachineInstr *MI, int OpNo);
-
-    void printRegisterList(const MachineInstr *MI, int opNum);
-    void printCPInstOperand(const MachineInstr *MI, int opNum,
-                            const char *Modifier);
-
-
-    bool printInstruction(const MachineInstr *MI);  // autogenerated.
-    void emitFunctionStart(MachineFunction &F);
-    bool runOnMachineFunction(MachineFunction &F);
-    bool doInitialization(Module &M);
-    bool doFinalization(Module &M);
-
-    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
-    
-    void getAnalysisUsage(AnalysisUsage &AU) const;
-
-    public:
-    void SwitchToTextSection(const char *NewSection, 
-                             const GlobalValue *GV = NULL);    
-    void SwitchToDataSection(const char *NewSection, 
-                             const GlobalValue *GV = NULL);
-    void SwitchToDataOvrSection(const char *NewSection, 
-                                const GlobalValue *GV = NULL);
-  };
-} // end of anonymous namespace
-
 #include "PIC16GenAsmWriter.inc"
 
-/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16
-/// assembly code for a MachineFunction to the given output stream,
-/// using the given target machine description.  This should work
-/// regardless of whether the function is in SSA form.
-///
-FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o,
-                                               PIC16TargetMachine &tm) {
-  return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
-}
-
-void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const 
-{
-  // FIXME: Currently unimplemented.
-}
-
-
-void PIC16AsmPrinter ::
-EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) 
-{
-  printDataDirective(MCPV->getType());
-
-  PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV;
-  GlobalValue *GV = ACPV->getGV();
-  std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
-  if (!GV)
-    Name += ACPV->getSymbol();
-  if (ACPV->isNonLazyPointer()) {
-    GVNonLazyPtrs.insert(Name);
-    O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
-  } else if (ACPV->isStub()) {
-    FnStubs.insert(Name);
-    O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
-  } else {
-    O << Name;
-  }
-
-  if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
-
-  if (ACPV->getPCAdjustment() != 0) {
-    O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
-      << utostr(ACPV->getLabelId())
-      << "+" << (unsigned)ACPV->getPCAdjustment();
-
-    if (ACPV->mustAddCurrentAddress())
-      O << "-.";
-
-    O << ")";
-  }
-  O << "\n";
-
-  // If the constant pool value is a extern weak symbol, remember to emit
-  // the weak reference.
-  if (GV && GV->hasExternalWeakLinkage())
-    ExtWeakSymbols.insert(GV);
-}
-
-/// emitFunctionStart - Emit the directives used by ASM on the start of 
-/// functions.
-void PIC16AsmPrinter::emitFunctionStart(MachineFunction &MF)
-{
-  // Print out the label for the function.
-  const Function *F = MF.getFunction();
-  MachineFrameInfo *FrameInfo = MF.getFrameInfo();
-  if (FrameInfo->hasStackObjects()) {           
-    int indexBegin = FrameInfo->getObjectIndexBegin();
-    int indexEnd = FrameInfo->getObjectIndexEnd();
-    while (indexBegin < indexEnd) {
-      if (indexBegin == 0)                     
-        SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(),
-                                F);
-                 
-        O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES" 
-          << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ;
-        indexBegin++;
+bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+  std::string NewBankselLabel;
+  unsigned Operands = MI->getNumOperands();
+  if (Operands > 1) {
+    // Global address or external symbol should be second operand from last
+    // if we want to print banksel for it.
+    const MachineOperand &Op = MI->getOperand(Operands-2);
+    unsigned OpType = Op.getType();
+    if (OpType == MachineOperand::MO_GlobalAddress ||
+        OpType == MachineOperand::MO_ExternalSymbol) { 
+      if (OpType == MachineOperand::MO_GlobalAddress ) 
+        NewBankselLabel =  Mang->getValueName(Op.getGlobal());
+      else 
+        NewBankselLabel =  Op.getSymbolName();
+
+      // Operand after global address or external symbol should be  banksel.
+      // Value 1 for this operand means we need to generate banksel else do not
+      // generate banksel.
+      const MachineOperand &BS = MI->getOperand(Operands-1);
+      if (((int)BS.getImm() == 1) &&
+          (strcmp (CurrentBankselLabelInBasicBlock.c_str(),
+                   NewBankselLabel.c_str()))) {
+        CurrentBankselLabelInBasicBlock = NewBankselLabel;
+        O << "\tbanksel ";
+        printOperand(MI, Operands-2);
+        O << "\n";
+      }
     }
   }
-  SwitchToTextSection(CurrentFnName.c_str(), F);  
-  O << "_" << CurrentFnName << ":" ; 
-  O << "\n";
+  printInstruction(MI);
+  return true;
 }
 
-
 /// runOnMachineFunction - This uses the printInstruction()
 /// method to print assembly for each instruction.
 ///
-bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) 
-{
+bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+  // This calls the base class function required to be called at beginning
+  // of runOnMachineFunction.
   SetupMachineFunction(MF);
-  O << "\n";
 
-  // What's my mangled name?
-  CurrentFnName = Mang->getValueName(MF.getFunction());
+  // Get the mangled name.
+  const Function *F = MF.getFunction();
+  CurrentFnName = Mang->getValueName(F);
 
-  // Emit the function start directives
-  emitFunctionStart(MF);
+  // Emit the function variables.
+  emitFunctionData(MF);
+  std::string codeSection;
+  codeSection = "code." + CurrentFnName + ".#";
+  O <<  "\n";
+  SwitchToTextSection (codeSection.c_str(),F);
 
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
@@ -209,319 +85,317 @@
       printBasicBlockLabel(I, true);
       O << '\n';
     }
+    else
+      O << "_" << CurrentFnName << ":\n";
+    CurrentBankselLabelInBasicBlock = "";
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << '\t';
-      printInstruction(II);
-      ++EmittedInsts;
+        printMachineInstruction(II);
     }
   }
+  return false;  // we didn't modify anything.
+}
 
-  // We didn't modify anything.
-  return false;
+/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16
+/// assembly code for a MachineFunction to the given output stream,
+/// using the given target machine description.  This should work
+/// regardless of whether the function is in SSA form.
+///
+FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o,
+                                               PIC16TargetMachine &tm) {
+  return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
 }
 
-void PIC16AsmPrinter::
-printOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
-{
+void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
   const MachineOperand &MO = MI->getOperand(opNum);
-  const TargetRegisterInfo  &RI = *TM.getRegisterInfo();
 
   switch (MO.getType()) {
     case MachineOperand::MO_Register:
       if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
-        O << RI.get(MO.getReg()).Name;
+        O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
       else
         assert(0 && "not implemented");
-      break;
+        return;
 
-    case MachineOperand::MO_Immediate: 
-      if (!Modifier || strcmp(Modifier, "no_hash") != 0)
-        O << "#";
+    case MachineOperand::MO_Immediate:
       O << (int)MO.getImm();
-      break;
-
-    case MachineOperand::MO_MachineBasicBlock:
-      printBasicBlockLabel(MO.getMBB());
       return;
 
-    case MachineOperand::MO_GlobalAddress: 
-      O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset();
+    case MachineOperand::MO_GlobalAddress:
+      O << Mang->getValueName(MO.getGlobal());
       break;
 
-    case MachineOperand::MO_ExternalSymbol: 
+    case MachineOperand::MO_ExternalSymbol:
       O << MO.getSymbolName();
       break;
 
-    case MachineOperand::MO_ConstantPoolIndex:
-      O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-        << '_' << MO.getIndex();
-      break;
-
-    case MachineOperand::MO_FrameIndex:
-      O << "_" << CurrentFnName 
-        << '+' << MO.getIndex();
-      break;
-
-    case MachineOperand::MO_JumpTableIndex:
-      O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-        << '_' << MO.getIndex();
-      break;
-
     default:
-      O << "<unknown operand type>"; abort (); 
-      break;
-  } // end switch.
+      assert(0 && " Operand type not supported.");
+  }
 }
 
-static void 
-printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI) 
-{
-  assert(V < (1 << 12) && "Not a valid so_imm value!");
-  
-  O << (unsigned) V;
+bool PIC16AsmPrinter::doInitialization (Module &M) {
+  bool Result = AsmPrinter::doInitialization(M);
+  // FIXME:: This is temporary solution to generate the include file.
+  // The processor should be passed to llc as in input and the header file
+  // should be generated accordingly.
+  O << "\t#include P16F1937.INC\n";
+
+  EmitInitData (M);
+  EmitUnInitData(M);
+  EmitRomData(M);
+  return Result;
 }
 
-/// printSOImmOperand - SOImm is 4-bit rotated amount in bits 8-11 with 8-bit
-/// immediate in bits 0-7.
-void PIC16AsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) 
+void PIC16AsmPrinter::EmitInitData (Module &M)
 {
-  const MachineOperand &MO = MI->getOperand(OpNum);
-  assert(MO.isImm() && "Not a valid so_imm value!");
-  printSOImm(O, MO.getImm(), TAI);
-}
+  std::string iDataSection = "idata.#";
+  SwitchToDataSection(iDataSection.c_str());
+  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I) {
+    if (!I->hasInitializer())   // External global require no code.
+      continue;
 
+    Constant *C = I->getInitializer();
+    const PointerType *PtrTy = I->getType();
+    int AddrSpace = PtrTy->getAddressSpace();
 
-void PIC16AsmPrinter::printAddrModeOperand(const MachineInstr *MI, int Op) 
-{
-  const MachineOperand &MO1 = MI->getOperand(Op);
-  const MachineOperand &MO2 = MI->getOperand(Op+1);
+    if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::RAM_SPACE)) {
+    
+      if (EmitSpecialLLVMGlobal(I)) 
+        continue;
 
-  if (MO2.isFI()) {
-    printOperand(MI, Op+1);
-    return;
-  }
+      // Any variables reaching here with "." in its name is a local scope
+      // variable and should not be printed in global data section.
+      std::string name = Mang->getValueName(I);
+      if (name.find(".") != std::string::npos)
+        continue;
 
-  if (!MO1.isReg()) {
-    // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op);
-    return;
+      O << name;
+      EmitGlobalConstant(C);
+    }
   }
+}
 
-  // If this is Stack Slot
-  if (MO1.isReg()) {
-    if (strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP") == 0) {
-      O << CurrentFnName <<"_"<< MO2.getImm();
-      return;
+void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) {
+  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+    unsigned BitWidth = CI->getBitWidth();
+    int Val = CI->getZExtValue();
+    if (BitWidth == 8) {
+      // Expecting db directive here. In case of romdata we need to pad the
+      // word with zeros.
+      if (IsRomData)
+        O << 0 <<", ";
+      O << Val; 
+    }
+    else if (BitWidth == 16) {
+      unsigned Element1, Element2;
+      Element1 = 0x00ff & Val;
+      Element2 = 0x00ff & (Val >> 8);
+      if (IsRomData)
+        O << 0 <<", "<<Element1 <<", "<< 0 <<", "<< Element2;
+      else
+        O << Element1 <<", "<< Element2;  
+    }
+    else if (BitWidth == 32) {
+      unsigned Element1, Element2, Element3, Element4;
+      Element1 = 0x00ff & Val;
+      Element2 = 0x00ff & (Val >> 8);
+      Element3 = 0x00ff & (Val >> 16);
+      Element4 = 0x00ff & (Val >> 24);
+      if (IsRomData)
+        O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0 
+          <<", "<< Element3 <<", "<< 0 <<", "<< Element4;
+      else 
+        O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4;    
     }
-    O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
-    O << "+";
-    O << MO2.getImm();
-    O << "]";
     return;
   }
-
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
-  O << "]";
+  AsmPrinter::EmitConstantValueOnly(CV);
 }
 
-
-void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) 
+void PIC16AsmPrinter::EmitRomData (Module &M)
 {
-  O << "{";
-  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
-    printOperand(MI, i);
-    if (i != e-1) O << ", ";
-  }
-  O << "}";
-}
+  std::string romDataSection = "romdata.#";
+  SwitchToRomDataSection(romDataSection.c_str());
+  IsRomData = true;
+  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I) {
+    if (!I->hasInitializer())   // External global require no code.
+      continue;
 
-void PIC16AsmPrinter::
-printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier) 
-{
-  assert(Modifier && "This operand only works with a modifier!");
+    Constant *C = I->getInitializer();
+    const PointerType *PtrTy = I->getType();
+    int AddrSpace = PtrTy->getAddressSpace();
+    if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) {
 
-  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
-  // data itself.
-  if (!strcmp(Modifier, "label")) {
-    unsigned ID = MI->getOperand(OpNo).getImm();
-    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-      << '_' << ID << ":\n";
-  } else {
-    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
-    unsigned CPI = MI->getOperand(OpNo).getIndex();
+      if (EmitSpecialLLVMGlobal(I))
+        continue;
 
-    const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
-      MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
-    
-    if (MCPE.isMachineConstantPoolEntry())
-      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
-    else {
-      EmitGlobalConstant(MCPE.Val.ConstVal);
-      // remember to emit the weak reference
-      if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
-        if (GV->hasExternalWeakLinkage())
-          ExtWeakSymbols.insert(GV);
+      // Any variables reaching here with "." in its name is a local scope
+      // variable and should not be printed in global data section.
+      std::string name = Mang->getValueName(I);
+      if (name.find(".") != std::string::npos)
+        continue;
+
+      O << name;
+      EmitGlobalConstant(C);
+      O << "\n";
     }
   }
+  IsRomData = false;
 }
 
 
-bool PIC16AsmPrinter::doInitialization(Module &M) 
-{
-  bool Result = AsmPrinter::doInitialization(M);
-  return Result;
-}
-
-bool PIC16AsmPrinter::doFinalization(Module &M) 
+void PIC16AsmPrinter::EmitUnInitData (Module &M)
 {
+  std::string uDataSection = "udata.#";
+  SwitchToUDataSection(uDataSection.c_str());
   const TargetData *TD = TM.getTargetData();
 
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
-    if (!I->hasInitializer())   // External global require no code
+    if (!I->hasInitializer())   // External global require no code.
       continue;
 
-    if (EmitSpecialLLVMGlobal(I)) {
-      continue;
+    Constant *C = I->getInitializer();
+    if (C->isNullValue()) {
+
+      if (EmitSpecialLLVMGlobal(I))
+        continue;
+
+      // Any variables reaching here with "." in its name is a local scope
+      // variable and should not be printed in global data section.
+      std::string name = Mang->getValueName(I);
+      if (name.find(".") != std::string::npos)
+        continue;
+
+      const Type *Ty = C->getType();
+      unsigned Size = TD->getABITypeSize(Ty);
+      O << name << " " <<"RES"<< " " << Size ;
+      O << "\n";
     }
+  }
+}
 
-    std::string name = Mang->getValueName(I);
+bool PIC16AsmPrinter::doFinalization(Module &M) {
+  O << "\t" << "END\n";
+  bool Result = AsmPrinter::doFinalization(M);
+  return Result;
+}
+
+void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
+  const Function *F = MF.getFunction();
+  std::string FuncName = Mang->getValueName(F);
+  const Module *M = F->getParent();
+  const TargetData *TD = TM.getTargetData();
+
+  // Emit the data section name.
+  O << "\n"; 
+  std::string fDataSection = "fdata." + CurrentFnName + ".#";
+  SwitchToUDataSection(fDataSection.c_str(), F);
+  // Emit the label for data section of current function.
+  O << "_frame_" << CurrentFnName << ":" ;
+  O << "\n";
+
+  // Emit the function variables. 
+   
+  if (F->hasExternalLinkage()) {
+    O << "\t" << "GLOBAL _frame_"  << CurrentFnName << "\n";
+    O << "\t" << "GLOBAL _"  << CurrentFnName << "\n";
+  }
+  // In PIC16 all the function arguments and local variables are global.
+  // Therefore to get the variable belonging to this function entire
+  // global list will be traversed and variables belonging to this function
+  // will be emitted in the current data section.
+  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
+       I != E; ++I) {
+    std::string VarName = Mang->getValueName(I);
+    
+    // The variables of a function are of form FuncName.* . If this variable
+    // does not belong to this function then continue. 
+    if (!(VarName.find(FuncName + ".") == 0 ? true : false))
+      continue;
+   
     Constant *C = I->getInitializer();
     const Type *Ty = C->getType();
     unsigned Size = TD->getABITypeSize(Ty);
-    unsigned Align = TD->getPreferredAlignmentLog(I);
+    // Emit memory reserve directive.
+    O << VarName << "  RES  " << Size << "\n";
+  }
+  emitFunctionTempData(MF);
+}
 
-    const char *VisibilityDirective = NULL;
-    if (I->hasHiddenVisibility())
-      VisibilityDirective = TAI->getHiddenDirective();
-    else if (I->hasProtectedVisibility())
-      VisibilityDirective = TAI->getProtectedDirective();
+void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF) {
+  // Emit temporary variables.
+  MachineFrameInfo *FrameInfo = MF.getFrameInfo();
+  if (FrameInfo->hasStackObjects()) {
+    int indexBegin = FrameInfo->getObjectIndexBegin();
+    int indexEnd = FrameInfo->getObjectIndexEnd();
 
-    if (VisibilityDirective)
-      O << VisibilityDirective << name << "\n";
+    if (indexBegin < indexEnd)
+      O << CurrentFnName << ".tmp RES"<< " " 
+        <<indexEnd - indexBegin <<"\n";
+    /*
+    while (indexBegin < indexEnd) {
+        O << CurrentFnName << "_tmp_" << indexBegin << " " << "RES"<< " " 
+          << 1 << "\n" ;
+        indexBegin++;
+    }
+    */
+  }
+}
 
-    if (C->isNullValue()) {
-      if (I->hasExternalLinkage()) {
-        if (const char *Directive = TAI->getZeroFillDirective()) {
-          O << "\t.globl\t" << name << "\n";
-          O << Directive << "__DATA__, __common, " << name << ", "
-            << Size << ", " << Align << "\n";
-          continue;
-        }
-      }
+/// The function is same as AsmPrinter::SwitchtoDataSection except the call
+/// to getUDataSectionStartSuffix.
+void PIC16AsmPrinter::SwitchToUDataSection(const char *NewSection,
+                                           const GlobalValue *GV) {
+  std::string NS;
+  if (GV && GV->hasSection())
+    NS = TAI->getSwitchToSectionDirective() + GV->getSection();
+  else
+    NS = NewSection;
 
-      if (!I->hasSection() &&
-          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-           I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
-        if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-        SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
-        if (TAI->getLCOMMDirective() != NULL) {
-          if (I->hasInternalLinkage()) {
-            O << TAI->getLCOMMDirective() << name << "," << Size;
-          } else
-            O << TAI->getCOMMDirective()  << name << "," << Size;
-        } else {
-          if (I->hasInternalLinkage())
-            O << "\t.local\t" << name << "\n";
-
-          O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " " 
-            << Size;
-          O << "\n\t\tGLOBAL" <<" "<< name;
-          if (TAI->getCOMMDirectiveTakesAlignment())
-            O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-        }
-        continue;
-      }
-    }
+  // If we're already in this section, we're done.
+  if (CurrentSection == NS) return;
 
-    switch (I->getLinkage()) {
-    case GlobalValue::AppendingLinkage:
-      // FIXME: appending linkage variables should go into a section of
-      // their name or something.  For now, just emit them as external.
-      // FALL THROUGH
-
-    case GlobalValue::ExternalLinkage:
-      O << "\t.globl " << name << "\n";
-      // FALL THROUGH
+  // Close the current section, if applicable.
+  if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
+    O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n';
 
-    case GlobalValue::InternalLinkage: 
-      break;
+  CurrentSection = NS;
 
-    default:
-      assert(0 && "Unknown linkage type!");
-      break;
-    } // end switch.
+  if (!CurrentSection.empty()){}
+    O << CurrentSection << (static_cast<const PIC16TargetAsmInfo *>(TAI))->
+                            getUDataSectionStartSuffix() << '\n';
 
-    EmitAlignment(Align, I);
-    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
-      << "\n";
+  IsInTextSection = false;
+}
 
-    // If the initializer is a extern weak symbol, remember to emit the weak
-    // reference!
-    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
-      if (GV->hasExternalWeakLinkage())
-        ExtWeakSymbols.insert(GV);
+/// The function is same as AsmPrinter::SwitchtoDataSection except the call
+/// to getRomDataSectionStartSuffix.
+void PIC16AsmPrinter::SwitchToRomDataSection(const char *NewSection,
+                                             const GlobalValue *GV) {
+  std::string NS;
+  if (GV && GV->hasSection())
+    NS = TAI->getSwitchToSectionDirective() + GV->getSection();
+  else
+    NS = NewSection;
 
-    EmitGlobalConstant(C);
-    O << '\n';
-  } // end for.
+  // If we're already in this section, we're done.
+  if (CurrentSection == NS) return;
 
-  O << "\n "<< "END";
-  return AsmPrinter::doFinalization(M);
-}
+  // Close the current section, if applicable.
+  if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
+    O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n';
 
-void PIC16AsmPrinter::
-SwitchToTextSection(const char *NewSection, const GlobalValue *GV)
-{
-  O << "\n";
-  if (NewSection && *NewSection) {
-    std::string codeSection = "code_";
-    codeSection += NewSection;
-    codeSection += " ";
-    codeSection += "CODE";
-    AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV);
-  } 
-  else 
-    AsmPrinter::SwitchToTextSection(NewSection, GV);
-}
+  CurrentSection = NS;
 
-void PIC16AsmPrinter::
-SwitchToDataSection(const char *NewSection, const GlobalValue *GV)
-{
-  // Need to append index for page.
-  O << "\n";
-  if (NewSection && *NewSection) {
-    std::string dataSection = "udata_";
-    dataSection += NewSection;
-    if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
-      dataSection = dataSection.substr(0, dataSection.length() - 2);
-    }
-    dataSection += " ";
-    dataSection += "UDATA";
-    AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
-  } 
-  else
-    AsmPrinter::SwitchToDataSection(NewSection, GV);
-}
+  if (!CurrentSection.empty()) {}
+    O << CurrentSection << (static_cast< const PIC16TargetAsmInfo *>(TAI))->
+                            getRomDataSectionStartSuffix() << '\n';
 
-void PIC16AsmPrinter::
-SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV)
-{
-  O << "\n";
-  if (NewSection && *NewSection) {
-    std::string dataSection = "frame_";
-    dataSection += NewSection;
-    if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
-      dataSection = dataSection.substr(0, dataSection.length() - 2);
-    }          
-    dataSection += "_";
-    dataSection += CurrentFnName;
-    dataSection += " ";
-    dataSection += "UDATA_OVR";
-    AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
-  } 
-  else
-    AsmPrinter::SwitchToDataSection(NewSection, GV);
+  IsInTextSection = false;
 }
+

Removed: llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td?rev=59616&view=auto

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16CallingConv.td (removed)
@@ -1,16 +0,0 @@
-//===- PIC16CallingConv.td - Calling Conventions PIC16 -----*- tablegen -*-===//
-// 
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-// 
-//===----------------------------------------------------------------------===//
-//
-// This describes the calling conventions for the PIC16 architectures.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Return Value Calling Conventions
-//===----------------------------------------------------------------------===//

Removed: llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp?rev=59616&view=auto

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.cpp (removed)
@@ -1,89 +0,0 @@
-//===- PIC16ConstantPoolValue.cpp - PIC16 constantpool value --------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source 
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the PIC16 specific constantpool value class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PIC16ConstantPoolValue.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/Type.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv, unsigned id,
-                                               PIC16CP::PIC16CPKind k,
-                                               unsigned char PCAdj,
-                                               const char *Modif, bool AddCA)
-  : MachineConstantPoolValue((const Type*)gv->getType()),
-    GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj),
-    Modifier(Modif), AddCurrentAddress(AddCA) {}
-
-PIC16ConstantPoolValue::PIC16ConstantPoolValue(const char *s, unsigned id,
-                                               PIC16CP::PIC16CPKind k,
-                                               unsigned char PCAdj,
-                                               const char *Modif, bool AddCA)
-  : MachineConstantPoolValue((const Type*)Type::Int32Ty),
-    GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
-    Modifier(Modif), AddCurrentAddress(AddCA) {}
-
-PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv,
-                                               PIC16CP::PIC16CPKind k,
-                                               const char *Modif)
-  : MachineConstantPoolValue((const Type*)Type::Int32Ty),
-    GV(gv), S(NULL), LabelId(0), Kind(k), PCAdjust(0),
-    Modifier(Modif) {}
-
-int PIC16ConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
-                                                      unsigned Alignment) {
-  unsigned AlignMask = (1 << Alignment)-1;
-  const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
-  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
-    if (Constants[i].isMachineConstantPoolEntry() &&
-        (Constants[i].Offset & AlignMask) == 0) {
-      PIC16ConstantPoolValue *CPV =
-        (PIC16ConstantPoolValue *)Constants[i].Val.MachineCPVal;
-      if (CPV->GV == GV &&
-          CPV->S == S &&
-          CPV->LabelId == LabelId &&
-          CPV->Kind == Kind &&
-          CPV->PCAdjust == PCAdjust)
-        return i;
-    }
-  }
-
-  return -1;
-}
-
-void
-PIC16ConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) {
-  ID.AddPointer(GV);
-  ID.AddPointer(S);
-  ID.AddInteger(LabelId);
-  ID.AddInteger((unsigned)Kind);
-  ID.AddInteger(PCAdjust);
-}
-
-void PIC16ConstantPoolValue::print(raw_ostream &O) const {
-  if (GV)
-    O << GV->getName();
-  else
-    O << S;
-  if (isNonLazyPointer()) O << "$non_lazy_ptr";
-  else if (isStub()) O << "$stub";
-  if (Modifier) O << "(" << Modifier << ")";
-  if (PCAdjust != 0) {
-    O << "-(LPIC" << LabelId << "+"
-      << (unsigned)PCAdjust;
-    if (AddCurrentAddress)
-      O << "-.";
-    O << ")";
-  }
-}

Removed: llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h?rev=59616&view=auto

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ConstantPoolValue.h (removed)
@@ -1,77 +0,0 @@
-//===- PIC16ConstantPoolValue.h - PIC16 constantpool value ------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source 
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the PIC16 specific constantpool value class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H
-#define LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H
-
-#include "llvm/CodeGen/MachineConstantPool.h"
-
-namespace llvm {
-
-class GlobalValue;
-
-namespace PIC16CP {
-  enum PIC16CPKind {
-    CPValue,
-    CPNonLazyPtr,
-    CPStub
-  };
-}
-
-/// PIC16ConstantPoolValue - PIC16 specific constantpool value. This is used to
-/// represent PC relative displacement between the address of the load
-/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)).
-class PIC16ConstantPoolValue : public MachineConstantPoolValue {
-  GlobalValue *GV;         // GlobalValue being loaded.
-  const char *S;           // ExtSymbol being loaded.
-  unsigned LabelId;        // Label id of the load.
-  PIC16CP::PIC16CPKind Kind;   // non_lazy_ptr or stub?
-  unsigned char PCAdjust;  // Extra adjustment if constantpool is pc relative.
-                           // 8 for PIC16
-  const char *Modifier;    // GV modifier i.e. (&GV(modifier)-(LPIC+8))
-  bool AddCurrentAddress;
-
-public:
-  PIC16ConstantPoolValue(GlobalValue *gv, unsigned id,
-                         PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue,
-                         unsigned char PCAdj = 0, const char *Modifier = NULL,
-                         bool AddCurrentAddress = false);
-  PIC16ConstantPoolValue(const char *s, unsigned id,
-                         PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue,
-                         unsigned char PCAdj = 0, const char *Modifier = NULL,
-                         bool AddCurrentAddress = false);
-  PIC16ConstantPoolValue(GlobalValue *GV, PIC16CP::PIC16CPKind Kind,
-                         const char *Modifier);
-
-
-  GlobalValue *getGV() const { return GV; }
-  const char *getSymbol() const { return S; }
-  const char *getModifier() const { return Modifier; }
-  bool hasModifier() const { return Modifier != NULL; }
-  bool mustAddCurrentAddress() const { return AddCurrentAddress; }
-  unsigned getLabelId() const { return LabelId; }
-  bool isNonLazyPointer() const { return Kind == PIC16CP::CPNonLazyPtr; }
-  bool isStub() const { return Kind == PIC16CP::CPStub; }
-  unsigned char getPCAdjustment() const { return PCAdjust; }
-
-  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
-                                        unsigned Alignment);
-
-  virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID);
-
-  virtual void print(raw_ostream &O) const;
-};
-  
-}
-
-#endif

Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp Wed Nov 19 05:00:54 2008
@@ -13,263 +13,47 @@
 
 #define DEBUG_TYPE "pic16-isel"
 
-#include "PIC16.h"
-#include "PIC16ISelLowering.h"
-#include "PIC16RegisterInfo.h"
-#include "PIC16Subtarget.h"
-#include "PIC16TargetMachine.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Type.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/Compiler.h"
+#include "PIC16ISelDAGToDAG.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetMachine.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// Instruction Selector Implementation
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// PIC16DAGToDAGISel - PIC16 specific code to select PIC16 machine
-// instructions for SelectionDAG operations.
-//===----------------------------------------------------------------------===//
-namespace {
-
-class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel {
-
-  /// TM - Keep a reference to PIC16TargetMachine.
-  PIC16TargetMachine &TM;
-
-public:
-  explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : 
-        SelectionDAGISel(*tm.getTargetLowering()),
-        TM(tm) {}
-  
-  virtual void InstructionSelect();
-
-  // Pass Name
-  virtual const char *getPassName() const {
-    return "PIC16 DAG->DAG Pattern Instruction Selection";
-  } 
-  
-private:
-  // Include the pieces autogenerated from the target description.
-#include "PIC16GenDAGISel.inc"
-
-  SDNode *Select(SDValue N);
-
-  // Select addressing mode. currently assume base + offset addr mode.
-  bool SelectAM(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset);
-  bool SelectDirectAM(SDValue Op, SDValue N, SDValue &Base, 
-                      SDValue &Offset);
-  bool StoreInDirectAM(SDValue Op, SDValue N, SDValue &fsr);
-  bool LoadFSR(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset);
-  bool LoadNothing(SDValue Op, SDValue N, SDValue &Base, 
-                   SDValue &Offset);
-
-  // getI8Imm - Return a target constant with the specified
-  // value, of type i8.
-  inline SDValue getI8Imm(unsigned Imm) {
-    return CurDAG->getTargetConstant(Imm, MVT::i8);
-  }
-
 
-#ifndef NDEBUG
-  unsigned Indent;
-#endif
-};
+using namespace llvm;
 
+/// createPIC16ISelDag - This pass converts a legalized DAG into a
+/// PIC16-specific DAG, ready for instruction scheduling.
+FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) {
+  return new PIC16DAGToDAGISel(TM);
 }
 
+
 /// InstructionSelect - This callback is invoked by
 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-void PIC16DAGToDAGISel::InstructionSelect() 
-{
+void PIC16DAGToDAGISel::InstructionSelect() {
   DEBUG(BB->dump());
-  // Codegen the basic block.
-
-  DOUT << "===== Instruction selection begins:\n";
-#ifndef NDEBUG
-  Indent = 0;
-#endif
-
-  // Select target instructions for the DAG.
   SelectRoot(*CurDAG);
-
-  DOUT << "===== Instruction selection ends:\n";
-
   CurDAG->RemoveDeadNodes();
 }
 
-
-bool PIC16DAGToDAGISel::
-SelectDirectAM (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset)
-{
-  GlobalAddressSDNode *GA;
-  ConstantSDNode      *GC;
-
-  // if Address is FI, get the TargetFrameIndex.
-  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
-    DOUT << "--------- its frame Index\n";
-    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
-    Offset = CurDAG->getTargetConstant(0, MVT::i32);
-    return true;
-  }
-
-  if (N.getOpcode() == ISD::GlobalAddress) {
-    GA = dyn_cast<GlobalAddressSDNode>(N);
-    Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8);
-    Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16,
-                                          GA->getOffset());
-    return true;
-  } 
-
-  if (N.getOpcode() == ISD::ADD) {
-    GC = dyn_cast<ConstantSDNode>(N.getOperand(1));
-    Offset = CurDAG->getTargetConstant((unsigned char)GC->getZExtValue(),
-                                       MVT::i8);
-    if ((GA = dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))) {
-      Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, 
-                                            GC->getZExtValue());
-      return true;
-    }
-    else if (FrameIndexSDNode *FIN 
-                = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
-      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
-      return true;
-    }
-  }
-
-  return false;  
-}
-
-
-// FIXME: must also account for preinc/predec/postinc/postdec.
-bool PIC16DAGToDAGISel::
-StoreInDirectAM (SDValue Op, SDValue N, SDValue &fsr)
-{
-  RegisterSDNode *Reg;
-  if (N.getOpcode() == ISD::LOAD) {
-    LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
-    if (LD) {
-      fsr = LD->getBasePtr();
-    }
-    else if (isa<RegisterSDNode>(N.getNode())) { 
-      //FIXME an attempt to retrieve the register number
-      //but does not work
-      DOUT << "this is a register\n";
-      Reg = dyn_cast<RegisterSDNode>(N.getNode());
-      fsr = CurDAG->getRegister(Reg->getReg(),MVT::i16);  
-    }
-    else {
-      DOUT << "this is not a register\n";
-      // FIXME must use whatever load is using
-      fsr = CurDAG->getRegister(1,MVT::i16);
-    }
-    return true;
-  }
-  return false;  
-}
-
-bool PIC16DAGToDAGISel::
-LoadFSR (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset)
-{
-  GlobalAddressSDNode *GA;
-
-  if (N.getOpcode() == ISD::GlobalAddress) {
-    GA = dyn_cast<GlobalAddressSDNode>(N);
-    Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8);
-    Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16,
-                                          GA->getOffset());
-    return true;
-  }
-  else if (N.getOpcode() == PIC16ISD::Package) {
-    CurDAG->setGraphColor(Op.getNode(), "blue");
-    CurDAG->viewGraph();
-  }
-
-  return false;
-}
-
-// LoadNothing - Don't thake this seriously, it will change.
-bool PIC16DAGToDAGISel::
-LoadNothing (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset)
-{
-  GlobalAddressSDNode *GA;
-  if (N.getOpcode() == ISD::GlobalAddress) {
-    GA = dyn_cast<GlobalAddressSDNode>(N);
-    DOUT << "==========" << GA->getOffset() << "\n";
-    Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8);
-    Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16,
-                                          GA->getOffset());
-    return true;
-  }  
-
-  return false;
-}
-
-
 /// Select - Select instructions not customized! Used for
 /// expanded, promoted and normal instructions.
-SDNode* PIC16DAGToDAGISel::Select(SDValue N) 
-{
-  SDNode *Node = N.getNode();
-  unsigned Opcode = Node->getOpcode();
-
-  // Dump information about the Node being selected
-#ifndef NDEBUG
-  DOUT << std::string(Indent, ' ') << "Selecting: ";
-  DEBUG(Node->dump(CurDAG));
-  DOUT << "\n";
-  Indent += 2;
-#endif
-
-  // If we have a custom node, we already have selected!
-  if (Node->isMachineOpcode()) {
-#ifndef NDEBUG
-    DOUT << std::string(Indent-2, ' ') << "== ";
-    DEBUG(Node->dump(CurDAG));
-    DOUT << "\n";
-    Indent -= 2;
-#endif
-    return NULL;
-  }
-
-  ///
-  // FIXME: Instruction Selection not handled by custom or by the 
-  // auto-generated tablegen selection should be handled here.
-  /// 
-  switch(Opcode) {
-    default: break;
-  }
+SDNode* PIC16DAGToDAGISel::Select(SDValue N) {
 
   // Select the default instruction.
   SDNode *ResNode = SelectCode(N);
 
-#ifndef NDEBUG
-  DOUT << std::string(Indent-2, ' ') << "=> ";
-  if (ResNode == NULL || ResNode == N.getNode())
-    DEBUG(N.getNode()->dump(CurDAG));
-  else
-    DEBUG(ResNode->dump(CurDAG));
-  DOUT << "\n";
-  Indent -= 2;
-#endif
-
   return ResNode;
 }
 
-/// createPIC16ISelDag - This pass converts a legalized DAG into a 
-/// PIC16-specific DAG, ready for instruction scheduling.
-FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) {
-  return new PIC16DAGToDAGISel(TM);
-}
 
+// SelectDirectAddr - Match a direct address for DAG. 
+// A direct address could be a globaladdress or externalsymbol.
+bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue Op, SDValue N, 
+                                      SDValue &Address) {
+  // Return true if TGA or ES.
+  if (N.getOpcode() == ISD::TargetGlobalAddress
+      || N.getOpcode() == ISD::TargetExternalSymbol) {
+    Address = N;
+    return true;
+  }
+
+  return false;
+}

Added: llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h?rev=59617&view=auto

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h (added)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelDAGToDAG.h Wed Nov 19 05:00:54 2008
@@ -0,0 +1,60 @@
+//===-- PIC16ISelDAGToDAG.cpp - A dag to dag inst selector for PIC16 ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an instruction selector for the PIC16 target.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "pic16-isel"
+
+#include "PIC16.h"
+#include "PIC16ISelLowering.h"
+#include "PIC16RegisterInfo.h"
+#include "PIC16TargetMachine.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Intrinsics.h"
+using namespace llvm;
+
+namespace {
+
+class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel {
+
+  /// TM - Keep a reference to PIC16TargetMachine.
+  PIC16TargetMachine &TM;
+
+  /// PIC16Lowering - This object fully describes how to lower LLVM code to an
+  /// PIC16-specific SelectionDAG.
+  PIC16TargetLowering PIC16Lowering;
+
+public:
+  explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : 
+        SelectionDAGISel(PIC16Lowering),
+        TM(tm), PIC16Lowering(*TM.getTargetLowering()) {}
+  
+  // Pass Name
+  virtual const char *getPassName() const {
+    return "PIC16 DAG->DAG Pattern Instruction Selection";
+  } 
+
+  virtual void InstructionSelect();
+  
+private:
+  // Include the pieces autogenerated from the target description.
+#include "PIC16GenDAGISel.inc"
+
+  SDNode *Select(SDValue N);
+
+  // Match direct address complex pattern.
+  bool SelectDirectAddr(SDValue Op, SDValue N, SDValue &Address);
+
+};
+
+}
+

Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed Nov 19 05:00:54 2008
@@ -17,751 +17,662 @@
 #include "PIC16ISelLowering.h"
 #include "PIC16TargetMachine.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/GlobalValue.h"
 #include "llvm/Function.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/CallingConv.h"
-#include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/Debug.h"
-using namespace llvm;
 
-const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const 
-{
-  switch (Opcode) {
-    case PIC16ISD::Hi        : return "PIC16ISD::Hi";
-    case PIC16ISD::Lo        : return "PIC16ISD::Lo";
-    case PIC16ISD::Package   : return "PIC16ISD::Package";
-    case PIC16ISD::Wrapper   : return "PIC16ISD::Wrapper";
-    case PIC16ISD::SetBank   : return "PIC16ISD::SetBank";
-    case PIC16ISD::SetPage   : return "PIC16ISD::SetPage";
-    case PIC16ISD::Branch    : return "PIC16ISD::Branch";
-    case PIC16ISD::Cmp       : return "PIC16ISD::Cmp";
-    case PIC16ISD::BTFSS     : return "PIC16ISD::BTFSS";
-    case PIC16ISD::BTFSC     : return "PIC16ISD::BTFSC";
-    case PIC16ISD::XORCC     : return "PIC16ISD::XORCC";
-    case PIC16ISD::SUBCC     : return "PIC16ISD::SUBCC";
-    default                  : return NULL;
-  }
-}
-
-PIC16TargetLowering::
-PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM) 
-{
-  // Set up the register classes.
-  addRegisterClass(MVT::i8, PIC16::CPURegsRegisterClass);
-  addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass);
-
-  // Load extented operations for i1 types must be promoted .
-  setLoadExtAction(ISD::EXTLOAD, MVT::i1,  Promote);
-  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
-  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
-
-  setOperationAction(ISD::ADD, MVT::i1, Promote);
-  setOperationAction(ISD::ADD, MVT::i8, Legal);
-  setOperationAction(ISD::ADD, MVT::i16, Custom);
-  setOperationAction(ISD::ADD, MVT::i32, Expand);
-  setOperationAction(ISD::ADD, MVT::i64, Expand);
-
-  setOperationAction(ISD::SUB, MVT::i1, Promote);
-  setOperationAction(ISD::SUB, MVT::i8, Legal);
-  setOperationAction(ISD::SUB, MVT::i16, Custom);
-  setOperationAction(ISD::SUB, MVT::i32, Expand);
-  setOperationAction(ISD::SUB, MVT::i64, Expand);
-
-  setOperationAction(ISD::ADDC, MVT::i1, Promote);
-  setOperationAction(ISD::ADDC, MVT::i8, Legal);
-  setOperationAction(ISD::ADDC, MVT::i16, Custom);
-  setOperationAction(ISD::ADDC, MVT::i32, Expand);
-  setOperationAction(ISD::ADDC, MVT::i64, Expand);
-
-  setOperationAction(ISD::ADDE, MVT::i1, Promote);
-  setOperationAction(ISD::ADDE, MVT::i8, Legal);
-  setOperationAction(ISD::ADDE, MVT::i16, Custom);
-  setOperationAction(ISD::ADDE, MVT::i32, Expand);
-  setOperationAction(ISD::ADDE, MVT::i64, Expand);
-
-  setOperationAction(ISD::SUBC, MVT::i1, Promote);
-  setOperationAction(ISD::SUBC, MVT::i8, Legal);
-  setOperationAction(ISD::SUBC, MVT::i16, Custom);
-  setOperationAction(ISD::SUBC, MVT::i32, Expand);
-  setOperationAction(ISD::SUBC, MVT::i64, Expand);
-
-  setOperationAction(ISD::SUBE, MVT::i1, Promote);
-  setOperationAction(ISD::SUBE, MVT::i8, Legal);
-  setOperationAction(ISD::SUBE, MVT::i16, Custom);
-  setOperationAction(ISD::SUBE, MVT::i32, Expand);
-  setOperationAction(ISD::SUBE, MVT::i64, Expand);
-
-  // PIC16 does not have these NodeTypes below.
-  setOperationAction(ISD::SETCC, MVT::i1, Expand);
-  setOperationAction(ISD::SETCC, MVT::i8, Expand);
-  setOperationAction(ISD::SETCC, MVT::Other, Expand);
-  setOperationAction(ISD::SELECT_CC, MVT::i1, Custom);
-  setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
-
-  setOperationAction(ISD::BRCOND, MVT::i1, Expand);
-  setOperationAction(ISD::BRCOND, MVT::i8, Expand);
-  setOperationAction(ISD::BRCOND, MVT::Other, Expand);
 
-  setOperationAction(ISD::BR_CC, MVT::i1, Custom);
-  setOperationAction(ISD::BR_CC, MVT::i8, Custom);
+using namespace llvm;
 
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
 
+// PIC16TargetLowering Constructor.
+PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
+  : TargetLowering(TM) {
   
-  // FIXME: Do we really need to Custom lower the GA ??
-  setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
-  setOperationAction(ISD::RET, MVT::Other, Custom);
-
-  setOperationAction(ISD::CTPOP, MVT::i32, Expand);
-  setOperationAction(ISD::CTTZ, MVT::i32, Expand);
-  setOperationAction(ISD::CTLZ, MVT::i32, Expand);
-  setOperationAction(ISD::ROTL, MVT::i32, Expand);
-  setOperationAction(ISD::ROTR, MVT::i32, Expand);
-  setOperationAction(ISD::BSWAP, MVT::i32, Expand);
-
-  setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
-  setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
-  setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
-
-  // We don't have line number support yet.
-  setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
-  setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
-  setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
-  setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
-
-  // Use the default for now.
-  setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
-  setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
-
-  setOperationAction(ISD::LOAD, MVT::i1, Promote);
-  setOperationAction(ISD::LOAD, MVT::i8, Legal);
-
-  setTargetDAGCombine(ISD::LOAD);
-  setTargetDAGCombine(ISD::STORE);
-  setTargetDAGCombine(ISD::ADDE);
-  setTargetDAGCombine(ISD::ADDC);
-  setTargetDAGCombine(ISD::ADD);
-  setTargetDAGCombine(ISD::SUBE);
-  setTargetDAGCombine(ISD::SUBC);
-  setTargetDAGCombine(ISD::SUB);
+  Subtarget = &TM.getSubtarget<PIC16Subtarget>();
 
-  setStackPointerRegisterToSaveRestore(PIC16::STKPTR);
-  computeRegisterProperties();
-}
+  addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
 
+  setShiftAmountType(MVT::i8);
+  setShiftAmountFlavor(Extend);
 
-SDValue PIC16TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) 
-{
-  SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other);
-  switch (Op.getOpcode()) {
-    case ISD::STORE: 
-      DOUT << "reduce store\n"; 
-      break;
 
-    case ISD::FORMAL_ARGUMENTS:   
-      DOUT << "==== lowering formal args\n";
-      return LowerFORMAL_ARGUMENTS(Op, DAG);
+  setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
 
-    case ISD::GlobalAddress:      
-      DOUT << "==== lowering GA\n";
-      return LowerGlobalAddress(Op, DAG);
-
-    case ISD::RET:                
-      DOUT << "==== lowering ret\n";
-      return LowerRET(Op, DAG);
-
-    case ISD::FrameIndex:                
-      DOUT << "==== lowering frame index\n";
-      return LowerFrameIndex(Op, DAG);
-
-    case ISD::ADDE: 
-      DOUT << "==== lowering adde\n"; 
-      break;
+  setOperationAction(ISD::LOAD,   MVT::i8,  Legal);
+  setOperationAction(ISD::LOAD,   MVT::i16, Custom);
+  setOperationAction(ISD::LOAD,   MVT::i32, Custom);
 
-    case ISD::LOAD:
-    case ISD::ADD: 
-      break;
+  setOperationAction(ISD::STORE,  MVT::i8,  Legal);
+  setOperationAction(ISD::STORE,  MVT::i16, Custom);
+  setOperationAction(ISD::STORE,  MVT::i32, Custom);
 
-    case ISD::BR_CC:                
-      DOUT << "==== lowering BR_CC\n"; 
-      return LowerBR_CC(Op, DAG); 
-  } // end switch.
-  return SDValue();
-}
+  setOperationAction(ISD::ADDE,    MVT::i8,  Custom);
+  setOperationAction(ISD::ADDC,    MVT::i8,  Custom);
+  setOperationAction(ISD::SUBE,    MVT::i8,  Custom);
+  setOperationAction(ISD::SUBC,    MVT::i8,  Custom);
+  setOperationAction(ISD::ADD,    MVT::i8,  Legal);
+  setOperationAction(ISD::ADD,    MVT::i16, Custom);
 
+  setOperationAction(ISD::SHL,    MVT::i16, Custom);
+  setOperationAction(ISD::SHL,    MVT::i32, Custom);
 
-//===----------------------------------------------------------------------===//
-//  Lower helper functions
-//===----------------------------------------------------------------------===//
-
-SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) 
-{
-  MVT VT = Op.getValueType();
-  SDValue Chain = Op.getOperand(0);
-  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
-  SDValue LHS = Op.getOperand(2);
-  SDValue RHS = Op.getOperand(3);
-  SDValue JumpVal = Op.getOperand(4);
-  SDValue Result;
-  unsigned  cmpOpcode;
-  unsigned  branchOpcode;
-  SDValue branchOperand;
-
-  SDValue StatusReg = DAG.getRegister(PIC16::STATUSREG, MVT::i8);
-  SDValue CPUReg = DAG.getRegister(PIC16::WREG, MVT::i8);
-  switch(CC) {
-    default:
-      assert(0 && "This condition code is not handled yet!!");
-      abort();
+  //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
+  setTruncStoreAction(MVT::i16,   MVT::i8,  Custom);
 
-    case ISD::SETNE:
-      DOUT << "setne\n";
-      cmpOpcode = PIC16ISD::XORCC;
-      branchOpcode = PIC16ISD::BTFSS;
-      branchOperand = DAG.getConstant(2, MVT::i8);
-      break;
-
-    case ISD::SETEQ:
-      DOUT << "seteq\n";
-      cmpOpcode = PIC16ISD::XORCC;
-      branchOpcode = PIC16ISD::BTFSC;
-      branchOperand = DAG.getConstant(2, MVT::i8);
-      break;
-
-    case ISD::SETGT:
-      assert(0 && "Greater Than condition code is not handled yet!!");
-      abort();
-      break;
-
-    case ISD::SETGE:
-      DOUT << "setge\n";
-      cmpOpcode = PIC16ISD::SUBCC;
-      branchOpcode = PIC16ISD::BTFSS;
-      branchOperand = DAG.getConstant(1, MVT::i8);
-      break;
-
-    case ISD::SETLT:
-      DOUT << "setlt\n";
-      cmpOpcode = PIC16ISD::SUBCC;
-      branchOpcode = PIC16ISD::BTFSC;
-      branchOperand = DAG.getConstant(1,MVT::i8);
-      break;
-
-    case ISD::SETLE:
-      assert(0 && "Less Than Equal condition code is not handled yet!!");
-      abort();
-      break;
-  }  // End of Switch
-
-   SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
-   SDValue CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1);
-   Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand, 
-                        StatusReg, CmpValue);
-   return Result;
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Misc Lower Operation implementation
-//===----------------------------------------------------------------------===//
-
-// LowerGlobalAddress - Create a constant pool entry for global value 
-// and wrap it in a wrapper node.
-SDValue
-PIC16TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) 
-{
-  MVT PtrVT = getPointerTy();
-  GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
-  GlobalValue *GV = GSDN->getGlobal();
-
-  // FIXME: for now only do the ram.
-  SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
-  SDValue CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr);
-  CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank);
-
-  return CPAddr;
-}
-
-SDValue
-PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) 
-{
-  switch(Op.getNumOperands()) {
-    default:
-      assert(0 && "Do not know how to return this many arguments!");
-      abort();
+  // Now deduce the information based on the above mentioned 
+  // actions
+  computeRegisterProperties();
+}
 
-    case 1:
-      return SDValue(); // ret void is legal
+const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
+  switch (Opcode) {
+  default:                         return NULL;
+  case PIC16ISD::Lo:               return "PIC16ISD::Lo";
+  case PIC16ISD::Hi:               return "PIC16ISD::Hi";
+  case PIC16ISD::MTLO:             return "PIC16ISD::MTLO";
+  case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
+  case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
+  case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
+  case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
+  case PIC16ISD::BCF:              return "PIC16ISD::BCF";
+  case PIC16ISD::LSLF:             return "PIC16ISD::LSLF";
+  case PIC16ISD::LRLF:             return "PIC16ISD::LRLF";
+  case PIC16ISD::RLF:              return "PIC16ISD::RLF";
+  case PIC16ISD::RRF:              return "PIC16ISD::RRF";
+  case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
   }
 }
 
-SDValue
-PIC16TargetLowering::LowerFrameIndex(SDValue N, SelectionDAG &DAG) 
-{
-  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
-    return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32);
-  }
-
-  return N;
-}
-
-SDValue
-PIC16TargetLowering::LowerLOAD(SDNode *N,
-                               SelectionDAG &DAG,
-                               DAGCombinerInfo &DCI) const
-{
-  SDValue Outs[2];
-  SDValue TF; //TokenFactor
-  SDValue OutChains[2];
-  SDValue Chain = N->getOperand(0);  
-  SDValue Src   = N->getOperand(1);
-  SDValue retVal;
-  SDVTList VTList;
-
-  // If this load is directly stored, replace the load value with the stored
-  // value.
-  // FIXME: Handle store large -> read small portion.
-  // FIXME: Handle TRUNCSTORE/LOADEXT
-  LoadSDNode *LD  = cast<LoadSDNode>(N);
-  SDValue Ptr   = LD->getBasePtr();
-  if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
-    if (ISD::isNON_TRUNCStore(Chain.getNode())) {
-      StoreSDNode *PrevST = cast<StoreSDNode>(Chain);
-      if (PrevST->getBasePtr() == Ptr &&
-          PrevST->getValue().getValueType() == N->getValueType(0))
-        return DCI.CombineTo(N, Chain.getOperand(1), Chain);
+SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
+  switch (N->getOpcode()) {
+    case ISD::GlobalAddress:
+      return ExpandGlobalAddress(N, DAG);
+    case ISD::STORE:
+      return ExpandStore(N, DAG);
+    case ISD::LOAD:
+      return ExpandLoad(N, DAG);
+    case ISD::ADD:
+      return ExpandAdd(N, DAG);
+    case ISD::SHL:
+      return ExpandShift(N, DAG);
+    default:
+      assert (0 && "not implemented");
+  }
+}
+
+SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { 
+  StoreSDNode *St = cast<StoreSDNode>(N);
+  SDValue Chain = St->getChain();
+  SDValue Src = St->getValue();
+  SDValue Ptr = St->getBasePtr();
+  MVT ValueType = Src.getValueType();
+  unsigned StoreOffset = 0;
+
+  SDValue PtrLo, PtrHi;
+  LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
+ 
+  if (ValueType == MVT::i8) {
+    SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
+                                 PtrLo, PtrHi, DAG.getConstant (0, MVT::i8));
+    return Store.getNode();
+  }
+  else if (ValueType == MVT::i16) {
+    // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
+    SDValue SrcLo, SrcHi;
+    GetExpandedParts(Src, DAG, SrcLo, SrcHi);
+    SDValue ChainLo = Chain, ChainHi = Chain;
+    if (Chain.getOpcode() == ISD::TokenFactor) {
+      ChainLo = Chain.getOperand(0);
+      ChainHi = Chain.getOperand(1);
     }
+    SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
+                                 ChainLo,
+                                 SrcLo, PtrLo, PtrHi,
+                                 DAG.getConstant (0 + StoreOffset, MVT::i8));
+
+    SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi, 
+                                 SrcHi, PtrLo, PtrHi,
+                                 DAG.getConstant (1 + StoreOffset, MVT::i8));
+
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
+                       getChain(Store2)).getNode();
   }
+  else if (ValueType == MVT::i32) {
+    // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
+    SDValue SrcLo, SrcHi;
+    GetExpandedParts(Src, DAG, SrcLo, SrcHi);
+
+    // Get the expanded parts of each of SrcLo and SrcHi.
+    SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
+    GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
+    GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
+
+    SDValue ChainLo = Chain, ChainHi = Chain;
+    if (Chain.getOpcode() == ISD::TokenFactor) {  
+      ChainLo = Chain.getOperand(0);
+      ChainHi = Chain.getOperand(1);
+    }
+    SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
+            ChainHi2 = ChainHi;
+    if (ChainLo.getOpcode() == ISD::TokenFactor) {
+      ChainLo1 = ChainLo.getOperand(0);
+      ChainLo2 = ChainLo.getOperand(1);
+    }
+    if (ChainHi.getOpcode() == ISD::TokenFactor) {
+      ChainHi1 = ChainHi.getOperand(0);
+      ChainHi2 = ChainHi.getOperand(1);
+    }
+    SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
+                                 ChainLo1,
+                                 SrcLo1, PtrLo, PtrHi,
+                                 DAG.getConstant (0 + StoreOffset, MVT::i8));
+
+    SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
+                                 SrcLo2, PtrLo, PtrHi,
+                                 DAG.getConstant (1 + StoreOffset, MVT::i8));
+
+    SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
+                                 SrcHi1, PtrLo, PtrHi,
+                                 DAG.getConstant (2 + StoreOffset, MVT::i8));
+
+    SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
+                                 SrcHi2, PtrLo, PtrHi,
+                                 DAG.getConstant (3 + StoreOffset, MVT::i8));
+
+    SDValue RetLo =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
+                                 getChain(Store2));
+    SDValue RetHi =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
+                                getChain(Store4));
+    return  DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode();
 
-  if (N->getValueType(0) != MVT::i16)
-    return SDValue();
+  }
+  else {
+    assert (0 && "value type not supported");
+  }
+}
 
-  SDValue toWorklist;
-  Outs[0] = DAG.getLoad(MVT::i8, Chain, Src, NULL, 0);
-  toWorklist = DAG.getNode(ISD::ADD, MVT::i16, Src,
-                           DAG.getConstant(1, MVT::i16));
-  Outs[1] = DAG.getLoad(MVT::i8, Chain, toWorklist, NULL, 0);
-  // FIXME: Add to worklist may not be needed. 
-  // It is meant to merge sequences of add with constant into one. 
-  DCI.AddToWorklist(toWorklist.getNode());   
+// ExpandGlobalAddress - 
+SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
+  GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
   
-  // Create the tokenfactors and carry it on to the build_pair node
-  OutChains[0] = Outs[0].getValue(1);
-  OutChains[1] = Outs[1].getValue(1);
-  TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &OutChains[0], 2);
-  
-  VTList = DAG.getVTList(MVT::i16, MVT::Flag);
-  retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2);
+  SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
+                                           G->getOffset());
 
-  DCI.CombineTo (N, retVal, TF);
+  SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
+  SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
 
-  return retVal;
+  SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
+  return BP.getNode();
 }
 
-SDValue
-PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG,
-                                 DAGCombinerInfo &DCI) const
-{
-  bool changed = false;
-  int i;
-  SDValue LoOps[3], HiOps[3];
-  SDValue OutOps[3]; // [0]:left, [1]:right, [2]:carry
-  SDValue InOp[2];
-  SDValue retVal;
-  SDValue as1,as2;
-  SDVTList VTList;
-  unsigned AS = 0, ASE = 0, ASC=0;
+bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
+  assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
 
-  InOp[0] = N->getOperand(0);
-  InOp[1] = N->getOperand(1);  
+  if (Op.getOpcode() == ISD::BUILD_PAIR) {
+   if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) 
+     return true;
+  }
+  return false;
+}
 
-  switch (N->getOpcode()) {
-    case ISD::ADD:
-      if (InOp[0].getOpcode() == ISD::Constant &&
-          InOp[1].getOpcode() == ISD::Constant) {
-        ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
-        ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
-        return DAG.getConstant(CST0->getZExtValue() + CST1->getZExtValue(),
-                               MVT::i16);
-      }
-      break;
+// Return true if DirectAddress is in ROM_SPACE
+bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
 
-    case ISD::ADDE:
-    case ISD::ADDC:
-      AS  = ISD::ADD;
-      ASE = ISD::ADDE;
-      ASC = ISD::ADDC;
-      break;
-
-    case ISD::SUB:
-      if (InOp[0].getOpcode() == ISD::Constant &&
-          InOp[1].getOpcode() == ISD::Constant) {
-        ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
-        ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
-        return DAG.getConstant(CST0->getZExtValue() - CST1->getZExtValue(),
-                               MVT::i16);
-      }
-      break;
+  // RomAddress is a GlobalAddress in ROM_SPACE_
+  // If the Op is not a GlobalAddress return NULL without checking
+  // anything further.
+  if (!isDirectAddress(Op))
+    return false; 
+
+  // Its a GlobalAddress.
+  // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
+  SDValue TGA = Op.getOperand(0).getOperand(0);
+  GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
+  const Type *ValueType = GSDN->getGlobal()->getType();
 
-    case ISD::SUBE:
-    case ISD::SUBC:
-      AS  = ISD::SUB;
-      ASE = ISD::SUBE;
-      ASC = ISD::SUBC;
-      break;
-  } // end switch.
-
-  assert ((N->getValueType(0) == MVT::i16) 
-           && "expecting an MVT::i16 node for lowering");
-  assert ((N->getOperand(0).getValueType() == MVT::i16) 
-           && (N->getOperand(1).getValueType() == MVT::i16) 
-            && "both inputs to addx/subx:i16 must be i16");
-
-  for (i = 0; i < 2; i++) {
-    if (InOp[i].getOpcode() == ISD::GlobalAddress) {
-      // We don't want to lower subs/adds with global address yet.
-      return SDValue();
-    }
-    else if (InOp[i].getOpcode() == ISD::Constant) {
-      changed = true;
-      ConstantSDNode *CST = dyn_cast<ConstantSDNode>(InOp[i]);
-      LoOps[i] = DAG.getConstant(CST->getZExtValue() & 0xFF, MVT::i8);
-      HiOps[i] = DAG.getConstant(CST->getZExtValue() >> 8, MVT::i8);
-    }
-    else if (InOp[i].getOpcode() == PIC16ISD::Package) {
-      LoOps[i] = InOp[i].getOperand(0);
-      HiOps[i] = InOp[i].getOperand(1);
-    }
-    else if (InOp[i].getOpcode() == ISD::LOAD) {
-      changed = true;
-      // LowerLOAD returns a Package node or it may combine and return 
-      // anything else.
-      SDValue lowered = LowerLOAD(InOp[i].getNode(), DAG, DCI);
-
-      // So If LowerLOAD returns something other than Package, 
-      // then just call ADD again.
-      if (lowered.getOpcode() != PIC16ISD::Package)
-        return LowerADDSUB(N, DAG, DCI);
-          
-      LoOps[i] = lowered.getOperand(0);
-      HiOps[i] = lowered.getOperand(1);
-    }
-    else if ((InOp[i].getOpcode() == ISD::ADD) || 
-             (InOp[i].getOpcode() == ISD::ADDE) ||
-             (InOp[i].getOpcode() == ISD::ADDC) ||
-             (InOp[i].getOpcode() == ISD::SUB) ||
-             (InOp[i].getOpcode() == ISD::SUBE) ||
-             (InOp[i].getOpcode() == ISD::SUBC)) {
-      changed = true;
-      // Must call LowerADDSUB recursively here,
-      // LowerADDSUB returns a Package node.
-      SDValue lowered = LowerADDSUB(InOp[i].getNode(), DAG, DCI);
+  if (!isa<PointerType>(ValueType)) {
+    assert(0 && "TGA must be of a PointerType");
+  }
 
-      LoOps[i] = lowered.getOperand(0);
-      HiOps[i] = lowered.getOperand(1);
-    }
-    else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) {
-      // FIXME: I am just zero extending. for now.
-      changed = true;
-      LoOps[i] = InOp[i].getOperand(0);
-      HiOps[i] = DAG.getConstant(0, MVT::i8);
-    }
-    else {
-      DAG.setGraphColor(N, "blue");
-      DAG.viewGraph();
-      assert (0 && "not implemented yet");
-    }
-  } // end for.
+  int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
+  if (AddrSpace == PIC16ISD::ROM_SPACE)
+    return true;
+
+  // Any other address space return it false
+  return false;
+}
+
+// To extract chain value from the SDValue Nodes
+// This function will help to maintain the chain extracting
+// code at one place. In case of any change in future it will
+// help maintain the code.
+SDValue PIC16TargetLowering::getChain(SDValue &Op) { 
+  SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
+
+  // All nodes may not produce a chain. Therefore following assert
+  // verifies that the node is returning a chain only.
+  assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
+
+  return Chain;
+}
+
+void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
+                                           SDValue &Lo, SDValue &Hi) {  
+  SDNode *N = Op.getNode();
+  unsigned NumValues = N->getNumValues();
+  std::vector<MVT> VTs;
+  MVT NewVT;
+  std::vector<SDValue> Opers;
+
+  // EXTRACT_ELEMENT should have same number and type of values that the 
+  // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element)
+  // Some nodes such as LOAD and PIC16Load have more than one values. In such 
+  // cases EXTRACT_ELEMENT should have more than one values. Therefore creating
+  // vector of Values for EXTRACT_ELEMENT. This list will have same number of 
+  // values as the extracted element will have.
+
+  for (unsigned i=0;i < NumValues; ++i) {
+    NewVT = getTypeToTransformTo(N->getValueType(i));
+    VTs.push_back(NewVT);
+  }
 
-  assert (changed && "nothing changed while lowering SUBx/ADDx");
+  // extract the lo component
+  Opers.push_back(Op);
+  Opers.push_back(DAG.getConstant(0,MVT::i8));
+  Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
+
+  // extract the hi component
+  Opers.clear();
+  Opers.push_back(Op);
+  Opers.push_back(DAG.getConstant(1,MVT::i8));
+  Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
+}
+
+// This function legalizes the PIC16 Addresses. If the Pointer is  
+//  -- Direct address variable residing 
+//     --> then a Banksel for that variable will be created.
+//  -- Rom variable            
+//     --> then it will be treated as an indirect address.
+//  -- Indirect address 
+//     --> then the address will be loaded into FSR
+//  -- ADD with constant operand
+//     --> then constant operand of ADD will be returned as Offset
+//         and non-constant operand of ADD will be treated as pointer.
+// Returns the high and lo part of the address, and the offset(in case of ADD).
+
+void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, 
+                                           SDValue &Lo, SDValue &Hi,
+                                           unsigned &Offset) {
+
+  // Offset, by default, should be 0
+  Offset = 0;
+
+  // If the pointer is ADD with constant,
+  // return the constant value as the offset  
+  if (Ptr.getOpcode() == ISD::ADD) {
+    SDValue OperLeft = Ptr.getOperand(0);
+    SDValue OperRight = Ptr.getOperand(1);
+    if (OperLeft.getOpcode() == ISD::Constant) {
+      Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
+      Ptr = OperRight;
+    } else {
+      Ptr = OperLeft;
+      Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
+    }
+  }
 
-  VTList = DAG.getVTList(MVT::i8, MVT::Flag);
-  if (N->getOpcode() == ASE) { 
-    // We must take in the existing carry
-    // if this node is part of an existing subx/addx sequence.
-    LoOps[2] = N->getOperand(2).getValue(1);
-    as1 = DAG.getNode (ASE, VTList, LoOps, 3);
+  if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
+    // Direct addressing case for RAM variables. The Hi part is constant
+    // and the Lo part is the TGA itself.
+    Lo = Ptr.getOperand(0).getOperand(0);
+
+    // For direct addresses Hi is a constant. Value 1 for the constant
+    // signifies that banksel needs to generated for it. Value 0 for
+    // the constant signifies that banksel does not need to be generated 
+    // for it. Mark it as 1 now and optimize later. 
+    Hi = DAG.getConstant(1, MVT::i8);
+    return; 
   }
-  else {
-    as1 = DAG.getNode (ASC, VTList, LoOps, 2);
+
+  // Indirect addresses. Get the hi and lo parts of ptr. 
+  GetExpandedParts(Ptr, DAG, Lo, Hi);
+
+  // Put the hi and lo parts into FSR.
+  Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
+  Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
+
+  return;
+}
+
+SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
+  SDValue OperLeft = N->getOperand(0);
+  SDValue OperRight = N->getOperand(1);
+
+  if((OperLeft.getOpcode() == ISD::Constant) || 
+     (OperRight.getOpcode() == ISD::Constant)) { 
+    return NULL;
   }
-  HiOps[2] = as1.getValue(1);
-  as2 = DAG.getNode (ASE, VTList, HiOps, 3);
-  // We must build a pair that also provides the carry from sube/adde.
-  OutOps[0] = as1;
-  OutOps[1] = as2;
-  OutOps[2] = as2.getValue(1);
-  // Breaking an original i16, so lets make the Package also an i16.
-  if (N->getOpcode() == ASE) {
-    VTList = DAG.getVTList(MVT::i16, MVT::Flag);
-    retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3);
-    DCI.CombineTo (N, retVal, OutOps[2]);
+
+  // These case are yet to be handled
+  return NULL;
+}
+
+SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
+  LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
+  SDValue Chain = LD->getChain();
+  SDValue Ptr = LD->getBasePtr();
+
+  SDValue Load, Offset;
+  SDVTList Tys; 
+  MVT VT, NewVT;
+  SDValue PtrLo, PtrHi;
+  unsigned LoadOffset;
+
+  // Legalize direct/indirect addresses. This will give the lo and hi parts
+  // of the address and the offset.
+  LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
+
+  // Load from the pointer (direct address or FSR) 
+  VT = N->getValueType(0);
+  unsigned NumLoads = VT.getSizeInBits() / 8; 
+  std::vector<SDValue> PICLoads;
+  unsigned iter;
+  MVT MemVT = LD->getMemoryVT();
+  if(ISD::isNON_EXTLoad(N)) {
+    for (iter=0; iter<NumLoads ; ++iter) {
+      // Add the pointer offset if any
+      Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
+      Tys = DAG.getVTList(MVT::i8, MVT::Other); 
+      Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
+                         Offset); 
+      PICLoads.push_back(Load);
+    }
+  } else {
+    // If it is extended load then use PIC16Load for Memory Bytes
+    // and for all extended bytes perform action based on type of
+    // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
+
+    
+    // For extended loads this is the memory value type
+    // i.e. without any extension
+    MVT MemVT = LD->getMemoryVT();
+    unsigned MemBytes = MemVT.getSizeInBits() / 8;
+    unsigned ExtdBytes = VT.getSizeInBits() / 8;
+    Offset = DAG.getConstant(LoadOffset, MVT::i8);
+
+    Tys = DAG.getVTList(MVT::i8, MVT::Other); 
+    // For MemBytes generate PIC16Load with proper offset
+    for (iter=0; iter<MemBytes; ++iter) {
+      // Add the pointer offset if any
+      Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
+      Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
+                         Offset); 
+      PICLoads.push_back(Load);
+    }
+
+    // For SignExtendedLoad
+    if (ISD::isSEXTLoad(N)) {
+      // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the 
+      // highest MemByte
+      SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load, 
+                                DAG.getConstant(7, MVT::i8));
+      for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
+        PICLoads.push_back(SRA);
+      }
+    } else if (ISD::isZEXTLoad(N)) {
+      // ZeroExtendedLoad -- For all ExtdBytes use constant 0
+      SDValue ConstZero = DAG.getConstant(0, MVT::i8);
+      for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
+        PICLoads.push_back(ConstZero);
+      }
+    }
   }
-  else if (N->getOpcode() == ASC) {
-    VTList = DAG.getVTList(MVT::i16, MVT::Flag);
-    retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
-    DCI.CombineTo (N, retVal, OutOps[2]);
+  SDValue BP;
+
+  if (VT == MVT::i8) {
+    // Operand of Load is illegal -- Load itself is legal
+    return PICLoads[0].getNode();
   }
-  else if (N->getOpcode() == AS) {
-    VTList = DAG.getVTList(MVT::i16);
-    retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
-    DCI.CombineTo (N, retVal);
+  else if (VT == MVT::i16) {
+    BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
+    if (MemVT == MVT::i8)
+      Chain = getChain(PICLoads[0]);
+    else
+      Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
+                          getChain(PICLoads[1]));
+  } else if (VT == MVT::i32) {
+    SDValue BPs[2];
+    BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
+    BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
+    BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
+    if (MemVT == MVT::i8)
+      Chain = getChain(PICLoads[0]);
+    else if (MemVT == MVT::i16)
+      Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
+                          getChain(PICLoads[1]));
+    else {
+      SDValue Chains[2];
+      Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                              getChain(PICLoads[0]), getChain(PICLoads[1]));
+      Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                              getChain(PICLoads[2]), getChain(PICLoads[3]));
+      Chain =  DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
+    }
   }
+  Tys = DAG.getVTList(VT, MVT::Other); 
+  SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
+  return MergeV.getNode();
 
-  return retVal;
 }
 
+SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
+  SDValue Value = N->getOperand(0);
+  SDValue Amt = N->getOperand(1);
+  SDValue BCF, BCFInput;
+  SDVTList Tys; 
+  SDValue ShfCom;   // Shift Component - Lo component should be shifted
+  SDValue RotCom;   // Rotate Component- Hi component should be rotated
+  PIC16ISD::NodeType ShfNode, RotNode; 
+  
+  // Currently handling Constant shift only
+  if (Amt.getOpcode() != ISD::Constant)
+    return NULL;
 
-//===----------------------------------------------------------------------===//
-//                      Calling Convention Implementation
-//===----------------------------------------------------------------------===//
+  // Following code considers 16 bit left-shift only
+  if (N->getValueType(0) != MVT::i16)
+    return NULL;
 
-#include "PIC16GenCallingConv.inc"
+  if (N->getOpcode() == ISD::SHL) {
+    ShfNode = PIC16ISD::LSLF;
+    RotNode = PIC16ISD::RLF;
+  } else if (N->getOpcode() == ISD::SRL) {
+    ShfNode = PIC16ISD::LRLF;
+    RotNode = PIC16ISD::RRF;
+  }
+  unsigned ShiftAmt = dyn_cast<ConstantSDNode>(Amt)->getZExtValue();
+  SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8);
+  // 0th Bit in StatusReg is CarryBit 
+  SDValue CarryBit= DAG.getConstant(0, MVT::i8);
+
+  GetExpandedParts(Value, DAG, ShfCom, RotCom);
+  BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag); 
+  Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+
+  for (unsigned i=0;i<ShiftAmt;i++) {
+    BCF = DAG.getNode(PIC16ISD::BCF, MVT::Flag, StatusReg, CarryBit, BCFInput);
+
+    // Following are Two-Address Instructions
+    ShfCom = DAG.getNode(ShfNode, Tys, ShfCom, BCF);
+    RotCom = DAG.getNode(RotNode, Tys, RotCom, ShfCom.getValue(1));
 
-//===----------------------------------------------------------------------===//
-//                  CALL Calling Convention Implementation
-//===----------------------------------------------------------------------===//
+    BCFInput = RotCom.getValue(1); 
+  }
 
+  SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom);
+  return BP.getNode();
+}
 
-//===----------------------------------------------------------------------===//
-//             FORMAL_ARGUMENTS Calling Convention Implementation
-//===----------------------------------------------------------------------===//
-SDValue PIC16TargetLowering::
-LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
-{
-  SmallVector<SDValue, 8> ArgValues;
-  SDValue Root = Op.getOperand(0);
+SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+    case ISD::FORMAL_ARGUMENTS:
+      return LowerFORMAL_ARGUMENTS(Op, DAG);
+    case ISD::ADDC:
+      return LowerADDC(Op, DAG);
+    case ISD::ADDE:
+      return LowerADDE(Op, DAG);
+    case ISD::SUBE:
+      return LowerSUBE(Op, DAG);
+    case ISD::SUBC:
+      return LowerSUBC(Op, DAG);
+    case ISD::LOAD:
+      return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo());
+    case ISD::STORE:
+      return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo());
+    case ISD::SHL:
+      return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo());
+  }
+  return SDValue();
+}
+
+SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
+                                                 SelectionDAG &DAG) {
+
+  assert (Op.getValueType() == MVT::i8 
+          && "illegal value type to store on stack.");
 
-  // Return the new list of results.
-  // FIXME: Just copy right now.
-  ArgValues.push_back(Root);
+  MachineFunction &MF = DAG.getMachineFunction();
+  const Function *Func = MF.getFunction();
+  const std::string FuncName = Func->getName();
+
+  char *tmpName = new char [strlen(FuncName.c_str()) +  6];
+
+  // Put the value on stack.
+  // Get a stack slot index and convert to es.
+  int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
+  sprintf(tmpName, "%s.tmp", FuncName.c_str());
+  SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
+
+  // Store the value to ES.
+  SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
+                               DAG.getEntryNode(),
+                               Op, ES, 
+                               DAG.getConstant (1, MVT::i8), // Banksel.
+                               DAG.getConstant (FI, MVT::i8));
+
+  // Load the value from ES.
+  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
+  SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
+                             ES, DAG.getConstant (1, MVT::i8),
+                             DAG.getConstant (FI, MVT::i8));
+    
+  return Load.getValue(0);
+}
+
+SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
+  // We should have handled larger operands in type legalizer itself.
+  assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
+
+  // Nothing to do if the one of the operands is already a load.
+  if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
+      || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
+    return SDValue();
 
-  return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0],
-                            ArgValues.size()).getValue(Op.getResNo());
+  // Put one value on stack.
+  SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
+    
+  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+  return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal);
 }
 
+SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) {
+  // We should have handled larger operands in type legalizer itself.
+  assert (Op.getValueType() == MVT::i8 && "illegal adde to lower");
+
+  // Nothing to do if the one of the operands is already a load.
+  if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
+      || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
+    return SDValue();
 
-//===----------------------------------------------------------------------===//
-//               Return Value Calling Convention Implementation
-//===----------------------------------------------------------------------===//
+  // Put one value on stack.
+  SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
+    
+  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+  return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal, 
+                     Op.getOperand(2));
+}
 
-//===----------------------------------------------------------------------===//
-//                           PIC16 Inline Assembly Support
-//===----------------------------------------------------------------------===//
+SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) {
+  // We should have handled larger operands in type legalizer itself.
+  assert (Op.getValueType() == MVT::i8 && "illegal subc to lower");
 
-//===----------------------------------------------------------------------===//
-// Target Optimization Hooks
-//===----------------------------------------------------------------------===//
+  // Nothing to do if the first operand is already a load.
+  if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
+    return SDValue();
 
-SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
-                                                 DAGCombinerInfo &DCI) const 
-{
-  int i;
-  ConstantSDNode *CST;
-  SelectionDAG &DAG = DCI.DAG;
+  // Put first operand on stack.
+  SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
 
-  switch (N->getOpcode()) {
-    default: 
-      break;
+  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+  return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1));
+}
 
-    case PIC16ISD::Package:
-      DOUT << "==== combining PIC16ISD::Package\n";
-      return SDValue();
+SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) {
+  // We should have handled larger operands in type legalizer itself.
+  assert (Op.getValueType() == MVT::i8 && "illegal sube to lower");
 
-    case ISD::ADD:
-    case ISD::SUB:
-      if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) ||
-          (N->getOperand(0).getOpcode() == ISD::FrameIndex)) {
-        // Do not touch pointer adds.
-        return SDValue ();
-      }
-      break;
+  // Nothing to do if the first operand is already a load.
+  if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
+    return SDValue();
 
-    case ISD::ADDE :
-    case ISD::ADDC :
-    case ISD::SUBE :
-    case ISD::SUBC :
-      if (N->getValueType(0) == MVT::i16) {
-        SDValue retVal = LowerADDSUB(N, DAG,DCI); 
-        // LowerADDSUB has already combined the result, 
-        // so we just return nothing to avoid assertion failure from llvm 
-        // if N has been deleted already.
-        return SDValue();
-      }
-      else if (N->getValueType(0) == MVT::i8) { 
-        // Sanity check ....
-        for (int i=0; i<2; i++) {
-          if (N->getOperand (i).getOpcode() == PIC16ISD::Package) {
-            assert (0 && 
-                    "don't want to have PIC16ISD::Package as intput to add:i8");
-          }
-        }
-      }
-      break;
+  // Put first operand on stack.
+  SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
 
-    // FIXME: split this large chunk of code.
-    case ISD::STORE :
-    {
-      SDValue Chain = N->getOperand(0);  
-      SDValue Src = N->getOperand(1);
-      SDValue Dest = N->getOperand(2);
-      unsigned int DstOff = 0;
-      int NUM_STORES = 0;
-      SDValue Stores[6];
-
-      // if source operand is expected to be extended to 
-      // some higher type then - remove this extension 
-      // SDNode and do the extension manually
-      if ((Src.getOpcode() == ISD::ANY_EXTEND) ||
-          (Src.getOpcode() == ISD::SIGN_EXTEND) || 
-          (Src.getOpcode() == ISD::ZERO_EXTEND)) {
-        Src = Src.getNode()->getOperand(0);
-        Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0);
-        return Stores[0];
-      }
+  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
+  return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1),
+                     Op.getOperand(2));
+}
 
-      switch(Src.getValueType().getSimpleVT()) {
-        default:
-          assert(false && "Invalid value type!");
-
-        case MVT::i8:  
-          break;
-
-        case MVT::i16: 
-          NUM_STORES = 2;
-          break;
-
-        case MVT::i32: 
-          NUM_STORES = 4;
-          break;
-
-        case MVT::i64: 
-          NUM_STORES = 8; 
-          break;
-      }
+// LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
+// is returned. MERGE_VALUES nodes number of operands and number of values are
+// equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
+// number of arguments of function have been created.
 
-      if (isa<GlobalAddressSDNode>(Dest) && isa<LoadSDNode>(Src) && 
-          (Src.getValueType() != MVT::i8)) {
-        //create direct addressing a = b
-        Chain = Src.getOperand(0);
-        for (i=0; i<NUM_STORES; i++) {
-          SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Src.getOperand(1),
-                                      DAG.getConstant(DstOff, MVT::i16));
-          SDValue LDN = DAG.getLoad(MVT::i8, Chain, ADN, NULL, 0);
-          SDValue DSTADDR = DAG.getNode(ISD::ADD, MVT::i16, Dest,
-                                          DAG.getConstant(DstOff, MVT::i16));
-          Stores[i] = DAG.getStore(Chain, LDN, DSTADDR, NULL, 0);
-          Chain = Stores[i];
-          DstOff += 1;
-        } 
-        
-        Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
-        return Chain;
-      }
-      else if (isa<GlobalAddressSDNode>(Dest) && isa<ConstantSDNode>(Src) 
-               && (Src.getValueType() != MVT::i8)) {
-        //create direct addressing a = CONST
-        CST = dyn_cast<ConstantSDNode>(Src);
-        for (i = 0; i < NUM_STORES; i++) {
-          SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
-          SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest,
-                                      DAG.getConstant(DstOff, MVT::i16));
-          Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0);
-          Chain = Stores[i];
-          DstOff += 1;
-        } 
-          
-        Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
-        return Chain;
-      }
-      else if (isa<LoadSDNode>(Dest) && isa<ConstantSDNode>(Src) 
-              && (Src.getValueType() != MVT::i8)) {
-        // Create indirect addressing.
-        CST = dyn_cast<ConstantSDNode>(Src);
-        Chain = Dest.getOperand(0);  
-        SDValue Load;
-        Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0);
-        Chain = Load.getValue(1);
-        for (i=0; i<NUM_STORES; i++) {
-          SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
-          Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0);
-          Chain = Stores[i];
-          DstOff += 1;
-        } 
-          
-        Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
-        return Chain;
-      }
-      else if (isa<LoadSDNode>(Dest) && isa<GlobalAddressSDNode>(Src)) {
-        // GlobalAddressSDNode *GAD = dyn_cast<GlobalAddressSDNode>(Src);
-        return SDValue();
-      }
-      else if (Src.getOpcode() == PIC16ISD::Package) {
-        StoreSDNode *st = dyn_cast<StoreSDNode>(N);
-        SDValue toWorkList, retVal;
-        Chain = N->getOperand(0);
-
-        if (st->isTruncatingStore()) {
-          retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
-        }
-        else {
-          toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest,
-                                   DAG.getConstant(1, MVT::i16));
-          Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
-          Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL, 
-                                   0);
-
-          // We want to merge sequence of add with constant to one add and a 
-          // constant, so add the ADD node to worklist to have llvm do that 
-          // automatically.
-          DCI.AddToWorklist(toWorkList.getNode()); 
-
-          // We don't need the Package so add to worklist so llvm deletes it
-          DCI.AddToWorklist(Src.getNode());
-          retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2);
-        }
+SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op, 
+                                                    SelectionDAG &DAG) {
+  SmallVector<SDValue, 8> ArgValues;
+  unsigned NumArgs = Op.getNumOperands() - 3;
 
-        return retVal;
-      }
-      else if (Src.getOpcode() == ISD::TRUNCATE) {
-      }
-      else {
-      }
-    } // end ISD::STORE.
-    break;
+  // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
+  for(unsigned i = 0 ; i<NumArgs ; i++) {
+    SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
+    ArgValues.push_back(TempNode);
+  }
 
-    case ISD::LOAD :
-    {
-      SDValue Ptr = N->getOperand(1);
-      if (Ptr.getOpcode() == PIC16ISD::Package) {
-        assert (0 && "not implemented yet");
-       }
-    }
-    break;
-  } // end switch.
+  ArgValues.push_back(Op.getOperand(0));
+  return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), 
+                     &ArgValues[0],
+                     ArgValues.size()).getValue(Op.getResNo());
+}
 
+// Perform DAGCombine of PIC16Load 
+SDValue PIC16TargetLowering::
+PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
+  SelectionDAG &DAG = DCI.DAG;
+  SDValue Chain = N->getOperand(0); 
+  if (N->hasNUsesOfValue(0, 0)) {
+    DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
+  }
   return SDValue();
 }
 
-//===----------------------------------------------------------------------===//
-//               Utility functions
-//===----------------------------------------------------------------------===//
-const SDValue *PIC16TargetLowering::
-findLoadi8(const SDValue &Src, SelectionDAG &DAG) const
-{
-  unsigned int i;
-  if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8))
-    return &Src;
-  for (i=0; i<Src.getNumOperands(); i++) {
-    const SDValue *retVal = findLoadi8(Src.getOperand(i),DAG);
-    if (retVal) return retVal;
-  }
 
-  return NULL;
+SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
+                                               DAGCombinerInfo &DCI) const {
+  switch (N->getOpcode()) {
+  case PIC16ISD::PIC16Load:
+    return PerformPIC16LoadCombine(N, DCI);
+  }
+  return SDValue();
 }

Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Wed Nov 19 05:00:54 2008
@@ -26,66 +26,89 @@
       // Start the numbering from where ISD NodeType finishes.
       FIRST_NUMBER = ISD::BUILTIN_OP_END,
 
-      // used for encapsulating the expanded nodes into one node.
-      Package,
-
-      // Get the Higher 16 bits from a 32-bit immediate
-      Hi, 
-
-      // Get the Lower 16 bits from a 32-bit immediate
-      Lo,
+      Lo,            // Low 8-bits of GlobalAddress.
+      Hi,            // High 8-bits of GlobalAddress.
+      PIC16Load,
+      PIC16Store,
+      Banksel,
+      MTLO,
+      MTHI,
+      BCF,
+      LSLF,          // PIC16 Logical shift left
+      LRLF,          // PIC16 Logical shift right
+      RLF,           // Rotate left through carry
+      RRF,           // Rotate right through carry
+      Dummy
+    };
 
-      Cmp,        // PIC16 Generic Comparison instruction.
-      Branch,        // PIC16 Generic Branch Instruction.        
-      BTFSS,        // PIC16 BitTest Instruction (Skip if set).
-      BTFSC,        // PIC16 BitTest Instruction (Skip if clear).
-
-      // PIC16 comparison to be converted to either XOR or SUB
-      // Following instructions cater to those convertions.
-      XORCC,        
-      SUBCC,        
-
-      // Get the Global Address wrapped into a wrapper that also captures 
-      // the bank or page.
-      Wrapper,
-      SetBank,
-      SetPage
+    // Keep track of different address spaces. 
+    enum AddressSpace {
+      RAM_SPACE = 0,   // RAM address space
+      ROM_SPACE = 1    // ROM address space number is 1
     };
   }
 
   //===--------------------------------------------------------------------===//
   // TargetLowering Implementation
   //===--------------------------------------------------------------------===//
-  class PIC16TargetLowering : public TargetLowering 
-  {
+  class PIC16TargetLowering : public TargetLowering {
   public:
-    typedef std::map<SDNode *, SDNode *> NodeMap_t;
-
     explicit PIC16TargetLowering(PIC16TargetMachine &TM);
 
-    /// LowerOperation - Provide custom lowering hooks for some operations.
-    virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
-
-    SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG);
-
-    SDValue RemoveHiLo(SDNode *, SelectionDAG &DAG, 
-                         DAGCombinerInfo &DCI) const;
-    SDValue LowerADDSUB(SDNode *, SelectionDAG &DAG, 
-                          DAGCombinerInfo &DCI) const;
-    SDValue LowerLOAD(SDNode *, SelectionDAG &DAG, 
-                        DAGCombinerInfo &DCI) const;
-
-    /// getTargetNodeName - This method returns the name of a target specific 
-    //  DAG node.
+    /// getTargetNodeName - This method returns the name of a target specific
+    /// DAG node.
     virtual const char *getTargetNodeName(unsigned Opcode) const;
-    virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
-
-    // utility function.
-    const SDValue *findLoadi8(const SDValue &Src, SelectionDAG &DAG) const;
+    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerADDE(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerADDC(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerSUBE(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG);
+
+    SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandLoad(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG);
+    SDNode *ExpandShift(SDNode *N, SelectionDAG &DAG);
+
+    SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
+    SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; 
+
+  private:
+    // If the Node is a BUILD_PAIR representing representing an Address
+    // then this function will return true
+    bool isDirectAddress(const SDValue &Op);
+
+    // If the Node is a DirectAddress in ROM_SPACE then this 
+    // function will return true
+    bool isRomAddress(const SDValue &Op);
+
+    // To extract chain value from the SDValue Nodes
+    // This function will help to maintain the chain extracting
+    // code at one place. In case of any change in future it will
+    // help maintain the code
+    SDValue getChain(SDValue &Op);
+
+
+    // Extract the Lo and Hi component of Op. 
+    void GetExpandedParts(SDValue Op, SelectionDAG &DAG, SDValue &Lo, 
+                          SDValue &Hi); 
+
+
+    // Load pointer can be a direct or indirect address. In PIC16 direct
+    // addresses need Banksel and Indirect addresses need to be loaded to
+    // FSR first. Handle address specific cases here.
+    void LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, SDValue &Chain, 
+                         SDValue &NewPtr, unsigned &Offset);
+
+    // We can not have both operands of a binary operation in W.
+    // This function is used to put one operand on stack and generate a load.
+    SDValue ConvertToMemOperand(SDValue Op, SelectionDAG &DAG); 
+
+    /// Subtarget - Keep a pointer to the PIC16Subtarget around so that we can
+    /// make the right decision when generating code for different targets.
+    const PIC16Subtarget *Subtarget;
   };
 } // namespace llvm
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16InstrFormats.td Wed Nov 19 05:00:54 2008
@@ -1,4 +1,4 @@
-//===- PIC16RegisterInfo.td - PIC16 Register defs ------------*- tblgen -*-===//
+//===- PIC16InstrFormats.td - PIC16 Instruction Formats-------*- tblgen -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -21,16 +21,17 @@
 //===----------------------------------------------------------------------===//
 
 // Generic PIC16 Format
+// PIC16 Instructions are 14-bit wide.
+
+// FIXME: Add Cooper Specific Formats if any.
+
 class PIC16Inst<dag outs, dag ins, string asmstr, list<dag> pattern>
-        : Instruction 
-{
+  : Instruction {
   field bits<14> Inst;
 
   let Namespace = "PIC16";
-
   dag OutOperandList = outs;
   dag InOperandList = ins;
-
   let AsmString = asmstr;
   let Pattern = pattern;
 }
@@ -38,16 +39,18 @@
 
 //===----------------------------------------------------------------------===//
 // Byte Oriented instruction class in PIC16 : <|opcode|d|f|>
+// opcode = 6 bits.
+// d = direction = 1 bit.
+// f = file register address = 7 bits.
 //===----------------------------------------------------------------------===//
 
-class ByteFormat<bits<6> op, dag outs, dag ins, string asmstr,
-                  list<dag> pattern>
-        :PIC16Inst<outs, ins, asmstr, pattern> 
-{
+class ByteFormat<bits<6> opcode, dag outs, dag ins, string asmstr,
+                 list<dag> pattern>
+  :PIC16Inst<outs, ins, asmstr, pattern> {
   bits<1>  d;
   bits<7>  f;
 
-  let Inst{13-8} = op;
+  let Inst{13-8} = opcode;
 
   let Inst{7} = d;
   let Inst{6-0} = f; 
@@ -55,15 +58,18 @@
 
 //===----------------------------------------------------------------------===//
 // Bit Oriented instruction class in PIC16 : <|opcode|b|f|>
+// opcode = 4 bits.
+// b = bit specifier = 3 bits.
+// f = file register address = 7 bits.
 //===----------------------------------------------------------------------===//
 
-class BitFormat<bits<4> op, dag outs, dag ins, string asmstr, list<dag> pattern>
-         : PIC16Inst<outs, ins, asmstr, pattern> 
-{
+class BitFormat<bits<4> opcode, dag outs, dag ins, string asmstr, 
+                list<dag> pattern>
+  : PIC16Inst<outs, ins, asmstr, pattern> {
   bits<3>  b;
   bits<7>  f;
 
-  let Inst{13-10} = op;
+  let Inst{13-10} = opcode;
 
   let Inst{9-7} = b;
   let Inst{6-0} = f; 
@@ -71,32 +77,32 @@
 
 //===----------------------------------------------------------------------===//
 // Literal Format instruction class in PIC16 : <|opcode|k|>
+// opcode = 6 bits
+// k = literal = 8 bits
 //===----------------------------------------------------------------------===//
 
-class LiteralFormat<bits<6> op, dag outs, dag ins, string asmstr, 
+class LiteralFormat<bits<6> opcode, dag outs, dag ins, string asmstr, 
                     list<dag> pattern>
-        : PIC16Inst<outs, ins, asmstr, pattern> 
-{
+  : PIC16Inst<outs, ins, asmstr, pattern> {
   bits<8> k;
-
   
-  let Inst{13-8} = op;
+  let Inst{13-8} = opcode;
 
   let Inst{7-0} = k; 
 }
 
 //===----------------------------------------------------------------------===//
 // Control Format instruction class in PIC16 : <|opcode|k|>
+// opcode = 3 bits.
+// k = jump address = 11 bits.
 //===----------------------------------------------------------------------===//
 
-class ControlFormat<bits<3> op, dag outs, dag ins, string asmstr, 
+class ControlFormat<bits<3> opcode, dag outs, dag ins, string asmstr, 
                     list<dag> pattern>
-        :PIC16Inst<outs, ins, asmstr, pattern> 
-{
+  : PIC16Inst<outs, ins, asmstr, pattern> {
   bits<11> k;
 
-  
-  let Inst{13-11} = op;
+  let Inst{13-11} = opcode;
 
   let Inst{10-0} = k; 
 }
@@ -105,8 +111,7 @@
 // Pseudo instruction class in PIC16
 //===----------------------------------------------------------------------===//
 
-class Pseudo<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
-      PIC16Inst<outs, ins, asmstr, pattern>
-{
-   let Inst{13-6} = op;
+class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
+  : PIC16Inst<outs, ins, asmstr, pattern> {
+   let Inst{13-6} = 0;
 }

Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.cpp Wed Nov 19 05:00:54 2008
@@ -13,132 +13,131 @@
 
 #include "PIC16.h"
 #include "PIC16InstrInfo.h"
+#include "PIC16TargetMachine.h"
+#include "PIC16GenInstrInfo.inc"
 #include "llvm/Function.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "PIC16GenInstrInfo.inc"
-#include <cstdio>
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+
 
 using namespace llvm;
 
 // FIXME: Add the subtarget support on this constructor.
 PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm)
   : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)),
-    TM(tm), RI(*this) {}
+    TM(tm), 
+    RegInfo(*this, *TM.getSubtargetImpl()) {}
 
-static bool isZeroImm(const MachineOperand &op) {
-  return op.isImm() && 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(const MachineInstr *MI, int &FrameIndex) const 
-{
-  if (MI->getOpcode() == PIC16::MOVF) {
-    if ((MI->getOperand(2).isFI()) && // is a stack slot
-        (MI->getOperand(1).isImm()) &&  // the imm is zero
-        (isZeroImm(MI->getOperand(1)))) {
-      FrameIndex = MI->getOperand(2).getIndex();
-      return MI->getOperand(0).getReg();
-    }
+/// 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 
+      && MI->getOperand(0).isReg()
+      && MI->getOperand(1).isSymbol()) {
+    FrameIndex = MI->getOperand(1).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
+/// isLoadFromStackSlot - If the specified machine instruction is a direct
+/// load from a stack slot, return the virtual or physical register number of
+/// the dest reg along with the FrameIndex of the 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(const MachineInstr *MI, int &FrameIndex) const 
-{
-  if (MI->getOpcode() == PIC16::MOVWF) {
-    if ((MI->getOperand(0).isFI()) && // is a stack slot
-        (MI->getOperand(1).isImm()) &&  // the imm is zero
-        (isZeroImm(MI->getOperand(1)))) {
-      FrameIndex = MI->getOperand(0).getIndex();
-      return MI->getOperand(2).getReg();
-    }
+unsigned PIC16InstrInfo::isLoadFromStackSlot(MachineInstr *MI,
+                                            int &FrameIndex) const {
+  if (MI->getOpcode() == PIC16::movf 
+      && MI->getOperand(0).isReg()
+      && MI->getOperand(1).isSymbol()) {
+    FrameIndex = MI->getOperand(1).getIndex();
+    return MI->getOperand(0).getReg();
   }
   return 0;
 }
 
-void PIC16InstrInfo::
-storeRegToStackSlot(MachineBasicBlock &MBB,
-                    MachineBasicBlock::iterator I,
-                    unsigned SrcReg, bool isKill, int FI,
-                    const TargetRegisterClass *RC) const {
+
+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);
+  sprintf(tmpName, "%s.tmp", FuncName.c_str());
 
-  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.
+  // On the order of operands here: think "movwf SrcReg, tmp_slot, offset".
+  if (RC == PIC16::GPRRegisterClass) {
+    //MachineFunction &MF = *MBB.getParent();
+    //MachineRegisterInfo &RI = MF.getRegInfo();
+    BuildMI(MBB, I, get(PIC16::movwf))
+      .addReg(SrcReg, false, false, isKill)
+      .addImm(FI)
+      .addExternalSymbol(tmpName)
+      .addImm(1); // Emit banksel for it.
   }
+  else if (RC == PIC16::FSR16RegisterClass)
+    assert(0 && "Don't know yet how to store a FSR16 to stack slot");
   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 
-{
+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);
+  sprintf(tmpName, "%s.tmp", FuncName.c_str());
 
-  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.
+  // On the order of operands here: think "movf FrameIndex, W".
+  if (RC == PIC16::GPRRegisterClass) {
+    //MachineFunction &MF = *MBB.getParent();
+    //MachineRegisterInfo &RI = MF.getRegInfo();
+    BuildMI(MBB, I, get(PIC16::movf), DestReg)
+      .addImm(FI)
+      .addExternalSymbol(tmpName)
+      .addImm(1); // Emit banksel for it.
+  }
+  else if (RC == PIC16::FSR16RegisterClass)
+    assert(0 && "Don't know yet how to load an FSR16 from stack slot");
   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 SmallVectorImpl<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;
-  }
-
-  // FIXME: 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;
+bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator I,
+                                   unsigned DestReg, unsigned SrcReg,
+                                   const TargetRegisterClass *DestRC,
+                                   const TargetRegisterClass *SrcRC) const {
+  if (DestRC == PIC16::FSR16RegisterClass) {
+    BuildMI(MBB, I, get(PIC16::copy_fsr), DestReg).addReg(SrcReg);
+  }
+
+  return true;
+}
+
+bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI,
+                                         unsigned &SrcReg,
+                                         unsigned &DestReg) const {
+
+  if (MI.getOpcode() == PIC16::copy_fsr) {
+    DestReg = MI.getOperand(0).getReg();
+    SrcReg = MI.getOperand(1).getReg();
+    return true;
+  }
+  return false;
 }
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.h Wed Nov 19 05:00:54 2008
@@ -24,54 +24,43 @@
 class PIC16InstrInfo : public TargetInstrInfoImpl 
 {
   PIC16TargetMachine &TM;
-  const PIC16RegisterInfo RI;
+  const PIC16RegisterInfo RegInfo;
 public:
   explicit PIC16InstrInfo(PIC16TargetMachine &TM);
 
-  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
-  /// such, whenever a client has an instance of instruction info, it should
-  /// always be able to get register info as well (through this method).
-  ///
-  virtual const PIC16RegisterInfo &getRegisterInfo() const { return RI; }
+  virtual const PIC16RegisterInfo &getRegisterInfo() const { return RegInfo; }
 
-  
   /// 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.
-  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
-                                       int &FrameIndex) const;
-  
+  virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
+                                                                               
   /// 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.
-  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
-                                      int &FrameIndex) const;
- 
-  /// Used for spilling a register
-  void storeRegToStackSlot(MachineBasicBlock &MBB,
-                           MachineBasicBlock::iterator MI,
-                           unsigned SrcReg, bool isKill, int FrameIndex,
-                           const TargetRegisterClass *RC) const;
-
-
-  void loadRegFromStackSlot(MachineBasicBlock &MBB,
-                            MachineBasicBlock::iterator MI,
-                            unsigned DestReg, int FrameIndex,
-                            const TargetRegisterClass *RC) const;
-
-  /// 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.
-  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
-                                MachineBasicBlock *FBB,
-                            const SmallVectorImpl<MachineOperand> &Cond) const ; 
+  virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
+
+  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator MBBI,
+                                   unsigned SrcReg, bool isKill, int FrameIndex,
+                                   const TargetRegisterClass *RC) const;
+                                                                               
+  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
+                                    MachineBasicBlock::iterator MBBI,
+                                    unsigned DestReg, int FrameIndex,
+                                    const TargetRegisterClass *RC) const;
+  virtual bool copyRegToReg(MachineBasicBlock &MBB,
+                            MachineBasicBlock::iterator MBBI,
+                            unsigned DestReg, unsigned SrcReg,
+                            const TargetRegisterClass *DestRC,
+                            const TargetRegisterClass *SrcRC) const;
+  virtual bool isMoveInstr(const MachineInstr &MI,
+                           unsigned &SrcReg,
+                           unsigned &DestReg) const;
 
 };
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Wed Nov 19 05:00:54 2008
@@ -1,4 +1,4 @@
-//===- PIC16InstrInfo.td - PIC16 Register defs ----------------*- tblgen-*-===//
+//===- PIC16InstrInfo.td - PIC16 Instruction defs -------------*- tblgen-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -6,297 +6,302 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Instruction format superclass
+//
+// This file describes the ARM instructions in TableGen format.
+//
 //===----------------------------------------------------------------------===//
 
-include "PIC16InstrFormats.td"
-
 //===----------------------------------------------------------------------===//
-// PIC16 profiles and nodes
+// PIC16 Specific Type Constraints.
 //===----------------------------------------------------------------------===//
+class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
+class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
 
 //===----------------------------------------------------------------------===//
-// PIC16 addressing mode. 
+// PIC16 Specific Type Profiles.
 //===----------------------------------------------------------------------===//
-// It matches address of globals as well as the stack slots
-// that are created for locals and temporaries. This addressing mode
-// converts the GlobalAddress and FrameIndex nodes to TargetGlobalAddress
-// and TargetFrameIndex nodes.
-def diraddrmode : ComplexPattern<i16, 2, "SelectDirectAM", [frameindex], []>;
-def dirloadmode : ComplexPattern<i16, 2, "LoadNothing", [frameindex], []>;
-def indirloadmode : ComplexPattern<i16, 2, "LoadFSR", [frameindex], []>;
-
-
-// Address operand.
-def mem : Operand<i16> {
-  let PrintMethod = "printAddrModeOperand";
-  let MIOperandInfo = (ops i16imm, PTRRegs);
-}
-
-// Instruction operand types
-def simm8      : Operand<i8>;
-
-
-// These are target-independent nodes, but have target-specific formats.
-def SDT_PIC16CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i8> ]>;
-def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PIC16CallSeq,
-                           [SDNPHasChain, SDNPOutFlag]>;
-def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_PIC16CallSeq,
-                           [SDNPHasChain, SDNPOutFlag]>;
-
-def PIC16Wrapper  : SDNode<"PIC16ISD::Wrapper", SDTIntUnaryOp>;
-
-// so_imm_XFORM - Return a so_imm value packed into the format described for
-// so_imm def below.
-def so_imm_XFORM : SDNodeXForm<imm, [{
-  return CurDAG->getTargetConstant((int8_t)N->getZExtValue(), MVT::i32);
-}]>;
-
-def so_imm : Operand<i8>,
-             PatLeaf<(imm), [{}]> {
-  let PrintMethod = "printSOImmOperand";
-}
-
-
-
-// PIC16 Address Mode! SDNode frameindex could possibily be a match 
-// since load and store instructions from stack used it.
-def addr : Operand<i16>;
-
-// Arithmetic 2 register operands
-class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
-             Operand Od> :
-  LiteralFormat< op,
-      (outs CPURegs:$dst),
-      (ins CPURegs:$b, Od:$c),
-      !strconcat(instr_asm, " $c"),
-      [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c))]>;
-
-// Memory Load/Store. 
-class LoadDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
-  ByteFormat< op,
-      (outs CPURegs:$dst),
-      (ins mem:$addr),
-      !strconcat(instr_asm, " $addr"),
-      [(set CPURegs:$dst, (OpNode diraddrmode:$addr))]>;
-
-class LoadInDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
-  ByteFormat< op,
-      (outs PTRRegs:$dst),
-      (ins mem:$addr),
-      !strconcat(instr_asm, " $addr, $dst"),
-      [(set PTRRegs:$dst, (OpNode indirloadmode:$addr))]>;
-
-class StoreDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
-  ByteFormat< op,
-      (outs),
-      (ins CPURegs:$src, mem:$addr),
-      !strconcat(instr_asm, " $addr"),
-      [(OpNode CPURegs:$src, diraddrmode:$addr)]>;
-
-class StoreInDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
-  ByteFormat< op,
-      (outs),
-      (ins CPURegs:$src, PTRRegs:$fsr),
-      !strconcat(instr_asm, " $fsr"),
-      [(OpNode CPURegs:$src, PTRRegs:$fsr)]>;
-
-// Move.
-class MovLit<bits<6> op, string instr_asm>:
-  LiteralFormat< op,
-      (outs CPURegs:$dst),
-      (ins i8imm:$src),
-      !strconcat(instr_asm, " $src"),
-      [(set CPURegs:$dst, imm:$src)]>;
-
-
-// Arithmetic with memory store.
-// Arithmetic instrunctions involving W and memory location.
-// Since W is implicit, we only print the memory operand.
-class Arith1M<bits<6> op, string instr_asm, SDNode OpNode>:
-  ByteFormat< op,
-      (outs),
-      (ins CPURegs:$b, mem:$dst),
-      !strconcat(instr_asm, " $dst"),
-      [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst),
-       (store (OpNode CPURegs:$b, (load diraddrmode:$dst)), diraddrmode:$dst)]>;
-
-// Arithmetic with memory load.
-// Arithmetic instrunctions involving W and memory location.
-// Since W is implicit, we only print the memory operand.
-class Arith1R<bits<6> op, string instr_asm, SDNode OpNode>:
-  ByteFormat< op,
-      (outs CPURegs:$dst),
-      (ins mem:$src1, CPURegs:$src2),
-      !strconcat(instr_asm, " $src1"),
-      [(set CPURegs:$dst, (OpNode (load diraddrmode:$src1), CPURegs:$src2))]>;
-
-// Arithmetic with memory load.
-// Arithmetic instrunctions involving W and memory location.
-// Since W is implicit, we only print the memory operand.
-class Arith2R<bits<6> op, string instr_asm, SDNode OpNode>:
-  ByteFormat< op,
-      (outs CPURegs:$dst),
-      (ins mem:$src1, CPURegs:$src2),
-      !strconcat(instr_asm, " $src1"),
-      [(set CPURegs:$dst, (OpNode CPURegs:$src2, (load diraddrmode:$src1)))]>;
-
-//===----------------------------------------------------------------------===//
-// Instruction definition
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// PIC16I Instructions
-//===----------------------------------------------------------------------===//
-
-// Arithmetic
-
-// ADDiu just accept 16-bit immediates but we handle this on Pat's.
-// immZExt32 is used here so it can match GlobalAddress immediates.
-// def ADDLW   : ArithI<0x09, "addlw", add, so_imm>;
-
-let isReMaterializable = 1 in {
-def MOVLW : MovLit<0x24, "movlw">;
-}
-
-// Load/Store
-def LFSR1      : LoadInDirect        <0x4, "lfsr",  load>;
-
-let isReMaterializable = 1 in {
-def MOVF       : LoadDirect <0x23, "movf",  load>;
-}
-
-def MOVWF      : StoreDirect <0x2b, "movwf", store>;
-
-def MOVFSRINC  : StoreInDirect <0x5, "movfsrinc", store>;
-
-def RETURN     : ControlFormat<0x03, (outs), (ins), "return", []>;
-
-def ADDWF      : Arith1M<0x01, "addwf", add>; 
-def ADDFW      : Arith1R<0x02, "addfw", add>; 
-
-def ADDWFE     : Arith1M<0x03, "addwfe", adde>; 
-def ADDFWE     : Arith1R<0x04, "addfwe", adde>; 
 
-def ADDWFC     : Arith1M<0x05, "addwfc", addc>; 
-def ADDFWC     : Arith1R<0x06, "addfwc", addc>; 
+// Generic type profiles for i8/i16 unary/binary operations.
+// Taking one i8 or i16 and producing void.
+def SDTI8VoidOp : SDTypeProfile<0, 1, [SDTCisI8<0>]>;
+def SDTI16VoidOp : SDTypeProfile<0, 1, [SDTCisI16<0>]>;
 
-def SUBWF      : Arith1M<0x07, "subwf", sub>; 
-def SUBFW      : Arith1R<0x08, "subfw", sub>; 
+// Taking one value and producing an output of same type.
+def SDTI8UnaryOp : SDTypeProfile<1, 1, [SDTCisI8<0>, SDTCisI8<1>]>;
+def SDTI16UnaryOp : SDTypeProfile<1, 1, [SDTCisI16<0>, SDTCisI16<1>]>;
 
-def SUBWFE     : Arith1M<0x09, "subwfe", sube>; 
-def SUBFWE     : Arith1R<0x0a, "subfwe", sube>; 
+// Taking two values and producing an output of same type.
+def SDTI8BinOp : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>]>;
+def SDTI16BinOp : SDTypeProfile<1, 2, [SDTCisI16<0>, SDTCisI16<1>, 
+                                       SDTCisI16<2>]>;
 
-def SUBWFC     : Arith1M<0x0b, "subwfc", subc>; 
-def SUBFWC     : Arith1R<0x0d, "subfwc", subc>; 
+// Node specific type profiles.
+def SDT_PIC16Load : SDTypeProfile<1, 3, [SDTCisI8<0>, SDTCisI8<1>, 
+                                          SDTCisI8<2>, SDTCisI8<3>]>;
+def SDT_PIC16Store : SDTypeProfile<0, 4, [SDTCisI8<0>, SDTCisI8<1>, 
+                                          SDTCisI8<2>, SDTCisI8<3>]>;
 
-def SUBRFW     : Arith2R<0x08, "subfw", sub>; 
-
-def SUBRFWE    : Arith2R<0x0a, "subfwe", sube>; 
-
-def SUBRFWC    : Arith2R<0x0d, "subfwc", subc>; 
-
-def brtarget   : Operand<OtherVT>;
-
-class UncondJump< bits<4> op, string instr_asm>:
-  BitFormat< op,
-             (outs),
-             (ins brtarget:$target),
-             !strconcat(instr_asm, " $target"),
-             [(br bb:$target)]>;
-
-def GOTO       : UncondJump<0x1, "goto">;
-
-class LogicM<bits<6> op, string instr_asm, SDNode OpNode> :
-  ByteFormat< op,
-      (outs),
-      (ins CPURegs:$b, mem:$dst),
-      !strconcat(instr_asm, " $dst"),
-      [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst)]>;
-
-class LogicR<bits<6> op, string instr_asm, SDNode OpNode> :
-  ByteFormat< op,
-      (outs CPURegs:$dst),
-      (ins CPURegs:$b, mem:$c),
-      !strconcat(instr_asm, " $c"),
-      [(set CPURegs:$dst, (OpNode (load diraddrmode:$c), CPURegs:$b))]>;
-
-class LogicI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od> :
-  LiteralFormat< op,
-      (outs CPURegs:$dst),
-      (ins CPURegs:$b, Od:$c),
-      !strconcat(instr_asm, " $c"),
-      [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c ))]>;
-
-def XORWF : LogicM<0x1,"xorwf",xor>; 
-def XORFW : LogicR<0x1,"xorfw",xor>; 
-def XORLW : LogicI<0x1,"xorlw",xor, so_imm>;
-
-def ANDWF : LogicM<0x1,"andwf",and>; 
-def ANDFW : LogicR<0x1,"andfw",and>; 
-def ANDLW : LogicI<0x1,"andlw",and, so_imm>;
-
-def IORWF : LogicM<0x1,"iorwf",or>; 
-def IORFW : LogicR<0x1,"iorfw",or>; 
-def IORLW : LogicI<0x1,"iorlw",or, so_imm>;
-
-
-/* For comparison before branch */
-def SDT_PIC16Cmp  : SDTypeProfile<1, 3, [SDTCisSameAs<0,1>]>;
-def SDTIntBinOpPIC16 : SDTypeProfile<1, 2, [SDTCisSameAs<0,1>, 
-                                     SDTCisSameAs<1,2>, SDTCisInt<1>]>;
+//===----------------------------------------------------------------------===//
+// PIC16 addressing modes matching via DAG.
+//===----------------------------------------------------------------------===//
+def diraddr : ComplexPattern<i8, 1, "SelectDirectAddr", [], []>;
 
-def PIC16Cmp : SDNode<"PIC16ISD::Cmp",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
-def PIC16XORCC : SDNode<"PIC16ISD::XORCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
-def PIC16SUBCC : SDNode<"PIC16ISD::SUBCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
+//===----------------------------------------------------------------------===//
+// PIC16 Specific Node Definitions.
+//===----------------------------------------------------------------------===//
+def PIC16callseq_start : SDNode<"ISD::CALLSEQ_START", SDTI8VoidOp,
+                                [SDNPHasChain, SDNPOutFlag]>;
+def PIC16callseq_end   : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp, 
+                                [SDNPHasChain, SDNPOutFlag]>;
 
-def XORFWCC : LogicR<0x1,"xorfw",PIC16XORCC>; 
-def XORLWCC : LogicI<0x1,"xorlw",PIC16XORCC, so_imm>; 
-def SUBFWCC : Arith1R<0x1,"subfw",PIC16SUBCC>; 
-def SUBLWCC : ArithI<0x1,"sublw",PIC16SUBCC, so_imm>; 
+// Low 8-bits of GlobalAddress.
+def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>;  
 
+// High 8-bits of GlobalAddress.
+def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>;
 
-/* For branch conditions */
-def SDT_PIC16Branch  : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, 
-                                     SDTCisVT<1,i8>, SDTCisVT<2,i8>]>;
+// The MTHI and MTLO nodes are used only to match them in the incoming 
+// DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions.
+// These nodes are not used for defining any instructions.
+def MTLO : SDNode<"PIC16ISD::MTLO", SDTI8UnaryOp>;
+def MTHI : SDNode<"PIC16ISD::MTHI", SDTI8UnaryOp>;
 
-def PIC16Branch : SDNode<"PIC16ISD::Branch",SDT_PIC16Branch, 
-                         [SDNPHasChain, SDNPInFlag]>; 
+// Node to generate Bank Select for a GlobalAddress.
+def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>;
 
-def PIC16BTFSS  : SDNode<"PIC16ISD::BTFSS",SDT_PIC16Branch, 
-                         [SDNPHasChain, SDNPInFlag]>; 
+// Node to match a direct store operation.
+def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>;
 
-def PIC16BTFSC  : SDNode<"PIC16ISD::BTFSC",SDT_PIC16Branch, 
-                         [SDNPHasChain, SDNPInFlag]>; 
+// Node to match a direct load operation.
+def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
 
-class InstrBitTestCC<bits<4> op, string instr_asm,SDNode OpNode>:
-  BitFormat< op,
-             (outs),
-             (ins brtarget:$target ,so_imm:$i, STATUSRegs:$s ),
-                   !strconcat(instr_asm, " $s, $i, $target"),
-                   [(OpNode bb:$target, so_imm:$i, STATUSRegs:$s )]>;
+//===----------------------------------------------------------------------===//
+// PIC16 Operand Definitions.
+//===----------------------------------------------------------------------===//
+def i8mem : Operand<i8>;
 
-def BTFSS : InstrBitTestCC<0x1,"btfss",PIC16BTFSS>;
-def BTFSC : InstrBitTestCC<0x1,"btfsc",PIC16BTFSC>;
 
 
 //===----------------------------------------------------------------------===//
-// Pseudo instructions
+// PIC16 Instructions.
 //===----------------------------------------------------------------------===//
+include "PIC16InstrFormats.td"
 
-let Defs = [STKPTR], Uses = [STKPTR] in {
-def ADJCALLSTACKDOWN : Pseudo<255, (outs), (ins i8imm:$amt),
-                               "!ADJCALLSTACKDOWN $amt",
-                               [(callseq_start imm:$amt)]>;
-def ADJCALLSTACKUP : Pseudo<254, (outs), (ins i8imm:$amt),
-                            "!ADJCALLSTACKUP $amt",
-                            [(callseq_end imm:$amt)]>;
+// Pseudo-instructions.
+def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
+                       "!ADJCALLSTACKDOWN $amt",
+                       [(PIC16callseq_start imm:$amt)]>;
+
+def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
+                       "!ADJCALLSTACKUP $amt", 
+                       [(PIC16callseq_end imm:$amt)]>;
+
+//-----------------------------------
+// Vaious movlw insn patterns.
+//-----------------------------------
+let isReMaterializable = 1 in {
+// Move 8-bit literal to W.
+def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
+                      "movlw $src",
+                      [(set GPR:$dst, (i8 imm:$src))]>;
+
+// Move a Lo(TGA) to W.
+def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
+                      "movlw LOW(${src})",
+                      [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
+
+// Move a Hi(TGA) to W.
+def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
+                      "movlw HIGH(${src})",
+                      [(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>;
 }
 
+//-------------------
+// FSR setting insns. 
+//-------------------
+// These insns are matched via a DAG replacement pattern.
+def set_fsrlo:
+  ByteFormat<0, (outs FSR16:$fsr), 
+             (ins GPR:$val),
+             "movwf ${fsr}L",
+             []>;
+
+let isTwoAddress = 1 in
+def set_fsrhi:
+  ByteFormat<0, (outs FSR16:$dst), 
+             (ins FSR16:$src, GPR:$val),
+             "movwf ${dst}H",
+             []>;
+
+def copy_fsr:
+  Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
+
+//--------------------------
+// Store to memory
+//-------------------------
+// Direct store.
+def movwf : 
+  ByteFormat<0, (outs), 
+             (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+             "movwf ${ptrlo} + ${offset}",
+             [(PIC16Store GPR:$val, tglobaladdr:$ptrlo, (i8 imm:$ptrhi), 
+               (i8 imm:$offset))]>;
+
+def movwf_1 : 
+  ByteFormat<0, (outs), 
+             (ins GPR:$val, i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
+             "movwf ${ptrlo} + ${offset}",
+             [(PIC16Store GPR:$val, texternalsym:$ptrlo, (i8 imm:$ptrhi), 
+               (i8 imm:$offset))]>;
+
+// Indirect store. Matched via a DAG replacement pattern.
+def store_indirect : 
+  ByteFormat<0, (outs), 
+             (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
+             "movwi $offset[$fsr]",
+             []>;
+
+//----------------------------
+// Load from memory
+//----------------------------
+// Direct load.
+def movf : 
+  ByteFormat<0, (outs GPR:$dst), 
+             (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+             "movf ${ptrlo} + ${offset}, W",
+             [(set GPR:$dst, 
+               (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi),
+               (i8 imm:$offset)))]>;
+
+def movf_1 : 
+  ByteFormat<0, (outs GPR:$dst), 
+             (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
+             "movf ${ptrlo} + ${offset}, W",
+             [(set GPR:$dst, 
+               (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi),
+               (i8 imm:$offset)))]>;
+
+// Indirect load. Matched via a DAG replacement pattern.
+def load_indirect : 
+  ByteFormat<0, (outs GPR:$dst), 
+             (ins FSR16:$fsr, i8imm:$offset),
+             "moviw $offset[$fsr]",
+             []>;
+
+//-------------------------
+// Various add/sub patterns.
+//-------------------------
+// W += [F] ; load from F and add the value to W. 
+class ADDFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
+  ByteFormat<OpCode, (outs GPR:$dst),
+             (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+              !strconcat(OpcStr, " $ptrlo + $offset, W"),
+             [(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
+                                             (i8 imm:$ptrhi),
+                                             (i8 imm:$offset))))]>;
+// let isTwoAddress = 1 in {
+def addfw_1: ADDFW<0, "addwf", add>;
+def addfw_2: ADDFW<0, "addwf", addc>;
+def addfwc: ADDFW<0, "addwfc", adde>;  // With Carry.
+// }
+
+// [F] += W ; add the value of  W to [F]. 
+class ADDWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
+  ByteFormat<OpCode, (outs),
+             (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+              !strconcat(OpcStr, " $ptrlo + $offset"),
+             [(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
+                                             (i8 imm:$ptrhi),
+                                             (i8 imm:$offset))),
+                                             diraddr:$ptrlo, 
+                                             (i8 imm:$ptrhi), (i8 imm:$offset)
+                                             )]>;
+def addwf_1: ADDWF<0, "addwf", add>;
+def addwf_2: ADDWF<0, "addwf", addc>;
+def addwfc: ADDWF<0, "addwfc", adde>;  // With Carry.
+
+// W -= [F] ; load from F and sub the value from W.
+class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
+  ByteFormat<OpCode, (outs GPR:$dst),
+             (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+              !strconcat(OpcStr, " $ptrlo + $offset, W"),
+             [(set GPR:$dst, (OpNode (PIC16Load diraddr:$ptrlo,
+                                      (i8 imm:$ptrhi), (i8 imm:$offset)),
+                                      GPR:$src))]>;
+//let isTwoAddress = 1 in {
+def subfw_1: SUBFW<0, "subwf", sub>;
+def subfw_2: SUBFW<0, "subwf", subc>;
+def subfwb: SUBFW<0, "subwfb", sube>;  // With Borrow.
+//}
+
+// [F] -= W ; 
+class SUBWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
+  ByteFormat<OpCode, (outs),
+             (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
+              !strconcat(OpcStr, " $ptrlo + $offset"),
+             [(PIC16Store (OpNode (PIC16Load diraddr:$ptrlo,
+                                      (i8 imm:$ptrhi), (i8 imm:$offset)),
+                                      GPR:$src), diraddr:$ptrlo,
+                                      (i8 imm:$ptrhi), (i8 imm:$offset))]>;
+
+def subwf_1: SUBWF<0, "subwf", sub>;
+def subwf_2: SUBWF<0, "subwf", subc>;
+def subwfb: SUBWF<0, "subwfb", sube>;  // With Borrow.
+
+// addlw 
+// W += C ; add literal to W. (Without carry). May Produce a carry.
+class ADDLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
+  LiteralFormat<opcode, (outs GPR:$dst),
+                (ins GPR:$src, i8imm:$literal),
+                !strconcat(OpcStr, " $literal"),
+                [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>;
+
+// let isTwoAddress = 1 in {
+def addlw_1 : ADDLW<0, "addlw", add>;
+def addlw_2 : ADDLW<0, "addlw", addc>;
+def addlwc : ADDLW<0, "addlwc", adde>; // With Carry. (Assembler macro).
+//}
+
+// sublw 
+// W = C - W ; sub W from literal. (Without borrow).
+class SUBLW<bits<6> opcode, SDNode OpNode> :
+  LiteralFormat<opcode, (outs GPR:$dst),
+                (ins GPR:$src, i8imm:$literal),
+                "addlw $literal",
+                [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
+
+//let isTwoAddress = 1 in {
+def sublw_1 : SUBLW<0, sub>;
+def sublw_2 : SUBLW<0, subc>;
+//}
+
+// Banksel.
+let isReMaterializable = 1 in {
+def banksel : 
+  Pseudo<(outs BSR:$dst),
+         (ins i8mem:$ptr),
+         "banksel $ptr",
+         [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>;
+}
+
+// Return insn.
+def Return : 
+  ControlFormat<0, (outs), (ins), "return", [(ret)]>;
+                      
+//===----------------------------------------------------------------------===//
+// PIC16 Replacment Patterns.
+//===----------------------------------------------------------------------===//
+
+// Identify an indirect store and select insns for it.
+def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
+           imm:$offset),
+          (store_indirect GPR:$val, 
+           (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
+           imm:$offset)>;
+
+// Identify an indirect load and select insns for it.
+def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
+           imm:$offset),
+          (load_indirect  (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
+           imm:$offset)>;
 
-//===----------------------------------------------------------------------===//
-//  Arbitrary patterns that map to one or more instructions
-//===----------------------------------------------------------------------===//
-def : Pat<(ret), (RETURN)>;

Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.cpp Wed Nov 19 05:00:54 2008
@@ -15,206 +15,68 @@
 
 #include "PIC16.h"
 #include "PIC16RegisterInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Type.h"
 #include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
+
 
 using namespace llvm;
 
-// FIXME: add subtarget support.
-PIC16RegisterInfo::PIC16RegisterInfo(const TargetInstrInfo &tii)
+PIC16RegisterInfo::PIC16RegisterInfo(const TargetInstrInfo &tii,
+                                     const PIC16Subtarget &st)
   : PIC16GenRegisterInfo(PIC16::ADJCALLSTACKDOWN, PIC16::ADJCALLSTACKUP),
-  TII(tii) {}
-
-/// getRegisterNumbering - Given the enum value for some register, e.g.
-/// PIC16::RA, return the number that it corresponds to (e.g. 31).
-unsigned PIC16RegisterInfo::
-getRegisterNumbering(unsigned RegEnum) 
-{
-  assert (RegEnum <= 31 && "Unknown register number!");
-  return RegEnum;
-}
+    TII(tii),
+    ST(st) {}
 
-void PIC16RegisterInfo::
-copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
-             unsigned DestReg, unsigned SrcReg,
-             const TargetRegisterClass *RC) const 
-{
-  return;
-}
-
-void PIC16RegisterInfo::reMaterialize(MachineBasicBlock &MBB, 
-                                      MachineBasicBlock::iterator I,
-                                      unsigned DestReg, 
-                                      const MachineInstr *Orig) const 
-{
-  MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
-  MI->getOperand(0).setReg(DestReg);
-  MBB.insert(I, MI);
-}
-
-MachineInstr *PIC16RegisterInfo::
-foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const 
-{
-  MachineInstr *NewMI = NULL;
-  return NewMI;
-}
-
-//===----------------------------------------------------------------------===//
-//
-// Callee Saved Registers methods 
-//
-//===----------------------------------------------------------------------===//
+#include "PIC16GenRegisterInfo.inc"
 
 /// PIC16 Callee Saved Registers
 const unsigned* PIC16RegisterInfo::
-getCalleeSavedRegs(const MachineFunction *MF) const 
-{
-  // PIC16 calle-save register range is $16-$26(s0-s7)
+getCalleeSavedRegs(const MachineFunction *MF) const {
   static const unsigned CalleeSavedRegs[] = { 0 };
   return CalleeSavedRegs;
 }
 
-/// PIC16 Callee Saved Register Classes
-const TargetRegisterClass* const* 
-PIC16RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const 
-{
+// PIC16 Callee Saved Reg Classes
+const TargetRegisterClass* const*
+PIC16RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 };
   return CalleeSavedRegClasses;
 }
 
-BitVector PIC16RegisterInfo::
-getReservedRegs(const MachineFunction &MF) const
-{
+BitVector PIC16RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   BitVector Reserved(getNumRegs());
   return Reserved;
 }
 
-//===----------------------------------------------------------------------===//
-//
-// Stack Frame Processing methods
-// +----------------------------+
-//
-// FIXME: Add stack layout description here.
-//
-//
-//===----------------------------------------------------------------------===//
-
-// hasFP - Return true if the specified function should have a dedicated frame
-// pointer register.  This is true if the function has variable sized allocas or
-// if frame pointer elimination is disabled.
-bool PIC16RegisterInfo::
-hasFP(const MachineFunction &MF) const {
+bool PIC16RegisterInfo::hasFP(const MachineFunction &MF) const {
   return false;
 }
 
-// This function eliminate ADJCALLSTACKDOWN, 
-// ADJCALLSTACKUP pseudo instructions
-void PIC16RegisterInfo::
-eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
-                              MachineBasicBlock::iterator I) const {
-  // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
-  MBB.erase(I);
-}
-
-// FrameIndex represent objects inside a abstract stack.
-// We must replace FrameIndex with an stack/frame pointer
-// direct reference.
 void PIC16RegisterInfo::
-eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, 
-                    RegScavenger *RS) const 
-{
-  MachineInstr &MI    = *II;
-  MachineFunction &MF = *MI.getParent()->getParent();
-
-  unsigned i = 0;
-  while (!MI.getOperand(i).isFI()) {
-    ++i;
-    assert(i < MI.getNumOperands() && 
-           "Instr doesn't have FrameIndex operand!");
-  }
-
-  int FrameIndex = MI.getOperand(i).getIndex();
-  int stackSize  = MF.getFrameInfo()->getStackSize();
-  int spOffset   = MF.getFrameInfo()->getObjectOffset(FrameIndex);
-
-  DOUT << "\nFunction : " << MF.getFunction()->getName() << "\n";
-  DOUT << "<--------->\n";
-#ifndef NDEBUG
-  MI.print(DOUT);
-#endif
-  DOUT << "FrameIndex : " << FrameIndex << "\n";
-  DOUT << "spOffset   : " << spOffset << "\n";
-  DOUT << "stackSize  : " << stackSize << "\n";
-
-  // As explained on LowerFORMAL_ARGUMENTS, detect negative offsets 
-  // and adjust SPOffsets considering the final stack size.
-  int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset));
+eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
+                    RegScavenger *RS) const
+{    /* NOT YET IMPLEMENTED */  }
 
-  DOUT << "Offset     : " << Offset << "\n";
-  DOUT << "<--------->\n";
-
-  // MI.getOperand(i+1).ChangeToImmediate(Offset);
-  MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
-}
-
-void PIC16RegisterInfo::
-emitPrologue(MachineFunction &MF) const 
-{
-}
-
-void PIC16RegisterInfo::
-emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 
-{
-}
+void PIC16RegisterInfo::emitPrologue(MachineFunction &MF) const
+{    /* NOT YET IMPLEMENTED */  }
 
 void PIC16RegisterInfo::
-processFunctionBeforeFrameFinalized(MachineFunction &MF) const 
-{
-}
-
-unsigned PIC16RegisterInfo::
-getRARegister() const {
-  assert(0 && "What is the return address register");
-  return 0;
-}
+emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
+{    /* NOT YET IMPLEMENTED */  }
 
-unsigned PIC16RegisterInfo::
-getFrameRegister(MachineFunction &MF) const {
-  return PIC16::STKPTR;
+int PIC16RegisterInfo::
+getDwarfRegNum(unsigned RegNum, bool isEH) const {
+  assert(0 && "Not keeping track of debug information yet!!");
+  return -1;
 }
 
-unsigned PIC16RegisterInfo::
-getEHExceptionRegister() const {
-  assert(0 && "What is the exception register");
+unsigned PIC16RegisterInfo::getFrameRegister(MachineFunction &MF) const {
+  assert(0 && "PIC16 Does not have any frame register");
   return 0;
 }
 
-unsigned PIC16RegisterInfo::
-getEHHandlerRegister() const {
-  assert(0 && "What is the exception handler register");
+unsigned PIC16RegisterInfo::getRARegister() const {
+  assert(0 && "PIC16 Does not have any return address register");
   return 0;
 }
 
-int PIC16RegisterInfo::
-getDwarfRegNum(unsigned RegNum, bool isEH) const {
-  assert(0 && "What is the dwarf register number");
-  return -1;
-}
-
-
-#include "PIC16GenRegisterInfo.inc"
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.h Wed Nov 19 05:00:54 2008
@@ -20,65 +20,43 @@
 namespace llvm {
 
 // Forward Declarations.
-class TargetInstrInfo;
-class Type;
+  class PIC16Subtarget;
+  class TargetInstrInfo;
 
-struct PIC16RegisterInfo : public PIC16GenRegisterInfo {
-  const TargetInstrInfo &TII;
+class PIC16RegisterInfo : public PIC16GenRegisterInfo {
+  private:
+    const TargetInstrInfo &TII;
+    const PIC16Subtarget &ST;
   
-  explicit PIC16RegisterInfo(const TargetInstrInfo &tii);
+  public:
+    PIC16RegisterInfo(const TargetInstrInfo &tii, 
+                      const PIC16Subtarget &st);
+
+
+  //------------------------------------------------------
+  // Pure virtual functions from TargetRegisterInfo
+  //------------------------------------------------------
+
+  // PIC16 callee saved registers
+  virtual const unsigned* 
+  getCalleeSavedRegs(const MachineFunction *MF = 0) const;
+
+  // PIC16 callee saved register classes
+  virtual const TargetRegisterClass* const *
+  getCalleeSavedRegClasses(const MachineFunction *MF) const;
+
+  virtual BitVector getReservedRegs(const MachineFunction &MF) const;
+  virtual bool hasFP(const MachineFunction &MF) const;
+
+  virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+                        int SPAdj, RegScavenger *RS=NULL) const;
+
+  virtual void emitPrologue(MachineFunction &MF) const;
+  virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
+  virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const;
+  virtual unsigned getFrameRegister(MachineFunction &MF) const;
+  virtual unsigned getRARegister() const;
 
-  /// getRegisterNumbering - Given the enum value for some register, e.g.
-  /// PIC16::RA, return the number that it corresponds to (e.g. 31).
-  static unsigned getRegisterNumbering(unsigned RegEnum);
-
-  void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
-                     unsigned DestReg, const MachineInstr *Orig) const;
-
-  MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
-                                  int FrameIndex) const;
-
-  MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
-                                  MachineInstr* LoadMI) const {
-    return 0;
-  }
-
-  void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-                    unsigned DestReg, unsigned SrcReg,
-                    const TargetRegisterClass *RC) const;
-  
-
-  const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
-
-  const TargetRegisterClass* const*
-  getCalleeSavedRegClasses(const MachineFunction* MF = 0) const;
-
-  BitVector getReservedRegs(const MachineFunction &MF) const;
-
-  bool hasFP(const MachineFunction &MF) const;
-
-  void eliminateCallFramePseudoInstr(MachineFunction &MF,
-                                     MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator I) const;
-
-  /// Stack Frame Processing Methods.
-  void eliminateFrameIndex(MachineBasicBlock::iterator II,
-                           int SPAdj, RegScavenger *RS = NULL) const;
-
-  void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
-
-  void emitPrologue(MachineFunction &MF) const;
-  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
-  
-  /// Debug information queries.
-  unsigned getRARegister() const;
-  unsigned getFrameRegister(MachineFunction &MF) const;
-
-  /// Exception handling queries.
-  unsigned getEHExceptionRegister() const;
-  unsigned getEHHandlerRegister() const;
-
-  int getDwarfRegNum(unsigned RegNum, bool isEH) const;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16RegisterInfo.td Wed Nov 19 05:00:54 2008
@@ -11,74 +11,22 @@
 //  Declarations that describe the PIC16 register file
 //===----------------------------------------------------------------------===//
 
-// We have banks of 32 registers each.
 class PIC16Reg<string n> : Register<n> {
-  field bits<5> Num;
   let Namespace = "PIC16";
 }
 
-// PIC16 CPU Registers
-class PIC16GPRReg<bits<5> num, string n> : PIC16Reg<n> {
-  let Num = num;
-}
-
-// CPU GPR Registers
-def FSR0 : PIC16GPRReg< 0, "FSR0">, DwarfRegNum<[0]>;
-def FSR1 : PIC16GPRReg< 1, "FSR1">, DwarfRegNum<[1]>;
-
-// CPU Registers Class
-def PTRRegs : RegisterClass<"PIC16", [i16], 8, 
-  [FSR0, FSR1]>
-{
-  let MethodProtos = [{
-    iterator allocation_order_end(const MachineFunction &MF) const;
-  }];
-  let MethodBodies = [{
-    PTRRegsClass::iterator
-    PTRRegsClass::allocation_order_end(const MachineFunction &MF) const {
-      return end();
-    }
-  }];
-}
+// PIC16 Registers.
+def W   : PIC16Reg<"W">;
+def FSR0   : PIC16Reg<"FSR0">;
+def FSR1   : PIC16Reg<"FSR1">;
+def BS     : PIC16Reg<"BS">;
+
+def STATUS : PIC16Reg<"STATUS">;
+
+// PIC16 Register classes.
+def GPR    : RegisterClass<"PIC16", [i8], 8, [W]>;
+def FSR16  : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]>;
+def BSR  : RegisterClass<"PIC16", [i8], 8, [BS]>;
 
-def WREG : PIC16GPRReg< 0, "WREG">, DwarfRegNum<[0]>;
+def STATUSR: RegisterClass<"PIC16", [i8], 8, [STATUS]>;
 
-// CPU Registers Class
-def CPURegs : RegisterClass<"PIC16", [i8], 8, 
-  [WREG]>
-{
-  let MethodProtos = [{
-    iterator allocation_order_end(const MachineFunction &MF) const;
-  }];
-  let MethodBodies = [{
-    CPURegsClass::iterator
-    CPURegsClass::allocation_order_end(const MachineFunction &MF) const {
-      return end();
-    }
-  }];
-}
-
-def STATUSREG : PIC16GPRReg<2, "STATUS">, DwarfRegNum<[0]>;
-
-// STATUS Registers Class
-def STATUSRegs : RegisterClass<"PIC16", [i8], 8, 
-  [STATUSREG]>;
-
-
-// Dummy stack pointer.
-def STKPTR : PIC16GPRReg< 0, "SP">, DwarfRegNum<[0]>;
-
-// CPU Registers Class
-def STKRegs : RegisterClass<"PIC16", [i8], 8, 
-  [STKPTR]>
-{
-  let MethodProtos = [{
-    iterator allocation_order_end(const MachineFunction &MF) const;
-  }];
-  let MethodBodies = [{
-    STKRegsClass::iterator
-    STKRegsClass::allocation_order_end(const MachineFunction &MF) const {
-      return end();
-    }
-  }];
-}

Modified: llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16Subtarget.cpp Wed Nov 19 05:00:54 2008
@@ -11,14 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "PIC16.h"
 #include "PIC16Subtarget.h"
 #include "PIC16GenSubtarget.inc"
+
 using namespace llvm;
 
-PIC16Subtarget::PIC16Subtarget(const TargetMachine &TM, const Module &M, 
-                               const std::string &FS) 
-  :IsPIC16Old(false)
+PIC16Subtarget::PIC16Subtarget(const Module &M, const std::string &FS, 
+                               bool Cooper)
+  :IsCooper(Cooper)
 {
   std::string CPU = "generic";
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16Subtarget.h Wed Nov 19 05:00:54 2008
@@ -14,7 +14,6 @@
 #ifndef PIC16SUBTARGET_H
 #define PIC16SUBTARGET_H
 
-#include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtarget.h"
 
 #include <string>
@@ -23,19 +22,23 @@
 class Module;
 
 class PIC16Subtarget : public TargetSubtarget {
-  bool IsPIC16Old;
+
+  // IsCooper - Target ISA is Cooper.
+  bool IsCooper;
 
 public:
   /// This constructor initializes the data members to match that
   /// of the specified module.
   ///
-  PIC16Subtarget(const TargetMachine &TM, const Module &M, 
-                 const std::string &FS);
+  PIC16Subtarget(const Module &M, const std::string &FS, bool Cooper);
   
+  /// isCooper - Returns true if the target ISA is Cooper.
+  bool isCooper() const { return IsCooper; }
+
   /// ParseSubtargetFeatures - Parses features string setting specified 
   /// subtarget options.  Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
 };
 } // End llvm namespace
 
-#endif
+#endif  // PIC16SUBTARGET_H

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.cpp Wed Nov 19 05:00:54 2008
@@ -17,11 +17,15 @@
 using namespace llvm;
 
 PIC16TargetAsmInfo::
-PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
+PIC16TargetAsmInfo(const PIC16TargetMachine &TM) 
   : TargetAsmInfo(TM) {
-  Data16bitsDirective = "\t.half\t";
-  Data32bitsDirective = "\t.word\t";
   CommentString = ";";
-  COMMDirective = "\t";
-  COMMDirectiveTakesAlignment = 0;
+  Data8bitsDirective = " db ";
+  Data16bitsDirective = " db ";
+  Data32bitsDirective = " db ";
+  DataSectionStartSuffix = " IDATA ";
+  UDataSectionStartSuffix = " UDATA ";
+  TextSectionStartSuffix = " CODE ";
+  RomDataSectionStartSuffix = " ROMDATA ";
+  ZeroDirective = NULL;
 }

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetAsmInfo.h Wed Nov 19 05:00:54 2008
@@ -23,6 +23,17 @@
 
   struct PIC16TargetAsmInfo : public TargetAsmInfo {
     PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
+    const char *UDataSectionStartSuffix;
+    const char *RomDataSectionStartSuffix;
+    public :
+    const char *getUDataSectionStartSuffix() const {
+      return UDataSectionStartSuffix;
+    }
+    const char *getRomDataSectionStartSuffix() const {
+      return RomDataSectionStartSuffix;
+    }
+
+
   };
 
 } // namespace llvm

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.cpp Wed Nov 19 05:00:54 2008
@@ -16,6 +16,7 @@
 #include "PIC16TargetMachine.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetMachineRegistry.h"
 
@@ -29,50 +30,42 @@
 extern "C" int PIC16TargetMachineModule;
 int PIC16TargetMachineModule = 0;
 
-namespace {
-  // Register the targets
-  RegisterTarget<PIC16TargetMachine> X("pic16", "PIC16 14-bit [experimental]");
-}
 
-PIC16TargetMachine::
-PIC16TargetMachine(const Module &M, const std::string &FS) :
-  Subtarget(*this, M, FS), DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), 
+// Register the targets
+static RegisterTarget<PIC16TargetMachine> 
+X("pic16", "PIC16 14-bit (experimental).");
+static RegisterTarget<CooperTargetMachine> 
+Y("cooper", "PIC16 Cooper (experimental).");
+
+// PIC16TargetMachine - Traditional PIC16 Machine.
+PIC16TargetMachine::PIC16TargetMachine(const Module &M, const std::string &FS,
+                                       bool Cooper)
+: Subtarget(M, FS, Cooper),
+  DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), 
   InstrInfo(*this), TLInfo(*this),
   FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0) { }
 
+// CooperTargetMachine - Uses the same PIC16TargetMachine, but makes IsCooper
+// as true.
+CooperTargetMachine::CooperTargetMachine(const Module &M, const std::string &FS)
+  : PIC16TargetMachine(M, FS, true) {}
+
 
-const TargetAsmInfo *PIC16TargetMachine::createTargetAsmInfo() const 
-{
+const TargetAsmInfo *PIC16TargetMachine::createTargetAsmInfo() const {
   return new PIC16TargetAsmInfo(*this);
 }
 
-//===----------------------------------------------------------------------===//
-// Pass Pipeline Configuration
-//===----------------------------------------------------------------------===//
-
-bool PIC16TargetMachine::addInstSelector(PassManagerBase &PM, bool Fast) 
-{
+bool PIC16TargetMachine::addInstSelector(PassManagerBase &PM, bool Fast) {
   // Install an instruction selector.
   PM.add(createPIC16ISelDag(*this));
   return false;
 }
 
 bool PIC16TargetMachine::
-addPrologEpilogInserter(PassManagerBase &PM, bool Fast) 
-{
-  return false;
-}
-
-bool PIC16TargetMachine::addPreEmitPass(PassManagerBase &PM, bool Fast) 
-{
-  return true;
-}
-
-bool PIC16TargetMachine::
-addAssemblyEmitter(PassManagerBase &PM, bool Fast, raw_ostream &Out) 
-{
+addAssemblyEmitter(PassManagerBase &PM, bool Fast, raw_ostream &Out) {
   // Output assembly language.
   PM.add(createPIC16CodePrinterPass(Out, *this));
   return false;
 }
 
+

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h?rev=59617&r1=59616&r2=59617&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetMachine.h Wed Nov 19 05:00:54 2008
@@ -17,6 +17,7 @@
 
 #include "PIC16InstrInfo.h"
 #include "PIC16ISelLowering.h"
+#include "PIC16RegisterInfo.h"
 #include "PIC16Subtarget.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetFrameInfo.h"
@@ -31,31 +32,42 @@
   const TargetData      DataLayout;       // Calculates type size & alignment
   PIC16InstrInfo        InstrInfo;
   PIC16TargetLowering   TLInfo;
+
+  // PIC16 does not have any call stack frame, therefore not having 
+  // any PIC16 specific FrameInfo class.
   TargetFrameInfo       FrameInfo;
 
 protected:
   virtual const TargetAsmInfo *createTargetAsmInfo() const;
-  
+
 public:
-  PIC16TargetMachine(const Module &M, const std::string &FS);
+  PIC16TargetMachine(const Module &M, const std::string &FS, 
+                     bool Cooper = false);
+
+  virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
+  virtual const PIC16InstrInfo *getInstrInfo() const  { return &InstrInfo; }
+  virtual const TargetData *getTargetData() const     { return &DataLayout;}
+  virtual const PIC16Subtarget *getSubtargetImpl() const { return &Subtarget; }
+ 
+  virtual const PIC16RegisterInfo *getRegisterInfo() const { 
+    return &(InstrInfo.getRegisterInfo()); 
+  }
+
+  virtual PIC16TargetLowering *getTargetLowering() const { 
+    return const_cast<PIC16TargetLowering*>(&TLInfo); 
+  }
 
-  virtual const TargetFrameInfo *getFrameInfo() const 
-  { return &FrameInfo; }
-  virtual const PIC16InstrInfo *getInstrInfo() const 
-  { return &InstrInfo; }
-  virtual const TargetData *getTargetData() const    
-  { return &DataLayout; }
-  virtual PIC16TargetLowering *getTargetLowering() const 
-  { return const_cast<PIC16TargetLowering*>(&TLInfo); }
-  virtual const PIC16RegisterInfo *getRegisterInfo() const 
-  { return &InstrInfo.getRegisterInfo(); }
-  
   virtual bool addInstSelector(PassManagerBase &PM, bool Fast);
-  virtual bool addPrologEpilogInserter(PassManagerBase &PM, bool Fast);
-  virtual bool addPreEmitPass(PassManagerBase &PM, bool Fast);
-  virtual bool addAssemblyEmitter(PassManagerBase &PM, bool Fast, 
+  virtual bool addAssemblyEmitter(PassManagerBase &PM, bool Fast,
                                   raw_ostream &Out);
-};
+}; // PIC16TargetMachine.
+
+/// CooperTargetMachine
+class CooperTargetMachine : public PIC16TargetMachine {
+public:
+  CooperTargetMachine(const Module &M, const std::string &FS);
+}; // CooperTargetMachine.
+
 } // end namespace llvm
 
 #endif





More information about the llvm-commits mailing list