assert(0) -> LLVM_UNREACHABLE.
[oota-llvm.git] / lib / Target / PIC16 / PIC16AsmPrinter.cpp
index c6b2ace6f664db4e7c65296142b3ef7ea3a71ed3..d80476cdfad0ecacf8d56d4955a36e8330562c71 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/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/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.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"
 
 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 
-{
-  // FIXME: 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;
-  }
+  // This calls the base class function required to be called at beginning
+  // of runOnMachineFunction.
+  SetupMachineFunction(MF);
 
-  if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
+  // Get the mangled name.
+  const Function *F = MF.getFunction();
+  CurrentFnName = Mang->getValueName(F);
 
-  if (ACPV->getPCAdjustment() != 0) {
-    O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
-      << utostr(ACPV->getLabelId())
-      << "+" << (unsigned)ACPV->getPCAdjustment();
+  // Emit the function frame (args and temps).
+  EmitFunctionFrame(MF);
 
-    if (ACPV->mustAddCurrentAddress())
-      O << "-.";
+  DbgInfo.BeginFunction(MF);
 
-    O << ")";
-  }
-  O << "\n";
+  // Emit the autos section of function.
+  EmitAutos(CurrentFnName);
 
-  // If the constant pool value is a extern weak symbol, remember to emit
-  // the weak reference.
-  if (GV && GV->hasExternalWeakLinkage())
-    ExtWeakSymbols.insert(GV);
-}
+  // 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);
 
-/// 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++;
-    }
-  }
-  SwitchToTextSection(CurrentFnName.c_str(), F);  
-  O << "_" << CurrentFnName << ":" ; 
-  O << "\n";
-}
+  // 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 function start label.
+  O << CurrentFnName << ":\n";
 
-/// runOnMachineFunction - This uses the printInstruction()
-/// method to print assembly for each instruction.
-///
-bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) 
-{
-  SetupMachineFunction(MF);
-  O << "\n";
-
-  // What's my mangled name?
-  CurrentFnName = Mang->getValueName(MF.getFunction());
-
-  // Emit the function start directives
-  emitFunctionStart(MF);
-
+  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);
 
-  // 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) 
-{
+/// 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,
+                                               bool verbose) {
+  return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
+}
+
+
+// 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()) {
     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;
+        LLVM_UNREACHABLE("not implemented");
+      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();
-      break;
-
-    case MachineOperand::MO_ExternalSymbol: 
-      O << MO.getSymbolName();
-      break;
-
-    case MachineOperand::MO_ConstantPoolIndex:
-      O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-        << '_' << MO.getIndex();
+    case MachineOperand::MO_GlobalAddress: {
+      O << Mang->getValueName(MO.getGlobal());
       break;
+    }
+    case MachineOperand::MO_ExternalSymbol: {
+       const char *Sname = MO.getSymbolName();
 
-    case MachineOperand::MO_FrameIndex:
-      O << "_" << CurrentFnName 
-        << '+' << MO.getIndex();
-      break;
+      // If its a libcall name, record it to decls section.
+      if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
+        LibcallDecls.push_back(Sname);
+      }
 
-    case MachineOperand::MO_JumpTableIndex:
-      O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-        << '_' << MO.getIndex();
+      O  << Sname;
       break;
+    }
+    case MachineOperand::MO_MachineBasicBlock:
+      printBasicBlockLabel(MO.getMBB());
+      return;
 
     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!");
-  
-  O << (unsigned) V;
+/// 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 rotated 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++) {
+    std::string Name = Mang->getValueName(I);
+    if (Name.compare("@abort") == 0)
+      continue;
+    
+    // If it is llvm intrinsic call then don't emit
+    if (Name.find("llvm.") != std::string::npos)
+      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;
+
+  O << "\n" << TAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
+  for (unsigned j = 0; j < Items.size(); j++) {
+    O << TAI->getExternDirective() << Mang->getValueName(Items[j]) << "\n";
+  }
+  O << TAI->getCommentString() << "Imported Variables - END" << "\n";
+}
 
-void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) 
+// Emit variables defined in this module and are available to other modules.
+void PIC16AsmPrinter::EmitDefinedVars (Module &M)
 {
-  O << "{";
-  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
-    printOperand(MI, i);
-    if (i != e-1) O << ", ";
+  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->getValueName(Items[j]) << "\n";
   }
-  O << "}";
+  O <<  TAI->getCommentString() << "Exported Variables - END" << "\n";
 }
 
-void PIC16AsmPrinter::
-printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier) 
+// Emit initialized data placed in ROM.
+void PIC16AsmPrinter::EmitRomData (Module &M)
 {
-  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);
+  // Print ROM Data section.
+  std::vector <PIC16Section *>ROSections = PTAI->ROSections;
+  for (unsigned i = 0; i < ROSections.size(); i++) {
+    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->getValueName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      int AddrSpace = Items[j]->getType()->getAddressSpace();
+      EmitGlobalConstant(C, AddrSpace);
     }
   }
 }
 
-
-bool PIC16AsmPrinter::doInitialization(Module &M) 
-{
-  bool Result = AsmPrinter::doInitialization(M);
+bool PIC16AsmPrinter::doFinalization(Module &M) {
+  printLibcallDecls();
+  EmitRemainingAutos();
+  DbgInfo.EndModule(M);
+  O << "\n\t" << "END\n";
+  bool Result = AsmPrinter::doFinalization(M);
   return Result;
 }
 
-bool PIC16AsmPrinter::doFinalization(Module &M) 
-{
+void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
+  const Function *F = MF.getFunction();
+  std::string FuncName = Mang->getValueName(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";
 
-    if (EmitSpecialLLVMGlobal(I)) {
-      continue;
-    }
+  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);
+   }
+
+  O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
+
+  // Emit temporary space
+  int TempSize = PTLI->GetTmpSize();
+  if (TempSize > 0 )
+    O << PAN::getTempdataLabel(CurrentFnName) << " RES  " << TempSize <<"\n";
+}
 
-    std::string name = Mang->getValueName(I);
-    Constant *C = I->getInitializer();
-    const Type *Ty = C->getType();
-    unsigned Size = TD->getABITypeSize(Ty);
-    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::EmitIData (Module &M) {
 
-      if (!I->hasSection() &&
-          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-           I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
-        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 IDATA sections.
+  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->getValueName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      int AddrSpace = Items[j]->getType()->getAddressSpace();
+      O << Name;
+      EmitGlobalConstant(C, AddrSpace);
     }
+  }
+}
 
-    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;
-        }
-      }
-      break;
-
-    default:
-      assert(0 && "Unknown linkage type!");
-      break;
-    } // end switch.
+void PIC16AsmPrinter::EmitUData (Module &M) {
+  const TargetData *TD = TM.getTargetData();
 
-    EmitAlignment(Align, I);
-    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
-      << "\n";
+  // Print all BSS sections.
+  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->getValueName(Items[j]);
+      Constant *C = Items[j]->getInitializer();
+      const Type *Ty = C->getType();
+      unsigned Size = TD->getTypeAllocSize(Ty);
+
+      O << Name << " " <<"RES"<< " " << Size ;
+      O << "\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);
+void PIC16AsmPrinter::EmitAutos (std::string FunctName)
+{
+  // Section names for all globals are already set.
 
-    EmitGlobalConstant(C);
-    O << '\n';
-  } // end for.
+  const TargetData *TD = TM.getTargetData();
 
-  O << "\n "<< "END";
-  return AsmPrinter::doFinalization(M);
+  // Now print Autos section for this function.
+  std::string SectionName = PAN::getAutosSectionName(FunctName);
+  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_);
+      std::vector<const GlobalVariable*> Items = AutosSections[i]->Items;
+      for (unsigned j = 0; j < Items.size(); j++) {
+        std::string VarName = Mang->getValueName(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;
+    }
+  }
 }
 
-void PIC16AsmPrinter::
-SwitchToTextSection(const char *NewSection, const GlobalValue *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()
 {
-  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);
-}
+  const TargetData *TD = TM.getTargetData();
 
-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);
+  // 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;
+
+    // Set status as printed
+    AutosSections[i]->setPrintedStatus(true);
+
+    O << "\n";
+    SwitchToSection(AutosSections[i]->S_);
+    std::vector<const GlobalVariable*> Items = AutosSections[i]->Items;
+    for (unsigned j = 0; j < Items.size(); j++) {
+      std::string VarName = Mang->getValueName(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";
     }
-    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);
-}