Add new helpers for registering targets.
[oota-llvm.git] / lib / Target / PIC16 / PIC16AsmPrinter.cpp
index 151fafc4c5463dcc63e7715fb94feb325de5a65f..95d363e4ecc1754f6c47bfc5c6f8532fe263a6ee 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "asm-printer"
-#include "PIC16.h"
-#include "PIC16TargetMachine.h"
-#include "PIC16ConstantPoolValue.h"
-#include "PIC16InstrInfo.h"
-#include "llvm/Constants.h"
+#include "PIC16AsmPrinter.h"
+#include "PIC16TargetAsmInfo.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
 #include "llvm/Module.h"
-#include "llvm/ADT/SetVector.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/DwarfWriter.h"
+#include "llvm/Support/FormattedStream.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/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include <cctype>
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Target/TargetRegistry.h"
 
 using namespace llvm;
 
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
-namespace {
-  struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
-    PIC16AsmPrinter(std::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(std::ostream &o,
-                                               PIC16TargetMachine &tm) {
-  return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
-}
-
-void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const 
-{
-  // Currently unimplemented.
+bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+  printInstruction(MI);
+  return true;
 }
 
+/// runOnMachineFunction - This emits the frame section, autos section and 
+/// assembly for each instruction. Also takes care of function begin debug
+/// directive and file begin debug directive (if required) for the function.
+///
+bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+  this->MF = &MF;
 
-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);
-}
-
-/// 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++;
-     }
-   }
-   SwitchToTextSection(CurrentFnName.c_str(), F);  
-   O << "_" << CurrentFnName << ":" ; 
-   O << "\n";
-}
+  // This calls the base class function required to be called at beginning
+  // of runOnMachineFunction.
+  SetupMachineFunction(MF);
 
+  // Get the mangled name.
+  const Function *F = MF.getFunction();
+  CurrentFnName = Mang->getMangledName(F);
 
-/// runOnMachineFunction - This uses the printInstruction()
-/// method to print assembly for each instruction.
-///
-bool PIC16AsmPrinter::
-runOnMachineFunction(MachineFunction &MF) 
-{
+  // Emit the function frame (args and temps).
+  EmitFunctionFrame(MF);
 
-  // DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>());
-  SetupMachineFunction(MF);
-  O << "\n";
+  DbgInfo.BeginFunction(MF);
 
-  // NOTE: we don't print out constant pools here, they are handled as
-  // instructions.
-  O << "\n";
+  // Emit the autos section of function.
+  EmitAutos(CurrentFnName);
 
-  // What's my mangled name?
-  CurrentFnName = Mang->getValueName(MF.getFunction());
+  // Now emit the instructions of function in its code section.
+  const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str();
+  const Section *fCodeSection = TAI->getNamedSection(codeSection,
+                                                     SectionFlags::Code);
+  // Start the Code Section.
+  O <<  "\n";
+  SwitchToSection(fCodeSection);
 
-  // Emit the function start directives
-  emitFunctionStart(MF);
+  // Emit the frame address of the function at the beginning of code.
+  O << "\tretlw  low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+  O << "\tretlw  high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
 
-  // Emit pre-function debug information.
-  // DW.BeginFunction(&MF);
+  // Emit function start label.
+  O << CurrentFnName << ":\n";
 
+  DebugLoc CurDL;
+  O << "\n"; 
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
+
     // Print a label for the basic block.
     if (I != MF.begin()) {
       printBasicBlockLabel(I, true);
       O << '\n';
     }
+    
+    // Print a basic block.
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
+
+      // Emit the line directive if source line changed.
+      const DebugLoc DL = II->getDebugLoc();
+      if (!DL.isUnknown() && DL != CurDL) {
+        DbgInfo.ChangeDebugLoc(MF, DL);
+        CurDL = DL;
+      }
+        
       // Print the assembly for the instruction.
-      O << '\t';
-      printInstruction(II);
-      ++EmittedInsts;
+      printMachineInstruction(II);
     }
   }
+  
+  // Emit function end debug directives.
+  DbgInfo.EndFunction(MF);
 
-  // Emit post-function debug information.
-  // DW.EndFunction();
-
-  // We didn't modify anything.
-  return false;
+  return false;  // we didn't modify anything.
 }
 
-void PIC16AsmPrinter::
-printOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
-{
+
+// printOperand - print operand of insn.
+void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
   const MachineOperand &MO = MI->getOperand(opNum);
-  const TargetRegisterInfo  &RI = *TM.getRegisterInfo();
 
-  switch (MO.getType()) 
-  {
+  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");
+        llvm_unreachable("not implemented");
+      return;
+
+    case MachineOperand::MO_Immediate:
+      O << (int)MO.getImm();
+      return;
+
+    case MachineOperand::MO_GlobalAddress: {
+      O << Mang->getMangledName(MO.getGlobal());
       break;
     }
-    case MachineOperand::MO_Immediate: 
-    {
-      if (!Modifier || strcmp(Modifier, "no_hash") != 0)
-        O << "#";
-      O << (int)MO.getImm();
+    case MachineOperand::MO_ExternalSymbol: {
+       const char *Sname = MO.getSymbolName();
+
+      // If its a libcall name, record it to decls section.
+      if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
+        LibcallDecls.push_back(Sname);
+      }
+
+      O  << Sname;
       break;
     }
     case MachineOperand::MO_MachineBasicBlock:
-    {
       printBasicBlockLabel(MO.getMBB());
       return;
-    }
-    case MachineOperand::MO_GlobalAddress: 
-    {
-      O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset();
-      break;
-    }
-    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.
+      llvm_unreachable(" Operand type not supported.");
+  }
 }
 
-static void 
-printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) 
-{
-  assert(V < (1 << 12) && "Not a valid so_imm value!");
-  unsigned Imm = V;
-  
-  O << Imm;
+/// printCCOperand - Print the cond code operand.
+///
+void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
+  int CC = (int)MI->getOperand(opNum).getImm();
+  O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
 }
 
-/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
-/// immediate in bits 0-7.
-void PIC16AsmPrinter::
-printSOImmOperand(const MachineInstr *MI, int OpNum) 
-{
-  const MachineOperand &MO = MI->getOperand(OpNum);
-  assert(MO.isImmediate() && "Not a valid so_imm value!");
-  printSOImm(O, MO.getImm(), TAI);
+/// printLibcallDecls - print the extern declarations for compiler 
+/// intrinsics.
+///
+void PIC16AsmPrinter::printLibcallDecls(void) {
+  // If no libcalls used, return.
+  if (LibcallDecls.empty()) return;
+
+  O << TAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
+  // Remove duplicate entries.
+  LibcallDecls.sort();
+  LibcallDecls.unique();
+  for (std::list<const char*>::const_iterator I = LibcallDecls.begin(); 
+       I != LibcallDecls.end(); I++) {
+    O << TAI->getExternDirective() << *I << "\n";
+    O << TAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
+    O << TAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
+  }
+  O << TAI->getCommentString() << "External decls for libcalls - END." <<"\n";
 }
 
+/// doInitialization - Perfrom Module level initializations here.
+/// One task that we do here is to sectionize all global variables.
+/// The MemSelOptimizer pass depends on the sectionizing.
+///
+bool PIC16AsmPrinter::doInitialization(Module &M) {
+  bool Result = AsmPrinter::doInitialization(M);
 
-void PIC16AsmPrinter:: printAddrModeOperand(const MachineInstr *MI, int Op) 
-{
-  const MachineOperand &MO1 = MI->getOperand(Op);
-  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  // 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 << "\n\t#include P16F1937.INC\n";
 
-  if (MO2.isFrameIndex ()) {
-    printOperand(MI, Op+1);
-    return;
+  // Set the section names for all globals.
+  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I) {
+    I->setSection(TAI->SectionForGlobal(I)->getName());
   }
 
-  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
-    printOperand(MI, Op);
-    return;
-  }
+  DbgInfo.BeginModule(M);
+  EmitFunctionDecls(M);
+  EmitUndefinedVars(M);
+  EmitDefinedVars(M);
+  EmitIData(M);
+  EmitUData(M);
+  EmitRomData(M);
+  return Result;
+}
 
-  // If this is Stack Slot
-  if (MO1.isRegister()) {  
-    if(strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP")==0) 
-    {
-      O << CurrentFnName <<"_"<< MO2.getImm();
-      return;
-    }
-    O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
-    O << "+";
-    O << MO2.getImm();
-    O << "]";
-    return;
+/// Emit extern decls for functions imported from other modules, and emit
+/// global declarations for function defined in this module and which are
+/// available to other modules.
+///
+void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
+ // Emit declarations for external functions.
+  O <<"\n"<<TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
+  for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
+    if (I->isIntrinsic())
+      continue;
+
+    std::string Name = Mang->getMangledName(I);
+    if (Name.compare("@abort") == 0)
+      continue;
+    
+    if (!I->isDeclaration() && !I->hasExternalLinkage())
+      continue;
+
+    const char *directive = I->isDeclaration() ? TAI->getExternDirective() :
+                                                 TAI->getGlobalDirective();
+      
+    O << directive << Name << "\n";
+    O << directive << PAN::getRetvalLabel(Name) << "\n";
+    O << directive << PAN::getArgsLabel(Name) << "\n";
   }
 
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
-  O << "]";
+  O << TAI->getCommentString() << "Function Declarations - END." <<"\n";
 }
 
+// Emit variables imported from other Modules.
+void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
+  std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDecls->Items;
+  if (!Items.size()) return;
 
-void PIC16AsmPrinter:: printRegisterList(const MachineInstr *MI, int opNum) 
-{
-  O << "{";
-  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
-    printOperand(MI, i);
-    if (i != e-1) O << ", ";
+  O << "\n" << TAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
+  for (unsigned j = 0; j < Items.size(); j++) {
+    O << TAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
   }
-  O << "}";
+  O << TAI->getCommentString() << "Imported Variables - END" << "\n";
 }
 
-void PIC16AsmPrinter::
-printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier) 
-{
-  assert(Modifier && "This operand only works with a modifier!");
-
-  // 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();
-
-    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);
-    }
+// Emit variables defined in this module and are available to other modules.
+void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
+  std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDefs->Items;
+  if (!Items.size()) return;
+
+  O << "\n" << TAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
+  for (unsigned j = 0; j < Items.size(); j++) {
+    O << TAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
   }
+  O <<  TAI->getCommentString() << "Exported Variables - END" << "\n";
 }
 
+// Emit initialized data placed in ROM.
+void PIC16AsmPrinter::EmitRomData(Module &M) {
+  // Print ROM Data section.
+  const std::vector<PIC16Section*> &ROSections = PTAI->ROSections;
+  for (unsigned i = 0; i < ROSections.size(); i++) {
+    const std::vector<const GlobalVariable*> &Items = ROSections[i]->Items;
+    if (!Items.size()) continue;
+    O << "\n";
+    SwitchToSection(PTAI->ROSections[i]->S_);
+    for (unsigned j = 0; j < Items.size(); j++) {
+      O << Mang->getMangledName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      int AddrSpace = Items[j]->getType()->getAddressSpace();
+      EmitGlobalConstant(C, AddrSpace);
+    }
+  }
+}
 
-bool PIC16AsmPrinter:: doInitialization(Module &M) 
-{
-  // Emit initial debug information.
-  // DW.BeginModule(&M);
-
-  bool Result = AsmPrinter::doInitialization(M);
-  return Result;
+bool PIC16AsmPrinter::doFinalization(Module &M) {
+  printLibcallDecls();
+  EmitRemainingAutos();
+  DbgInfo.EndModule(M);
+  O << "\n\t" << "END\n";
+  return AsmPrinter::doFinalization(M);
 }
 
-bool PIC16AsmPrinter:: doFinalization(Module &M) 
-{
+void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
+  const Function *F = MF.getFunction();
+  std::string FuncName = Mang->getMangledName(F);
   const TargetData *TD = TM.getTargetData();
+  // Emit the data section name.
+  O << "\n"; 
+  const char *SectionName = PAN::getFrameSectionName(CurrentFnName).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;
+  const Section *fPDataSection = TAI->getNamedSection(SectionName,
+                                                      SectionFlags::Writeable);
+  SwitchToSection(fPDataSection);
+  
+  // Emit function frame label
+  O << PAN::getFrameLabel(CurrentFnName) << ":\n";
+
+  const Type *RetType = F->getReturnType();
+  unsigned RetSize = 0; 
+  if (RetType->getTypeID() != Type::VoidTyID) 
+    RetSize = TD->getTypeAllocSize(RetType);
+  
+  //Emit function return value space
+  // FIXME: Do not emit RetvalLable when retsize is zero. To do this
+  // we will need to avoid printing a global directive for Retval label
+  // in emitExternandGloblas.
+  if(RetSize > 0)
+     O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
+  else
+     O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
+   
+  // Emit variable to hold the space for function arguments 
+  unsigned ArgSize = 0;
+  for (Function::const_arg_iterator argi = F->arg_begin(),
+           arge = F->arg_end(); argi != arge ; ++argi) {
+    const Type *Ty = argi->getType();
+    ArgSize += TD->getTypeAllocSize(Ty);
+   }
 
-    if (EmitSpecialLLVMGlobal(I)) {
+  O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
+
+  // Emit temporary space
+  int TempSize = PTLI->GetTmpSize();
+  if (TempSize > 0)
+    O << PAN::getTempdataLabel(CurrentFnName) << " RES  " << TempSize << '\n';
+}
+
+void PIC16AsmPrinter::EmitIData(Module &M) {
+
+  // Print all IDATA sections.
+  const std::vector<PIC16Section*> &IDATASections = PTAI->IDATASections;
+  for (unsigned i = 0; i < IDATASections.size(); i++) {
+    O << "\n";
+    if (IDATASections[i]->S_->getName().find("llvm.") != std::string::npos)
       continue;
+    SwitchToSection(IDATASections[i]->S_);
+    std::vector<const GlobalVariable*> Items = IDATASections[i]->Items;
+    for (unsigned j = 0; j < Items.size(); j++) {
+      std::string Name = Mang->getMangledName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      int AddrSpace = Items[j]->getType()->getAddressSpace();
+      O << Name;
+      EmitGlobalConstant(C, AddrSpace);
     }
+  }
+}
 
-    std::string name = Mang->getValueName(I);
-    Constant *C = I->getInitializer();
-    const Type *Type = C->getType();
-    unsigned Size = TD->getABITypeSize(Type);
-    unsigned Align = TD->getPreferredAlignmentLog(I);
-
-    const char *VisibilityDirective = NULL;
-    if (I->hasHiddenVisibility())
-      VisibilityDirective = TAI->getHiddenDirective();
-    else if (I->hasProtectedVisibility())
-      VisibilityDirective = TAI->getProtectedDirective();
-
-    if (VisibilityDirective)
-      O << VisibilityDirective << name << "\n";
-
-    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;
-        }
-      }
+void PIC16AsmPrinter::EmitUData(Module &M) {
+  const TargetData *TD = TM.getTargetData();
 
-      if (!I->hasSection() &&
-          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-           I->hasLinkOnceLinkage())) {
-        if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-        if (!NoZerosInBSS && TAI->getBSSSection())
-           SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
-        else
-          SwitchToDataSection(TAI->getDataSection(), 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;
-      }
+  // Print all BSS sections.
+  const std::vector<PIC16Section*> &BSSSections = PTAI->BSSSections;
+  for (unsigned i = 0; i < BSSSections.size(); i++) {
+    O << "\n";
+    SwitchToSection(BSSSections[i]->S_);
+    std::vector<const GlobalVariable*> Items = BSSSections[i]->Items;
+    for (unsigned j = 0; j < Items.size(); j++) {
+      std::string Name = Mang->getMangledName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      const Type *Ty = C->getType();
+      unsigned Size = TD->getTypeAllocSize(Ty);
+
+      O << Name << " RES " << Size << "\n";
     }
+  }
+}
 
-    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
-    }
-    case GlobalValue::InternalLinkage: 
-    {
-      if (I->isConstant()) {
-        const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
-        if (TAI->getCStringSection() && CVA && CVA->isCString()) {
-          SwitchToDataSection(TAI->getCStringSection(), I);
-          break;
-        }
+void PIC16AsmPrinter::EmitAutos(std::string FunctName) {
+  // Section names for all globals are already set.
+  const TargetData *TD = TM.getTargetData();
+
+  // Now print Autos section for this function.
+  std::string SectionName = PAN::getAutosSectionName(FunctName);
+  const std::vector<PIC16Section*> &AutosSections = PTAI->AutosSections;
+  for (unsigned i = 0; i < AutosSections.size(); i++) {
+    O << "\n";
+    if (AutosSections[i]->S_->getName() == SectionName) { 
+      // Set the printing status to true
+      AutosSections[i]->setPrintedStatus(true);
+      SwitchToSection(AutosSections[i]->S_);
+      const std::vector<const GlobalVariable*> &Items = AutosSections[i]->Items;
+      for (unsigned j = 0; j < Items.size(); j++) {
+        std::string VarName = Mang->getMangledName(Items[j]);
+        Constant *C = Items[j]->getInitializer();
+        const Type *Ty = C->getType();
+        unsigned Size = TD->getTypeAllocSize(Ty);
+        // Emit memory reserve directive.
+        O << VarName << "  RES  " << Size << "\n";
       }
       break;
     }
-    default:
-    {
-      assert(0 && "Unknown linkage type!");
-      break;
-    }
-    } // end switch.
-
-    EmitAlignment(Align, I);
-    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
-      << "\n";
+  }
+}
 
-    // 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);
+// Print autos that were not printed during the code printing of functions.
+// As the functions might themselves would have got deleted by the optimizer.
+void PIC16AsmPrinter::EmitRemainingAutos() {
+  const TargetData *TD = TM.getTargetData();
 
-    EmitGlobalConstant(C);
-    O << '\n';
-  } // end for.
+  // Now print Autos section for this function.
+  std::vector <PIC16Section *>AutosSections = PTAI->AutosSections;
+  for (unsigned i = 0; i < AutosSections.size(); i++) {
+    
+    // if the section is already printed then don't print again
+    if (AutosSections[i]->isPrinted()) 
+      continue;
 
-  O << "\n "<< "END";
-  return AsmPrinter::doFinalization(M);
-}
+    // Set status as printed
+    AutosSections[i]->setPrintedStatus(true);
 
-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);
+    O << "\n";
+    SwitchToSection(AutosSections[i]->S_);
+    const std::vector<const GlobalVariable*> &Items = AutosSections[i]->Items;
+    for (unsigned j = 0; j < Items.size(); j++) {
+      std::string VarName = Mang->getMangledName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      const Type *Ty = C->getType();
+      unsigned Size = TD->getTypeAllocSize(Ty);
+      // Emit memory reserve directive.
+      O << VarName << "  RES  " << Size << "\n";
+    }
+  }
 }
 
-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);
-}
 
-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);
+extern "C" void LLVMInitializePIC16Target() { 
+  // Register the targets
+  RegisterTargetMachine<PIC16TargetMachine> A(ThePIC16Target);  
+  RegisterTargetMachine<CooperTargetMachine> B(TheCooperTarget);
+  RegisterAsmPrinter<PIC16AsmPrinter> C(ThePIC16Target);
+  RegisterAsmPrinter<PIC16AsmPrinter> D(TheCooperTarget);
 }