| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 1 | //===-- PIC16AsmPrinter.cpp - PIC16 LLVM assembly writer ------------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This file contains a printer that converts from our internal representation | 
 | 11 | // of machine-dependent LLVM code to PIC16 assembly language. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 15 | #include "PIC16AsmPrinter.h" | 
 | 16 | #include "PIC16TargetAsmInfo.h" | 
| Owen Anderson | cb37188 | 2008-08-21 00:14:44 +0000 | [diff] [blame] | 17 | #include "llvm/Support/raw_ostream.h" | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 18 | #include "llvm/Support/Mangler.h" | 
 | 19 | #include "llvm/Function.h" | 
 | 20 | #include "llvm/Module.h" | 
 | 21 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
 | 22 | #include "llvm/DerivedTypes.h" | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 23 |  | 
 | 24 | using namespace llvm; | 
 | 25 |  | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 26 | #include "PIC16GenAsmWriter.inc" | 
 | 27 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 28 | bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { | 
 | 29 |   std::string NewBankselLabel; | 
 | 30 |   unsigned Operands = MI->getNumOperands(); | 
 | 31 |   if (Operands > 1) { | 
 | 32 |     // Global address or external symbol should be second operand from last | 
 | 33 |     // if we want to print banksel for it. | 
 | 34 |     const MachineOperand &Op = MI->getOperand(Operands-2); | 
 | 35 |     unsigned OpType = Op.getType(); | 
 | 36 |     if (OpType == MachineOperand::MO_GlobalAddress || | 
 | 37 |         OpType == MachineOperand::MO_ExternalSymbol) {  | 
 | 38 |       if (OpType == MachineOperand::MO_GlobalAddress )  | 
 | 39 |         NewBankselLabel =  Mang->getValueName(Op.getGlobal()); | 
 | 40 |       else  | 
 | 41 |         NewBankselLabel =  Op.getSymbolName(); | 
 | 42 |  | 
 | 43 |       // Operand after global address or external symbol should be  banksel. | 
 | 44 |       // Value 1 for this operand means we need to generate banksel else do not | 
 | 45 |       // generate banksel. | 
 | 46 |       const MachineOperand &BS = MI->getOperand(Operands-1); | 
 | 47 |       if (((int)BS.getImm() == 1) && | 
 | 48 |           (strcmp (CurrentBankselLabelInBasicBlock.c_str(), | 
 | 49 |                    NewBankselLabel.c_str()))) { | 
 | 50 |         CurrentBankselLabelInBasicBlock = NewBankselLabel; | 
 | 51 |         O << "\tbanksel "; | 
 | 52 |         printOperand(MI, Operands-2); | 
 | 53 |         O << "\n"; | 
 | 54 |       } | 
 | 55 |     } | 
 | 56 |   } | 
 | 57 |   printInstruction(MI); | 
 | 58 |   return true; | 
 | 59 | } | 
 | 60 |  | 
 | 61 | /// runOnMachineFunction - This uses the printInstruction() | 
 | 62 | /// method to print assembly for each instruction. | 
 | 63 | /// | 
 | 64 | bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { | 
 | 65 |   // This calls the base class function required to be called at beginning | 
 | 66 |   // of runOnMachineFunction. | 
 | 67 |   SetupMachineFunction(MF); | 
 | 68 |  | 
 | 69 |   // Get the mangled name. | 
 | 70 |   const Function *F = MF.getFunction(); | 
 | 71 |   CurrentFnName = Mang->getValueName(F); | 
 | 72 |  | 
 | 73 |   // Emit the function variables. | 
 | 74 |   emitFunctionData(MF); | 
 | 75 |   std::string codeSection; | 
 | 76 |   codeSection = "code." + CurrentFnName + ".#"; | 
 | 77 |   O <<  "\n"; | 
 | 78 |   SwitchToTextSection (codeSection.c_str(),F); | 
 | 79 |  | 
 | 80 |   // Print out code for the function. | 
 | 81 |   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); | 
 | 82 |        I != E; ++I) { | 
 | 83 |     // Print a label for the basic block. | 
 | 84 |     if (I != MF.begin()) { | 
 | 85 |       printBasicBlockLabel(I, true); | 
 | 86 |       O << '\n'; | 
 | 87 |     } | 
 | 88 |     else | 
 | 89 |       O << "_" << CurrentFnName << ":\n"; | 
 | 90 |     CurrentBankselLabelInBasicBlock = ""; | 
 | 91 |     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); | 
 | 92 |          II != E; ++II) { | 
 | 93 |       // Print the assembly for the instruction. | 
 | 94 |         printMachineInstruction(II); | 
 | 95 |     } | 
 | 96 |   } | 
 | 97 |   return false;  // we didn't modify anything. | 
 | 98 | } | 
 | 99 |  | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 100 | /// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 | 
 | 101 | /// assembly code for a MachineFunction to the given output stream, | 
 | 102 | /// using the given target machine description.  This should work | 
 | 103 | /// regardless of whether the function is in SSA form. | 
 | 104 | /// | 
| Owen Anderson | cb37188 | 2008-08-21 00:14:44 +0000 | [diff] [blame] | 105 | FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 106 |                                                PIC16TargetMachine &tm) { | 
 | 107 |   return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo()); | 
 | 108 | } | 
 | 109 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 110 | void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 111 |   const MachineOperand &MO = MI->getOperand(opNum); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 112 |  | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 113 |   switch (MO.getType()) { | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 114 |     case MachineOperand::MO_Register: | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 115 |       if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 116 |         O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 117 |       else | 
 | 118 |         assert(0 && "not implemented"); | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 119 |         return; | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 120 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 121 |     case MachineOperand::MO_Immediate: | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 122 |       O << (int)MO.getImm(); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 123 |       return; | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 124 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 125 |     case MachineOperand::MO_GlobalAddress: | 
 | 126 |       O << Mang->getValueName(MO.getGlobal()); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 127 |       break; | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 128 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 129 |     case MachineOperand::MO_ExternalSymbol: | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 130 |       O << MO.getSymbolName(); | 
 | 131 |       break; | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 132 |  | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 133 |     default: | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 134 |       assert(0 && " Operand type not supported."); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 135 |   } | 
 | 136 | } | 
 | 137 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 138 | bool PIC16AsmPrinter::doInitialization (Module &M) { | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 139 |   bool Result = AsmPrinter::doInitialization(M); | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 140 |   // FIXME:: This is temporary solution to generate the include file. | 
 | 141 |   // The processor should be passed to llc as in input and the header file | 
 | 142 |   // should be generated accordingly. | 
 | 143 |   O << "\t#include P16F1937.INC\n"; | 
 | 144 |  | 
 | 145 |   EmitInitData (M); | 
 | 146 |   EmitUnInitData(M); | 
 | 147 |   EmitRomData(M); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 148 |   return Result; | 
 | 149 | } | 
 | 150 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 151 | void PIC16AsmPrinter::EmitInitData (Module &M) | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 152 | { | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 153 |   std::string iDataSection = "idata.#"; | 
 | 154 |   SwitchToDataSection(iDataSection.c_str()); | 
 | 155 |   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); | 
 | 156 |        I != E; ++I) { | 
 | 157 |     if (!I->hasInitializer())   // External global require no code. | 
 | 158 |       continue; | 
 | 159 |  | 
 | 160 |     Constant *C = I->getInitializer(); | 
 | 161 |     const PointerType *PtrTy = I->getType(); | 
 | 162 |     int AddrSpace = PtrTy->getAddressSpace(); | 
 | 163 |  | 
 | 164 |     if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::RAM_SPACE)) { | 
 | 165 |      | 
 | 166 |       if (EmitSpecialLLVMGlobal(I))  | 
 | 167 |         continue; | 
 | 168 |  | 
 | 169 |       // Any variables reaching here with "." in its name is a local scope | 
 | 170 |       // variable and should not be printed in global data section. | 
 | 171 |       std::string name = Mang->getValueName(I); | 
 | 172 |       if (name.find(".") != std::string::npos) | 
 | 173 |         continue; | 
 | 174 |  | 
 | 175 |       O << name; | 
 | 176 |       EmitGlobalConstant(C); | 
 | 177 |     } | 
 | 178 |   } | 
 | 179 | } | 
 | 180 |  | 
 | 181 | void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) { | 
 | 182 |   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { | 
 | 183 |     unsigned BitWidth = CI->getBitWidth(); | 
 | 184 |     int Val = CI->getZExtValue(); | 
 | 185 |     if (BitWidth == 8) { | 
 | 186 |       // Expecting db directive here. In case of romdata we need to pad the | 
 | 187 |       // word with zeros. | 
 | 188 |       if (IsRomData) | 
 | 189 |         O << 0 <<", "; | 
 | 190 |       O << Val;  | 
 | 191 |     } | 
 | 192 |     else if (BitWidth == 16) { | 
 | 193 |       unsigned Element1, Element2; | 
 | 194 |       Element1 = 0x00ff & Val; | 
 | 195 |       Element2 = 0x00ff & (Val >> 8); | 
 | 196 |       if (IsRomData) | 
 | 197 |         O << 0 <<", "<<Element1 <<", "<< 0 <<", "<< Element2; | 
 | 198 |       else | 
 | 199 |         O << Element1 <<", "<< Element2;   | 
 | 200 |     } | 
 | 201 |     else if (BitWidth == 32) { | 
 | 202 |       unsigned Element1, Element2, Element3, Element4; | 
 | 203 |       Element1 = 0x00ff & Val; | 
 | 204 |       Element2 = 0x00ff & (Val >> 8); | 
 | 205 |       Element3 = 0x00ff & (Val >> 16); | 
 | 206 |       Element4 = 0x00ff & (Val >> 24); | 
 | 207 |       if (IsRomData) | 
 | 208 |         O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0  | 
 | 209 |           <<", "<< Element3 <<", "<< 0 <<", "<< Element4; | 
 | 210 |       else  | 
 | 211 |         O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4;     | 
 | 212 |     } | 
 | 213 |     return; | 
 | 214 |   } | 
 | 215 |   AsmPrinter::EmitConstantValueOnly(CV); | 
 | 216 | } | 
 | 217 |  | 
 | 218 | void PIC16AsmPrinter::EmitRomData (Module &M) | 
 | 219 | { | 
 | 220 |   std::string romDataSection = "romdata.#"; | 
 | 221 |   SwitchToRomDataSection(romDataSection.c_str()); | 
 | 222 |   IsRomData = true; | 
 | 223 |   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); | 
 | 224 |        I != E; ++I) { | 
 | 225 |     if (!I->hasInitializer())   // External global require no code. | 
 | 226 |       continue; | 
 | 227 |  | 
 | 228 |     Constant *C = I->getInitializer(); | 
 | 229 |     const PointerType *PtrTy = I->getType(); | 
 | 230 |     int AddrSpace = PtrTy->getAddressSpace(); | 
 | 231 |     if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) { | 
 | 232 |  | 
 | 233 |       if (EmitSpecialLLVMGlobal(I)) | 
 | 234 |         continue; | 
 | 235 |  | 
 | 236 |       // Any variables reaching here with "." in its name is a local scope | 
 | 237 |       // variable and should not be printed in global data section. | 
 | 238 |       std::string name = Mang->getValueName(I); | 
 | 239 |       if (name.find(".") != std::string::npos) | 
 | 240 |         continue; | 
 | 241 |  | 
 | 242 |       O << name; | 
 | 243 |       EmitGlobalConstant(C); | 
 | 244 |       O << "\n"; | 
 | 245 |     } | 
 | 246 |   } | 
 | 247 |   IsRomData = false; | 
 | 248 | } | 
 | 249 |  | 
 | 250 |  | 
 | 251 | void PIC16AsmPrinter::EmitUnInitData (Module &M) | 
 | 252 | { | 
 | 253 |   std::string uDataSection = "udata.#"; | 
 | 254 |   SwitchToUDataSection(uDataSection.c_str()); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 255 |   const TargetData *TD = TM.getTargetData(); | 
 | 256 |  | 
 | 257 |   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); | 
 | 258 |        I != E; ++I) { | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 259 |     if (!I->hasInitializer())   // External global require no code. | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 260 |       continue; | 
 | 261 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 262 |     Constant *C = I->getInitializer(); | 
 | 263 |     if (C->isNullValue()) { | 
 | 264 |  | 
 | 265 |       if (EmitSpecialLLVMGlobal(I)) | 
 | 266 |         continue; | 
 | 267 |  | 
 | 268 |       // Any variables reaching here with "." in its name is a local scope | 
 | 269 |       // variable and should not be printed in global data section. | 
 | 270 |       std::string name = Mang->getValueName(I); | 
 | 271 |       if (name.find(".") != std::string::npos) | 
 | 272 |         continue; | 
 | 273 |  | 
 | 274 |       const Type *Ty = C->getType(); | 
 | 275 |       unsigned Size = TD->getABITypeSize(Ty); | 
 | 276 |       O << name << " " <<"RES"<< " " << Size ; | 
 | 277 |       O << "\n"; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 278 |     } | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 279 |   } | 
 | 280 | } | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 281 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 282 | bool PIC16AsmPrinter::doFinalization(Module &M) { | 
 | 283 |   O << "\t" << "END\n"; | 
 | 284 |   bool Result = AsmPrinter::doFinalization(M); | 
 | 285 |   return Result; | 
 | 286 | } | 
 | 287 |  | 
 | 288 | void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { | 
 | 289 |   const Function *F = MF.getFunction(); | 
 | 290 |   std::string FuncName = Mang->getValueName(F); | 
 | 291 |   const Module *M = F->getParent(); | 
 | 292 |   const TargetData *TD = TM.getTargetData(); | 
 | 293 |  | 
 | 294 |   // Emit the data section name. | 
 | 295 |   O << "\n";  | 
 | 296 |   std::string fDataSection = "fdata." + CurrentFnName + ".#"; | 
 | 297 |   SwitchToUDataSection(fDataSection.c_str(), F); | 
 | 298 |   // Emit the label for data section of current function. | 
 | 299 |   O << "_frame_" << CurrentFnName << ":" ; | 
 | 300 |   O << "\n"; | 
 | 301 |  | 
 | 302 |   // Emit the function variables.  | 
 | 303 |     | 
 | 304 |   if (F->hasExternalLinkage()) { | 
 | 305 |     O << "\t" << "GLOBAL _frame_"  << CurrentFnName << "\n"; | 
 | 306 |     O << "\t" << "GLOBAL _"  << CurrentFnName << "\n"; | 
 | 307 |   } | 
 | 308 |   // In PIC16 all the function arguments and local variables are global. | 
 | 309 |   // Therefore to get the variable belonging to this function entire | 
 | 310 |   // global list will be traversed and variables belonging to this function | 
 | 311 |   // will be emitted in the current data section. | 
 | 312 |   for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); | 
 | 313 |        I != E; ++I) { | 
 | 314 |     std::string VarName = Mang->getValueName(I); | 
 | 315 |      | 
 | 316 |     // The variables of a function are of form FuncName.* . If this variable | 
 | 317 |     // does not belong to this function then continue.  | 
 | 318 |     if (!(VarName.find(FuncName + ".") == 0 ? true : false)) | 
 | 319 |       continue; | 
 | 320 |     | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 321 |     Constant *C = I->getInitializer(); | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 322 |     const Type *Ty = C->getType(); | 
 | 323 |     unsigned Size = TD->getABITypeSize(Ty); | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 324 |     // Emit memory reserve directive. | 
 | 325 |     O << VarName << "  RES  " << Size << "\n"; | 
 | 326 |   } | 
 | 327 |   emitFunctionTempData(MF); | 
 | 328 | } | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 329 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 330 | void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF) { | 
 | 331 |   // Emit temporary variables. | 
 | 332 |   MachineFrameInfo *FrameInfo = MF.getFrameInfo(); | 
 | 333 |   if (FrameInfo->hasStackObjects()) { | 
 | 334 |     int indexBegin = FrameInfo->getObjectIndexBegin(); | 
 | 335 |     int indexEnd = FrameInfo->getObjectIndexEnd(); | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 336 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 337 |     if (indexBegin < indexEnd) | 
 | 338 |       O << CurrentFnName << ".tmp RES"<< " "  | 
 | 339 |         <<indexEnd - indexBegin <<"\n"; | 
 | 340 |     /* | 
 | 341 |     while (indexBegin < indexEnd) { | 
 | 342 |         O << CurrentFnName << "_tmp_" << indexBegin << " " << "RES"<< " "  | 
 | 343 |           << 1 << "\n" ; | 
 | 344 |         indexBegin++; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 345 |     } | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 346 |     */ | 
 | 347 |   } | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 348 | } | 
 | 349 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 350 | /// The function is same as AsmPrinter::SwitchtoDataSection except the call | 
 | 351 | /// to getUDataSectionStartSuffix. | 
 | 352 | void PIC16AsmPrinter::SwitchToUDataSection(const char *NewSection, | 
 | 353 |                                            const GlobalValue *GV) { | 
 | 354 |   std::string NS; | 
 | 355 |   if (GV && GV->hasSection()) | 
 | 356 |     NS = TAI->getSwitchToSectionDirective() + GV->getSection(); | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 357 |   else | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 358 |     NS = NewSection; | 
 | 359 |  | 
 | 360 |   // If we're already in this section, we're done. | 
 | 361 |   if (CurrentSection == NS) return; | 
 | 362 |  | 
 | 363 |   // Close the current section, if applicable. | 
 | 364 |   if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) | 
 | 365 |     O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; | 
 | 366 |  | 
 | 367 |   CurrentSection = NS; | 
 | 368 |  | 
 | 369 |   if (!CurrentSection.empty()){} | 
 | 370 |     O << CurrentSection << (static_cast<const PIC16TargetAsmInfo *>(TAI))-> | 
 | 371 |                             getUDataSectionStartSuffix() << '\n'; | 
 | 372 |  | 
 | 373 |   IsInTextSection = false; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 374 | } | 
 | 375 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 376 | /// The function is same as AsmPrinter::SwitchtoDataSection except the call | 
 | 377 | /// to getRomDataSectionStartSuffix. | 
 | 378 | void PIC16AsmPrinter::SwitchToRomDataSection(const char *NewSection, | 
 | 379 |                                              const GlobalValue *GV) { | 
 | 380 |   std::string NS; | 
 | 381 |   if (GV && GV->hasSection()) | 
 | 382 |     NS = TAI->getSwitchToSectionDirective() + GV->getSection(); | 
| Sanjiv Gupta | 2010b3e | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 383 |   else | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 384 |     NS = NewSection; | 
 | 385 |  | 
 | 386 |   // If we're already in this section, we're done. | 
 | 387 |   if (CurrentSection == NS) return; | 
 | 388 |  | 
 | 389 |   // Close the current section, if applicable. | 
 | 390 |   if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) | 
 | 391 |     O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; | 
 | 392 |  | 
 | 393 |   CurrentSection = NS; | 
 | 394 |  | 
 | 395 |   if (!CurrentSection.empty()) {} | 
 | 396 |     O << CurrentSection << (static_cast< const PIC16TargetAsmInfo *>(TAI))-> | 
 | 397 |                             getRomDataSectionStartSuffix() << '\n'; | 
 | 398 |  | 
 | 399 |   IsInTextSection = false; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 400 | } | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame^] | 401 |  |