1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
62 static int labelOffset=0;
63 static int debug_verbose=1;
65 unsigned int pic14aopLiteral (value *val, int offset);
67 /* this is the down and dirty file with all kinds of
68 kludgy & hacky stuff. This is what it is all about
69 CODE GENERATION for a specific MCU . some of the
70 routines may be reusable, will have to see */
72 static char *zero = "#0x00";
73 static char *one = "#0x01";
74 static char *spname = "sp";
76 char *fReturnpic14[] = {"FSR","dph","b","a" };
77 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
78 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
79 static char **fReturn = fReturnpic14;
81 static char *accUse[] = {"a","b"};
83 //static short rbank = -1;
95 char *Safe_strdup(char *str); // in pcode.c
97 extern int pic14_ptrRegReq ;
98 extern int pic14_nRegs;
99 extern FILE *codeOutFile;
100 static void saverbank (int, iCode *,bool);
102 static lineNode *lineHead = NULL;
103 static lineNode *lineCurr = NULL;
105 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
106 0xE0, 0xC0, 0x80, 0x00};
107 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
108 0x07, 0x03, 0x01, 0x00};
112 /*-----------------------------------------------------------------*/
113 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
114 /* exponent of 2 is returned, otherwise -1 is */
116 /* note that this is similar to the function `powof2' in SDCCsymt */
120 /*-----------------------------------------------------------------*/
121 static int my_powof2 (unsigned long num)
124 if( (num & (num-1)) == 0) {
137 static void emitpLabel(int key)
139 addpCode2pBlock(pb,newpCodeLabel(key));
142 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
145 addpCode2pBlock(pb,newpCode(poc,pcop));
148 /*-----------------------------------------------------------------*/
149 /* pic14_emitcode - writes the code into a file : for now it is simple */
150 /*-----------------------------------------------------------------*/
151 void pic14_emitcode (char *inst,char *fmt, ...)
154 char lb[INITIAL_INLINEASM];
161 sprintf(lb,"%s\t",inst);
163 sprintf(lb,"%s",inst);
164 vsprintf(lb+(strlen(lb)),fmt,ap);
168 while (isspace(*lbp)) lbp++;
171 lineCurr = (lineCurr ?
172 connectLine(lineCurr,newLineNode(lb)) :
173 (lineHead = newLineNode(lb)));
174 lineCurr->isInline = _G.inLine;
175 lineCurr->isDebug = _G.debugLine;
178 addpCode2pBlock(pb,newpCodeCharP(lb));
183 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
186 char lb[INITIAL_INLINEASM];
196 sprintf(lb,"%s\t",inst);
198 sprintf(lb,"%s",inst);
199 vsprintf(lb+(strlen(lb)),fmt,ap);
203 while (isspace(*lbp)) lbp++;
206 lineCurr = (lineCurr ?
207 connectLine(lineCurr,newLineNode(lb)) :
208 (lineHead = newLineNode(lb)));
209 lineCurr->isInline = _G.inLine;
210 lineCurr->isDebug = _G.debugLine;
212 addpCode2pBlock(pb,newpCodeCharP(lb));
218 /*-----------------------------------------------------------------*/
219 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
220 /*-----------------------------------------------------------------*/
221 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
223 bool r0iu = FALSE , r1iu = FALSE;
224 bool r0ou = FALSE , r1ou = FALSE;
226 /* the logic: if r0 & r1 used in the instruction
227 then we are in trouble otherwise */
229 /* first check if r0 & r1 are used by this
230 instruction, in which case we are in trouble */
231 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
232 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
237 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
238 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
240 /* if no usage of r0 then return it */
241 if (!r0iu && !r0ou) {
242 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
243 (*aopp)->type = AOP_R0;
245 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
248 /* if no usage of r1 then return it */
249 if (!r1iu && !r1ou) {
250 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
251 (*aopp)->type = AOP_R1;
253 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
256 /* now we know they both have usage */
257 /* if r0 not used in this instruction */
259 /* push it if not already pushed */
261 pic14_emitcode ("push","%s",
262 pic14_regWithIdx(R0_IDX)->dname);
266 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
267 (*aopp)->type = AOP_R0;
269 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
272 /* if r1 not used then */
275 /* push it if not already pushed */
277 pic14_emitcode ("push","%s",
278 pic14_regWithIdx(R1_IDX)->dname);
282 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
283 (*aopp)->type = AOP_R1;
284 return pic14_regWithIdx(R1_IDX);
288 /* I said end of world but not quite end of world yet */
289 /* if this is a result then we can push it on the stack*/
291 (*aopp)->type = AOP_STK;
295 /* other wise this is true end of the world */
296 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
297 "getFreePtr should never reach here");
301 /*-----------------------------------------------------------------*/
302 /* newAsmop - creates a new asmOp */
303 /*-----------------------------------------------------------------*/
304 asmop *newAsmop (short type)
308 aop = Safe_calloc(1,sizeof(asmop));
313 static void genSetDPTR(int n)
317 pic14_emitcode(";", "Select standard DPTR");
318 pic14_emitcode("mov", "dps, #0x00");
322 pic14_emitcode(";", "Select alternate DPTR");
323 pic14_emitcode("mov", "dps, #0x01");
327 /*-----------------------------------------------------------------*/
328 /* pointerCode - returns the code for a pointer type */
329 /*-----------------------------------------------------------------*/
330 static int pointerCode (sym_link *etype)
333 return PTR_TYPE(SPEC_OCLS(etype));
337 /*-----------------------------------------------------------------*/
338 /* aopForSym - for a true symbol */
339 /*-----------------------------------------------------------------*/
340 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
343 memmap *space= SPEC_OCLS(sym->etype);
345 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
346 /* if already has one */
350 /* assign depending on the storage class */
351 /* if it is on the stack or indirectly addressable */
352 /* space we need to assign either r0 or r1 to it */
353 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
354 sym->aop = aop = newAsmop(0);
355 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
356 aop->size = getSize(sym->type);
358 /* now assign the address of the variable to
359 the pointer register */
360 if (aop->type != AOP_STK) {
364 pic14_emitcode("push","acc");
366 pic14_emitcode("mov","a,_bp");
367 pic14_emitcode("add","a,#0x%02x",
369 ((char)(sym->stack - _G.nRegsSaved )) :
370 ((char)sym->stack)) & 0xff);
371 pic14_emitcode("mov","%s,a",
372 aop->aopu.aop_ptr->name);
375 pic14_emitcode("pop","acc");
377 pic14_emitcode("mov","%s,#%s",
378 aop->aopu.aop_ptr->name,
380 aop->paged = space->paged;
382 aop->aopu.aop_stk = sym->stack;
386 if (sym->onStack && options.stack10bit)
388 /* It's on the 10 bit stack, which is located in
392 //DEBUGpic14_emitcode(";","%d",__LINE__);
395 pic14_emitcode("push","acc");
397 pic14_emitcode("mov","a,_bp");
398 pic14_emitcode("add","a,#0x%02x",
400 ((char)(sym->stack - _G.nRegsSaved )) :
401 ((char)sym->stack)) & 0xff);
404 pic14_emitcode ("mov","dpx1,#0x40");
405 pic14_emitcode ("mov","dph1,#0x00");
406 pic14_emitcode ("mov","dpl1, a");
410 pic14_emitcode("pop","acc");
412 sym->aop = aop = newAsmop(AOP_DPTR2);
413 aop->size = getSize(sym->type);
417 //DEBUGpic14_emitcode(";","%d",__LINE__);
418 /* if in bit space */
419 if (IN_BITSPACE(space)) {
420 sym->aop = aop = newAsmop (AOP_CRY);
421 aop->aopu.aop_dir = sym->rname ;
422 aop->size = getSize(sym->type);
423 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
426 /* if it is in direct space */
427 if (IN_DIRSPACE(space)) {
428 sym->aop = aop = newAsmop (AOP_DIR);
429 aop->aopu.aop_dir = sym->rname ;
430 aop->size = getSize(sym->type);
431 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
435 /* special case for a function */
436 if (IS_FUNC(sym->type)) {
437 sym->aop = aop = newAsmop(AOP_IMMD);
438 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
439 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
440 strcpy(aop->aopu.aop_immd,sym->rname);
441 aop->size = FPTRSIZE;
446 /* only remaining is far space */
447 /* in which case DPTR gets the address */
448 sym->aop = aop = newAsmop(AOP_DPTR);
449 pic14_emitcode ("mov","dptr,#%s", sym->rname);
450 aop->size = getSize(sym->type);
452 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
453 /* if it is in code space */
454 if (IN_CODESPACE(space))
460 /*-----------------------------------------------------------------*/
461 /* aopForRemat - rematerialzes an object */
462 /*-----------------------------------------------------------------*/
463 static asmop *aopForRemat (symbol *sym)
465 iCode *ic = sym->rematiCode;
466 asmop *aop = newAsmop(AOP_IMMD);
468 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
471 val += (int) operandLitValue(IC_RIGHT(ic));
472 else if (ic->op == '-')
473 val -= (int) operandLitValue(IC_RIGHT(ic));
477 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
481 sprintf(buffer,"(%s %c 0x%04x)",
482 OP_SYMBOL(IC_LEFT(ic))->rname,
483 val >= 0 ? '+' : '-',
486 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
488 //DEBUGpic14_emitcode(";","%s",buffer);
489 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
490 strcpy(aop->aopu.aop_immd,buffer);
494 /*-----------------------------------------------------------------*/
495 /* regsInCommon - two operands have some registers in common */
496 /*-----------------------------------------------------------------*/
497 static bool regsInCommon (operand *op1, operand *op2)
502 /* if they have registers in common */
503 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
506 sym1 = OP_SYMBOL(op1);
507 sym2 = OP_SYMBOL(op2);
509 if (sym1->nRegs == 0 || sym2->nRegs == 0)
512 for (i = 0 ; i < sym1->nRegs ; i++) {
517 for (j = 0 ; j < sym2->nRegs ;j++ ) {
521 if (sym2->regs[j] == sym1->regs[i])
529 /*-----------------------------------------------------------------*/
530 /* operandsEqu - equivalent */
531 /*-----------------------------------------------------------------*/
532 static bool operandsEqu ( operand *op1, operand *op2)
536 /* if they not symbols */
537 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
540 sym1 = OP_SYMBOL(op1);
541 sym2 = OP_SYMBOL(op2);
543 /* if both are itemps & one is spilt
544 and the other is not then false */
545 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
546 sym1->isspilt != sym2->isspilt )
549 /* if they are the same */
553 if (strcmp(sym1->rname,sym2->rname) == 0)
557 /* if left is a tmp & right is not */
561 (sym1->usl.spillLoc == sym2))
568 (sym2->usl.spillLoc == sym1))
574 /*-----------------------------------------------------------------*/
575 /* pic14_sameRegs - two asmops have the same registers */
576 /*-----------------------------------------------------------------*/
577 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
584 if (aop1->type != AOP_REG ||
585 aop2->type != AOP_REG )
588 if (aop1->size != aop2->size )
591 for (i = 0 ; i < aop1->size ; i++ )
592 if (aop1->aopu.aop_reg[i] !=
593 aop2->aopu.aop_reg[i] )
599 /*-----------------------------------------------------------------*/
600 /* aopOp - allocates an asmop for an operand : */
601 /*-----------------------------------------------------------------*/
602 void aopOp (operand *op, iCode *ic, bool result)
611 DEBUGpic14_emitcode(";","%d",__LINE__);
612 /* if this a literal */
613 if (IS_OP_LITERAL(op)) {
614 DEBUGpic14_emitcode(";","%d",__LINE__);
615 op->aop = aop = newAsmop(AOP_LIT);
616 aop->aopu.aop_lit = op->operand.valOperand;
617 aop->size = getSize(operandType(op));
621 /* if already has a asmop then continue */
625 /* if the underlying symbol has a aop */
626 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
627 DEBUGpic14_emitcode(";","%d",__LINE__);
628 op->aop = OP_SYMBOL(op)->aop;
632 /* if this is a true symbol */
633 if (IS_TRUE_SYMOP(op)) {
634 DEBUGpic14_emitcode(";","%d",__LINE__);
635 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
639 /* this is a temporary : this has
645 e) can be a return use only */
650 /* if the type is a conditional */
651 if (sym->regType == REG_CND) {
652 DEBUGpic14_emitcode(";","%d",__LINE__);
653 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
658 /* if it is spilt then two situations
660 b) has a spill location */
661 if (sym->isspilt || sym->nRegs == 0) {
663 DEBUGpic14_emitcode(";","%d",__LINE__);
664 /* rematerialize it NOW */
666 sym->aop = op->aop = aop =
668 aop->size = getSize(sym->type);
669 DEBUGpic14_emitcode(";","%d",__LINE__);
675 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
676 aop->size = getSize(sym->type);
677 for ( i = 0 ; i < 2 ; i++ )
678 aop->aopu.aop_str[i] = accUse[i];
679 DEBUGpic14_emitcode(";","%d",__LINE__);
685 aop = op->aop = sym->aop = newAsmop(AOP_STR);
686 aop->size = getSize(sym->type);
687 for ( i = 0 ; i < fReturnSizePic ; i++ )
688 aop->aopu.aop_str[i] = fReturn[i];
689 DEBUGpic14_emitcode(";","%d",__LINE__);
693 /* else spill location */
694 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
695 sym->aop = op->aop = aop =
696 aopForSym(ic,sym->usl.spillLoc,result);
697 aop->size = getSize(sym->type);
701 /* must be in a register */
702 sym->aop = op->aop = aop = newAsmop(AOP_REG);
703 aop->size = sym->nRegs;
704 for ( i = 0 ; i < sym->nRegs ;i++)
705 aop->aopu.aop_reg[i] = sym->regs[i];
708 /*-----------------------------------------------------------------*/
709 /* freeAsmop - free up the asmop given to an operand */
710 /*----------------------------------------------------------------*/
711 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
728 /* depending on the asmop type only three cases need work AOP_RO
729 , AOP_R1 && AOP_STK */
734 pic14_emitcode ("pop","ar0");
738 bitVectUnSetBit(ic->rUsed,R0_IDX);
744 pic14_emitcode ("pop","ar1");
748 bitVectUnSetBit(ic->rUsed,R1_IDX);
754 int stk = aop->aopu.aop_stk + aop->size;
755 bitVectUnSetBit(ic->rUsed,R0_IDX);
756 bitVectUnSetBit(ic->rUsed,R1_IDX);
758 getFreePtr(ic,&aop,FALSE);
760 if (options.stack10bit)
762 /* I'm not sure what to do here yet... */
765 "*** Warning: probably generating bad code for "
766 "10 bit stack mode.\n");
770 pic14_emitcode ("mov","a,_bp");
771 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
772 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
774 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
778 pic14_emitcode("pop","acc");
779 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
781 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
784 freeAsmop(op,NULL,ic,TRUE);
786 pic14_emitcode("pop","ar0");
791 pic14_emitcode("pop","ar1");
798 /* all other cases just dealloc */
802 OP_SYMBOL(op)->aop = NULL;
803 /* if the symbol has a spill */
805 SPIL_LOC(op)->aop = NULL;
810 /*-----------------------------------------------------------------*/
811 /* aopGet - for fetching value of the aop */
812 /*-----------------------------------------------------------------*/
813 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
818 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
819 /* offset is greater than
821 if (offset > (aop->size - 1) &&
822 aop->type != AOP_LIT)
825 /* depending on type */
830 DEBUGpic14_emitcode(";","%d",__LINE__);
831 /* if we need to increment it */
832 while (offset > aop->coff) {
833 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
837 while (offset < aop->coff) {
838 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
844 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
845 return (dname ? "acc" : "a");
847 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
848 rs = Safe_calloc(1,strlen(s)+1);
854 DEBUGpic14_emitcode(";","%d",__LINE__);
855 if (aop->type == AOP_DPTR2)
860 while (offset > aop->coff) {
861 pic14_emitcode ("inc","dptr");
865 while (offset < aop->coff) {
866 pic14_emitcode("lcall","__decdptr");
872 pic14_emitcode("clr","a");
873 pic14_emitcode("movc","a,@a+dptr");
876 pic14_emitcode("movx","a,@dptr");
879 if (aop->type == AOP_DPTR2)
884 return (dname ? "acc" : "a");
888 DEBUGpic14_emitcode(";","%d",__LINE__);
890 sprintf (s,"%s",aop->aopu.aop_immd);
893 sprintf(s,"(%s >> %d)",
899 rs = Safe_calloc(1,strlen(s)+1);
905 sprintf(s,"(%s + %d)",
909 sprintf(s,"%s",aop->aopu.aop_dir);
910 rs = Safe_calloc(1,strlen(s)+1);
915 DEBUGpic14_emitcode(";","%d",__LINE__);
917 return aop->aopu.aop_reg[offset]->dname;
919 return aop->aopu.aop_reg[offset]->name;
922 pic14_emitcode(";","%d",__LINE__);
923 //pic14_emitcode("clr","a");
924 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
925 //pic14_emitcode("rlc","a") ;
926 //return (dname ? "acc" : "a");
927 return aop->aopu.aop_dir;
930 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
931 //if (!offset && dname)
933 //return aop->aopu.aop_str[offset];
934 return "AOP_accumulator_bug";
937 DEBUGpic14_emitcode(";","%d",__LINE__);
938 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
939 rs = Safe_calloc(1,strlen(s)+1);
944 DEBUGpic14_emitcode(";","%d",__LINE__);
946 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
950 return aop->aopu.aop_str[offset];
954 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
955 "aopget got unsupported aop->type");
959 /*-----------------------------------------------------------------*/
960 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
961 /*-----------------------------------------------------------------*/
962 pCodeOp *popGetLabel(unsigned int key)
964 return newpCodeOpLabel(key+100+labelOffset);
967 /*-----------------------------------------------------------------*/
968 /* popCopyReg - copy a pcode operator */
969 /*-----------------------------------------------------------------*/
970 pCodeOp *popCopyReg(pCodeOpReg *pc)
974 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
975 pcor->pcop.type = pc->pcop.type;
976 if(!(pcor->pcop.name = strdup(pc->pcop.name)))
977 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
979 pcor->rIdx = pc->rIdx;
985 /*-----------------------------------------------------------------*/
986 /* popCopy - copy a pcode operator */
987 /*-----------------------------------------------------------------*/
988 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval)
992 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
994 if(!(pcop->name = strdup(pc->pcop.name)))
995 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
996 ((pCodeOpBit *)pcop)->bit = bitval;
998 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1003 /*-----------------------------------------------------------------*/
1004 /* popGet - asm operator to pcode operator conversion */
1005 /*-----------------------------------------------------------------*/
1006 pCodeOp *popGetLit(unsigned int lit)
1009 return newpCodeOpLit(lit);
1013 /*-----------------------------------------------------------------*/
1014 /* popGet - asm operator to pcode operator conversion */
1015 /*-----------------------------------------------------------------*/
1016 pCodeOp *popGetWithString(char *str)
1022 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1026 pcop = newpCodeOp(str,PO_STR);
1031 pCodeOp *popRegFromString(char *str)
1034 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1035 pcop->type = PO_GPR_REGISTER;
1037 PCOR(pcop)->rIdx = -1;
1038 PCOR(pcop)->r = NULL;
1040 DEBUGpic14_emitcode(";","%d",__LINE__);
1041 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1046 /*-----------------------------------------------------------------*/
1047 /* popGet - asm operator to pcode operator conversion */
1048 /*-----------------------------------------------------------------*/
1049 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1056 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1057 /* offset is greater than
1060 if (offset > (aop->size - 1) &&
1061 aop->type != AOP_LIT)
1062 return NULL; //zero;
1064 /* depending on type */
1065 switch (aop->type) {
1072 DEBUGpic14_emitcode(";8051 legacy","%d",__LINE__);
1073 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1074 pcop->type = PO_SFR_REGISTER;
1076 PCOR(pcop)->rIdx = -1;
1077 PCOR(pcop)->r = NULL;
1078 // Really nasty hack to check for temporary registers
1080 pcop->name = Safe_strdup("BAD_REGISTER");
1085 DEBUGpic14_emitcode(";","%d",__LINE__);
1086 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1087 pcop->type = PO_IMMEDIATE;
1089 sprintf (s,"%s",aop->aopu.aop_immd);
1092 sprintf(s,"(%s >> %d)",
1097 aop->aopu.aop_immd);
1098 pcop->name = Safe_calloc(1,strlen(s)+1);
1099 strcpy(pcop->name,s);
1103 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1104 pcop->type = PO_DIR;
1106 sprintf(s,"(%s + %d)",
1110 sprintf(s,"%s",aop->aopu.aop_dir);
1111 pcop->name = Safe_calloc(1,strlen(s)+1);
1112 strcpy(pcop->name,s);
1117 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1119 DEBUGpic14_emitcode(";","%d",__LINE__);
1120 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1121 pcop->type = PO_GPR_REGISTER;
1122 PCOR(pcop)->rIdx = rIdx;
1123 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1124 pcop->type = PCOR(pcop)->r->pc_type;
1127 rs = aop->aopu.aop_reg[offset]->dname;
1129 rs = aop->aopu.aop_reg[offset]->name;
1131 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1137 pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
1141 DEBUGpic14_emitcode(";","%d",__LINE__);
1142 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1145 DEBUGpic14_emitcode(";","%d",__LINE__);
1147 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1148 pcop->type = PO_STR;
1150 //aop->coff = offset ;
1151 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1152 sprintf(s,"%s","acc");
1154 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1155 pcop->name = Safe_calloc(1,strlen(s)+1);
1156 strcpy(pcop->name,s);
1161 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1162 "popGet got unsupported aop->type");
1165 /*-----------------------------------------------------------------*/
1166 /* aopPut - puts a string for a aop */
1167 /*-----------------------------------------------------------------*/
1168 void aopPut (asmop *aop, char *s, int offset)
1173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1175 if (aop->size && offset > ( aop->size - 1)) {
1176 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1177 "aopPut got offset > aop->size");
1181 /* will assign value to value */
1182 /* depending on where it is ofcourse */
1183 switch (aop->type) {
1186 sprintf(d,"(%s + %d)",
1187 aop->aopu.aop_dir,offset);
1189 sprintf(d,"%s",aop->aopu.aop_dir);
1192 DEBUGpic14_emitcode(";","%d",__LINE__);
1194 pic14_emitcode("movf","%s,w",s);
1195 pic14_emitcode("movwf","%s",d);
1198 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1199 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1206 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1207 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1210 strcmp(s,"r0") == 0 ||
1211 strcmp(s,"r1") == 0 ||
1212 strcmp(s,"r2") == 0 ||
1213 strcmp(s,"r3") == 0 ||
1214 strcmp(s,"r4") == 0 ||
1215 strcmp(s,"r5") == 0 ||
1216 strcmp(s,"r6") == 0 ||
1217 strcmp(s,"r7") == 0 )
1218 pic14_emitcode("mov","%s,%s ; %d",
1219 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1224 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1226 pic14_emitcode("movwf","%s",
1227 aop->aopu.aop_reg[offset]->name);
1230 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1231 pcop->type = PO_GPR_REGISTER;
1233 PCOR(pcop)->rIdx = -1;
1234 PCOR(pcop)->r = NULL;
1236 DEBUGpic14_emitcode(";","%d",__LINE__);
1237 pcop->name = Safe_strdup(s);
1238 emitpcode(POC_MOVFW,pcop);
1240 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1248 if (aop->type == AOP_DPTR2)
1254 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1255 "aopPut writting to code space");
1259 while (offset > aop->coff) {
1261 pic14_emitcode ("inc","dptr");
1264 while (offset < aop->coff) {
1266 pic14_emitcode("lcall","__decdptr");
1271 /* if not in accumulater */
1274 pic14_emitcode ("movx","@dptr,a");
1276 if (aop->type == AOP_DPTR2)
1284 while (offset > aop->coff) {
1286 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1288 while (offset < aop->coff) {
1290 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1296 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1301 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1303 if (strcmp(s,"r0") == 0 ||
1304 strcmp(s,"r1") == 0 ||
1305 strcmp(s,"r2") == 0 ||
1306 strcmp(s,"r3") == 0 ||
1307 strcmp(s,"r4") == 0 ||
1308 strcmp(s,"r5") == 0 ||
1309 strcmp(s,"r6") == 0 ||
1310 strcmp(s,"r7") == 0 ) {
1312 sprintf(buffer,"a%s",s);
1313 pic14_emitcode("mov","@%s,%s",
1314 aop->aopu.aop_ptr->name,buffer);
1316 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1321 if (strcmp(s,"a") == 0)
1322 pic14_emitcode("push","acc");
1324 pic14_emitcode("push","%s",s);
1329 /* if bit variable */
1330 if (!aop->aopu.aop_dir) {
1331 pic14_emitcode("clr","a");
1332 pic14_emitcode("rlc","a");
1335 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1338 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1341 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1343 lbl = newiTempLabel(NULL);
1345 if (strcmp(s,"a")) {
1348 pic14_emitcode("clr","c");
1349 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1350 pic14_emitcode("cpl","c");
1351 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1352 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1359 if (strcmp(aop->aopu.aop_str[offset],s))
1360 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1365 if (!offset && (strcmp(s,"acc") == 0))
1368 if (strcmp(aop->aopu.aop_str[offset],s))
1369 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1373 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1374 "aopPut got unsupported aop->type");
1380 /*-----------------------------------------------------------------*/
1381 /* reAdjustPreg - points a register back to where it should */
1382 /*-----------------------------------------------------------------*/
1383 static void reAdjustPreg (asmop *aop)
1387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1389 if ((size = aop->size) <= 1)
1392 switch (aop->type) {
1396 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1400 if (aop->type == AOP_DPTR2)
1406 pic14_emitcode("lcall","__decdptr");
1409 if (aop->type == AOP_DPTR2)
1419 /*-----------------------------------------------------------------*/
1420 /* genNotFloat - generates not for float operations */
1421 /*-----------------------------------------------------------------*/
1422 static void genNotFloat (operand *op, operand *res)
1428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1429 /* we will put 127 in the first byte of
1431 aopPut(AOP(res),"#127",0);
1432 size = AOP_SIZE(op) - 1;
1435 l = aopGet(op->aop,offset++,FALSE,FALSE);
1439 pic14_emitcode("orl","a,%s",
1441 offset++,FALSE,FALSE));
1443 tlbl = newiTempLabel(NULL);
1445 tlbl = newiTempLabel(NULL);
1446 aopPut(res->aop,one,1);
1447 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1448 aopPut(res->aop,zero,1);
1449 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1451 size = res->aop->size - 2;
1453 /* put zeros in the rest */
1455 aopPut(res->aop,zero,offset++);
1459 /*-----------------------------------------------------------------*/
1460 /* opIsGptr: returns non-zero if the passed operand is */
1461 /* a generic pointer type. */
1462 /*-----------------------------------------------------------------*/
1463 static int opIsGptr(operand *op)
1465 sym_link *type = operandType(op);
1467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1468 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1476 /*-----------------------------------------------------------------*/
1477 /* pic14_getDataSize - get the operand data size */
1478 /*-----------------------------------------------------------------*/
1479 int pic14_getDataSize(operand *op)
1481 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1484 return AOP_SIZE(op);
1486 // tsd- in the pic port, the genptr size is 1, so this code here
1487 // fails. ( in the 8051 port, the size was 4).
1490 size = AOP_SIZE(op);
1491 if (size == GPTRSIZE)
1493 sym_link *type = operandType(op);
1494 if (IS_GENPTR(type))
1496 /* generic pointer; arithmetic operations
1497 * should ignore the high byte (pointer type).
1500 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1507 /*-----------------------------------------------------------------*/
1508 /* pic14_outAcc - output Acc */
1509 /*-----------------------------------------------------------------*/
1510 void pic14_outAcc(operand *result)
1513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1514 size = pic14_getDataSize(result);
1516 aopPut(AOP(result),"a",0);
1519 /* unsigned or positive */
1521 aopPut(AOP(result),zero,offset++);
1526 /*-----------------------------------------------------------------*/
1527 /* pic14_outBitC - output a bit C */
1528 /*-----------------------------------------------------------------*/
1529 void pic14_outBitC(operand *result)
1532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1533 /* if the result is bit */
1534 if (AOP_TYPE(result) == AOP_CRY)
1535 aopPut(AOP(result),"c",0);
1537 pic14_emitcode("clr","a ; %d", __LINE__);
1538 pic14_emitcode("rlc","a");
1539 pic14_outAcc(result);
1543 /*-----------------------------------------------------------------*/
1544 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1545 /*-----------------------------------------------------------------*/
1546 void pic14_toBoolean(operand *oper)
1548 int size = AOP_SIZE(oper) - 1;
1551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1553 if ( AOP_TYPE(oper) != AOP_ACC) {
1554 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1555 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1558 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1559 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1564 /*-----------------------------------------------------------------*/
1565 /* genNot - generate code for ! operation */
1566 /*-----------------------------------------------------------------*/
1567 static void genNot (iCode *ic)
1570 sym_link *optype = operandType(IC_LEFT(ic));
1572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1573 /* assign asmOps to operand & result */
1574 aopOp (IC_LEFT(ic),ic,FALSE);
1575 aopOp (IC_RESULT(ic),ic,TRUE);
1577 /* if in bit space then a special case */
1578 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1579 pic14_emitcode("movlw","1<<%s");
1580 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1581 //pic14_emitcode("cpl","c");
1582 //pic14_outBitC(IC_RESULT(ic));
1586 /* if type float then do float */
1587 if (IS_FLOAT(optype)) {
1588 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1592 pic14_toBoolean(IC_LEFT(ic));
1594 tlbl = newiTempLabel(NULL);
1595 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1596 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1597 pic14_outBitC(IC_RESULT(ic));
1600 /* release the aops */
1601 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1602 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1606 /*-----------------------------------------------------------------*/
1607 /* genCpl - generate code for complement */
1608 /*-----------------------------------------------------------------*/
1609 static void genCpl (iCode *ic)
1615 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1616 /* assign asmOps to operand & result */
1617 aopOp (IC_LEFT(ic),ic,FALSE);
1618 aopOp (IC_RESULT(ic),ic,TRUE);
1620 /* if both are in bit space then
1622 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1623 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1625 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1626 pic14_emitcode("cpl","c");
1627 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1631 size = AOP_SIZE(IC_RESULT(ic));
1633 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1635 pic14_emitcode("cpl","a");
1636 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1641 /* release the aops */
1642 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1643 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1646 /*-----------------------------------------------------------------*/
1647 /* genUminusFloat - unary minus for floating points */
1648 /*-----------------------------------------------------------------*/
1649 static void genUminusFloat(operand *op,operand *result)
1651 int size ,offset =0 ;
1654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1655 /* for this we just need to flip the
1656 first it then copy the rest in place */
1657 size = AOP_SIZE(op) - 1;
1658 l = aopGet(AOP(op),3,FALSE,FALSE);
1662 pic14_emitcode("cpl","acc.7");
1663 aopPut(AOP(result),"a",3);
1667 aopGet(AOP(op),offset,FALSE,FALSE),
1673 /*-----------------------------------------------------------------*/
1674 /* genUminus - unary minus code generation */
1675 /*-----------------------------------------------------------------*/
1676 static void genUminus (iCode *ic)
1679 sym_link *optype, *rtype;
1682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1684 aopOp(IC_LEFT(ic),ic,FALSE);
1685 aopOp(IC_RESULT(ic),ic,TRUE);
1687 /* if both in bit space then special
1689 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1690 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1692 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1693 pic14_emitcode("cpl","c");
1694 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1698 optype = operandType(IC_LEFT(ic));
1699 rtype = operandType(IC_RESULT(ic));
1701 /* if float then do float stuff */
1702 if (IS_FLOAT(optype)) {
1703 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1707 /* otherwise subtract from zero */
1708 size = AOP_SIZE(IC_LEFT(ic));
1712 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1713 if (!strcmp(l,"a")) {
1714 pic14_emitcode("cpl","a");
1715 pic14_emitcode("inc","a");
1717 pic14_emitcode("clr","a");
1718 pic14_emitcode("subb","a,%s",l);
1720 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1723 /* if any remaining bytes in the result */
1724 /* we just need to propagate the sign */
1725 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1726 pic14_emitcode("rlc","a");
1727 pic14_emitcode("subb","a,acc");
1729 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1733 /* release the aops */
1734 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1735 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1738 /*-----------------------------------------------------------------*/
1739 /* saveRegisters - will look for a call and save the registers */
1740 /*-----------------------------------------------------------------*/
1741 static void saveRegisters(iCode *lic)
1748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1750 for (ic = lic ; ic ; ic = ic->next)
1751 if (ic->op == CALL || ic->op == PCALL)
1755 fprintf(stderr,"found parameter push with no function call\n");
1759 /* if the registers have been saved already then
1761 if (ic->regsSaved || (OP_SYMBOL(IC_LEFT(ic))->calleeSave))
1764 /* find the registers in use at this time
1765 and push them away to safety */
1766 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1770 if (options.useXstack) {
1771 if (bitVectBitValue(rsave,R0_IDX))
1772 pic14_emitcode("mov","b,r0");
1773 pic14_emitcode("mov","r0,%s",spname);
1774 for (i = 0 ; i < pic14_nRegs ; i++) {
1775 if (bitVectBitValue(rsave,i)) {
1777 pic14_emitcode("mov","a,b");
1779 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1780 pic14_emitcode("movx","@r0,a");
1781 pic14_emitcode("inc","r0");
1784 pic14_emitcode("mov","%s,r0",spname);
1785 if (bitVectBitValue(rsave,R0_IDX))
1786 pic14_emitcode("mov","r0,b");
1788 for (i = 0 ; i < pic14_nRegs ; i++) {
1789 if (bitVectBitValue(rsave,i))
1790 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1793 detype = getSpec(operandType(IC_LEFT(ic)));
1795 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
1796 IS_ISR(currFunc->etype) &&
1799 saverbank(SPEC_BANK(detype),ic,TRUE);
1802 /*-----------------------------------------------------------------*/
1803 /* unsaveRegisters - pop the pushed registers */
1804 /*-----------------------------------------------------------------*/
1805 static void unsaveRegisters (iCode *ic)
1810 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1811 /* find the registers in use at this time
1812 and push them away to safety */
1813 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1816 if (options.useXstack) {
1817 pic14_emitcode("mov","r0,%s",spname);
1818 for (i = pic14_nRegs ; i >= 0 ; i--) {
1819 if (bitVectBitValue(rsave,i)) {
1820 pic14_emitcode("dec","r0");
1821 pic14_emitcode("movx","a,@r0");
1823 pic14_emitcode("mov","b,a");
1825 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1829 pic14_emitcode("mov","%s,r0",spname);
1830 if (bitVectBitValue(rsave,R0_IDX))
1831 pic14_emitcode("mov","r0,b");
1833 for (i = pic14_nRegs ; i >= 0 ; i--) {
1834 if (bitVectBitValue(rsave,i))
1835 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1841 /*-----------------------------------------------------------------*/
1843 /*-----------------------------------------------------------------*/
1844 static void pushSide(operand * oper, int size)
1847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1849 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1850 if (AOP_TYPE(oper) != AOP_REG &&
1851 AOP_TYPE(oper) != AOP_DIR &&
1853 pic14_emitcode("mov","a,%s",l);
1854 pic14_emitcode("push","acc");
1856 pic14_emitcode("push","%s",l);
1860 /*-----------------------------------------------------------------*/
1861 /* assignResultValue - */
1862 /*-----------------------------------------------------------------*/
1863 static void assignResultValue(operand * oper)
1866 int size = AOP_SIZE(oper);
1868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1870 // The last byte in the assignment is in W
1871 aopPut(AOP(oper),"W",size-1);
1875 aopPut(AOP(oper),fReturn[offset],offset);
1883 /*-----------------------------------------------------------------*/
1884 /* genXpush - pushes onto the external stack */
1885 /*-----------------------------------------------------------------*/
1886 static void genXpush (iCode *ic)
1888 asmop *aop = newAsmop(0);
1890 int size,offset = 0;
1892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1893 aopOp(IC_LEFT(ic),ic,FALSE);
1894 r = getFreePtr(ic,&aop,FALSE);
1897 pic14_emitcode("mov","%s,_spx",r->name);
1899 size = AOP_SIZE(IC_LEFT(ic));
1902 char *l = aopGet(AOP(IC_LEFT(ic)),
1903 offset++,FALSE,FALSE);
1905 pic14_emitcode("movx","@%s,a",r->name);
1906 pic14_emitcode("inc","%s",r->name);
1911 pic14_emitcode("mov","_spx,%s",r->name);
1913 freeAsmop(NULL,aop,ic,TRUE);
1914 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1917 /*-----------------------------------------------------------------*/
1918 /* genIpush - genrate code for pushing this gets a little complex */
1919 /*-----------------------------------------------------------------*/
1920 static void genIpush (iCode *ic)
1922 int size, offset = 0 ;
1926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1927 /* if this is not a parm push : ie. it is spill push
1928 and spill push is always done on the local stack */
1929 if (!ic->parmPush) {
1931 /* and the item is spilt then do nothing */
1932 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1935 aopOp(IC_LEFT(ic),ic,FALSE);
1936 size = AOP_SIZE(IC_LEFT(ic));
1937 /* push it on the stack */
1939 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1944 pic14_emitcode("push","%s",l);
1949 /* this is a paramter push: in this case we call
1950 the routine to find the call and save those
1951 registers that need to be saved */
1954 /* if use external stack then call the external
1955 stack pushing routine */
1956 if (options.useXstack) {
1961 /* then do the push */
1962 aopOp(IC_LEFT(ic),ic,FALSE);
1965 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
1966 size = AOP_SIZE(IC_LEFT(ic));
1969 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
1970 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
1971 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
1973 pic14_emitcode("mov","a,%s",l);
1974 pic14_emitcode("push","acc");
1976 pic14_emitcode("push","%s",l);
1979 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
1982 /*-----------------------------------------------------------------*/
1983 /* genIpop - recover the registers: can happen only for spilling */
1984 /*-----------------------------------------------------------------*/
1985 static void genIpop (iCode *ic)
1990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1991 /* if the temp was not pushed then */
1992 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
1995 aopOp(IC_LEFT(ic),ic,FALSE);
1996 size = AOP_SIZE(IC_LEFT(ic));
1999 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2002 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2005 /*-----------------------------------------------------------------*/
2006 /* unsaverbank - restores the resgister bank from stack */
2007 /*-----------------------------------------------------------------*/
2008 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2016 if (options.useXstack) {
2018 r = getFreePtr(ic,&aop,FALSE);
2021 pic14_emitcode("mov","%s,_spx",r->name);
2022 pic14_emitcode("movx","a,@%s",r->name);
2023 pic14_emitcode("mov","psw,a");
2024 pic14_emitcode("dec","%s",r->name);
2027 pic14_emitcode ("pop","psw");
2030 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2031 if (options.useXstack) {
2032 pic14_emitcode("movx","a,@%s",r->name);
2033 //pic14_emitcode("mov","(%s+%d),a",
2034 // regspic14[i].base,8*bank+regspic14[i].offset);
2035 pic14_emitcode("dec","%s",r->name);
2038 pic14_emitcode("pop",""); //"(%s+%d)",
2039 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2042 if (options.useXstack) {
2044 pic14_emitcode("mov","_spx,%s",r->name);
2045 freeAsmop(NULL,aop,ic,TRUE);
2050 /*-----------------------------------------------------------------*/
2051 /* saverbank - saves an entire register bank on the stack */
2052 /*-----------------------------------------------------------------*/
2053 static void saverbank (int bank, iCode *ic, bool pushPsw)
2059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2060 if (options.useXstack) {
2063 r = getFreePtr(ic,&aop,FALSE);
2064 pic14_emitcode("mov","%s,_spx",r->name);
2068 for (i = 0 ; i < pic14_nRegs ;i++) {
2069 if (options.useXstack) {
2070 pic14_emitcode("inc","%s",r->name);
2071 //pic14_emitcode("mov","a,(%s+%d)",
2072 // regspic14[i].base,8*bank+regspic14[i].offset);
2073 pic14_emitcode("movx","@%s,a",r->name);
2075 pic14_emitcode("push","");// "(%s+%d)",
2076 //regspic14[i].base,8*bank+regspic14[i].offset);
2080 if (options.useXstack) {
2081 pic14_emitcode("mov","a,psw");
2082 pic14_emitcode("movx","@%s,a",r->name);
2083 pic14_emitcode("inc","%s",r->name);
2084 pic14_emitcode("mov","_spx,%s",r->name);
2085 freeAsmop (NULL,aop,ic,TRUE);
2088 pic14_emitcode("push","psw");
2090 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2096 /*-----------------------------------------------------------------*/
2097 /* genCall - generates a call statement */
2098 /*-----------------------------------------------------------------*/
2099 static void genCall (iCode *ic)
2103 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2105 /* if caller saves & we have not saved then */
2109 /* if we are calling a function that is not using
2110 the same register bank then we need to save the
2111 destination registers on the stack */
2112 detype = getSpec(operandType(IC_LEFT(ic)));
2114 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)) &&
2115 IS_ISR(currFunc->etype) &&
2118 saverbank(SPEC_BANK(detype),ic,TRUE);
2120 /* if send set is not empty the assign */
2124 for (sic = setFirstItem(_G.sendSet) ; sic ;
2125 sic = setNextItem(_G.sendSet)) {
2126 int size, offset = 0;
2128 aopOp(IC_LEFT(sic),sic,FALSE);
2129 size = AOP_SIZE(IC_LEFT(sic));
2131 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2133 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2135 if (strcmp(l,fReturn[offset])) {
2137 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2138 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2139 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2140 //pic14_emitcode("movlw","%s",l);
2142 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2143 //pic14_emitcode("movf","%s,w",l);
2145 // The last one is passed in W
2147 pic14_emitcode("movwf","%s",fReturn[offset]);
2151 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2156 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2157 OP_SYMBOL(IC_LEFT(ic))->rname :
2158 OP_SYMBOL(IC_LEFT(ic))->name));
2160 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2161 OP_SYMBOL(IC_LEFT(ic))->rname :
2162 OP_SYMBOL(IC_LEFT(ic))->name));
2164 /* if we need assign a result value */
2165 if ((IS_ITEMP(IC_RESULT(ic)) &&
2166 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2167 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2168 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2171 aopOp(IC_RESULT(ic),ic,FALSE);
2174 assignResultValue(IC_RESULT(ic));
2176 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2179 /* adjust the stack for parameters if
2181 if (ic->parmBytes) {
2183 if (ic->parmBytes > 3) {
2184 pic14_emitcode("mov","a,%s",spname);
2185 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2186 pic14_emitcode("mov","%s,a",spname);
2188 for ( i = 0 ; i < ic->parmBytes ;i++)
2189 pic14_emitcode("dec","%s",spname);
2193 /* if register bank was saved then pop them */
2195 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2197 /* if we hade saved some registers then unsave them */
2198 if (ic->regsSaved && !(OP_SYMBOL(IC_LEFT(ic))->calleeSave))
2199 unsaveRegisters (ic);
2204 /*-----------------------------------------------------------------*/
2205 /* genPcall - generates a call by pointer statement */
2206 /*-----------------------------------------------------------------*/
2207 static void genPcall (iCode *ic)
2210 symbol *rlbl = newiTempLabel(NULL);
2213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2214 /* if caller saves & we have not saved then */
2218 /* if we are calling a function that is not using
2219 the same register bank then we need to save the
2220 destination registers on the stack */
2221 detype = getSpec(operandType(IC_LEFT(ic)));
2223 IS_ISR(currFunc->etype) &&
2224 (SPEC_BANK(currFunc->etype) != SPEC_BANK(detype)))
2225 saverbank(SPEC_BANK(detype),ic,TRUE);
2228 /* push the return address on to the stack */
2229 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2230 pic14_emitcode("push","acc");
2231 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2232 pic14_emitcode("push","acc");
2234 if (options.model == MODEL_FLAT24)
2236 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2237 pic14_emitcode("push","acc");
2240 /* now push the calling address */
2241 aopOp(IC_LEFT(ic),ic,FALSE);
2243 pushSide(IC_LEFT(ic), FPTRSIZE);
2245 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2247 /* if send set is not empty the assign */
2251 for (sic = setFirstItem(_G.sendSet) ; sic ;
2252 sic = setNextItem(_G.sendSet)) {
2253 int size, offset = 0;
2254 aopOp(IC_LEFT(sic),sic,FALSE);
2255 size = AOP_SIZE(IC_LEFT(sic));
2257 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2259 if (strcmp(l,fReturn[offset]))
2260 pic14_emitcode("mov","%s,%s",
2265 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2270 pic14_emitcode("ret","");
2271 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2274 /* if we need assign a result value */
2275 if ((IS_ITEMP(IC_RESULT(ic)) &&
2276 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2277 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2278 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2281 aopOp(IC_RESULT(ic),ic,FALSE);
2284 assignResultValue(IC_RESULT(ic));
2286 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2289 /* adjust the stack for parameters if
2291 if (ic->parmBytes) {
2293 if (ic->parmBytes > 3) {
2294 pic14_emitcode("mov","a,%s",spname);
2295 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2296 pic14_emitcode("mov","%s,a",spname);
2298 for ( i = 0 ; i < ic->parmBytes ;i++)
2299 pic14_emitcode("dec","%s",spname);
2303 /* if register bank was saved then unsave them */
2305 (SPEC_BANK(currFunc->etype) !=
2307 unsaverbank(SPEC_BANK(detype),ic,TRUE);
2309 /* if we hade saved some registers then
2312 unsaveRegisters (ic);
2316 /*-----------------------------------------------------------------*/
2317 /* resultRemat - result is rematerializable */
2318 /*-----------------------------------------------------------------*/
2319 static int resultRemat (iCode *ic)
2321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2322 if (SKIP_IC(ic) || ic->op == IFX)
2325 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2326 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2327 if (sym->remat && !POINTER_SET(ic))
2334 #if defined(__BORLANDC__) || defined(_MSC_VER)
2335 #define STRCASECMP stricmp
2337 #define STRCASECMP strcasecmp
2340 /*-----------------------------------------------------------------*/
2341 /* inExcludeList - return 1 if the string is in exclude Reg list */
2342 /*-----------------------------------------------------------------*/
2343 static bool inExcludeList(char *s)
2347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2348 if (options.excludeRegs[i] &&
2349 STRCASECMP(options.excludeRegs[i],"none") == 0)
2352 for ( i = 0 ; options.excludeRegs[i]; i++) {
2353 if (options.excludeRegs[i] &&
2354 STRCASECMP(s,options.excludeRegs[i]) == 0)
2360 /*-----------------------------------------------------------------*/
2361 /* genFunction - generated code for function entry */
2362 /*-----------------------------------------------------------------*/
2363 static void genFunction (iCode *ic)
2368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2369 labelOffset += FUNCTION_LABEL_INC;
2372 /* create the function header */
2373 pic14_emitcode(";","-----------------------------------------");
2374 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2375 pic14_emitcode(";","-----------------------------------------");
2377 pic14_emitcode("","%s:",sym->rname);
2378 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2380 fetype = getSpec(operandType(IC_LEFT(ic)));
2382 /* if critical function then turn interrupts off */
2383 if (SPEC_CRTCL(fetype))
2384 pic14_emitcode("clr","ea");
2386 /* here we need to generate the equates for the
2387 register bank if required */
2389 if (SPEC_BANK(fetype) != rbank) {
2392 rbank = SPEC_BANK(fetype);
2393 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2394 if (strcmp(regspic14[i].base,"0") == 0)
2395 pic14_emitcode("","%s = 0x%02x",
2397 8*rbank+regspic14[i].offset);
2399 pic14_emitcode ("","%s = %s + 0x%02x",
2402 8*rbank+regspic14[i].offset);
2407 /* if this is an interrupt service routine then
2408 save acc, b, dpl, dph */
2409 if (IS_ISR(sym->etype)) {
2411 if (!inExcludeList("acc"))
2412 pic14_emitcode ("push","acc");
2413 if (!inExcludeList("b"))
2414 pic14_emitcode ("push","b");
2415 if (!inExcludeList("dpl"))
2416 pic14_emitcode ("push","dpl");
2417 if (!inExcludeList("dph"))
2418 pic14_emitcode ("push","dph");
2419 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2421 pic14_emitcode ("push", "dpx");
2422 /* Make sure we're using standard DPTR */
2423 pic14_emitcode ("push", "dps");
2424 pic14_emitcode ("mov", "dps, #0x00");
2425 if (options.stack10bit)
2427 /* This ISR could conceivably use DPTR2. Better save it. */
2428 pic14_emitcode ("push", "dpl1");
2429 pic14_emitcode ("push", "dph1");
2430 pic14_emitcode ("push", "dpx1");
2433 /* if this isr has no bank i.e. is going to
2434 run with bank 0 , then we need to save more
2436 if (!SPEC_BANK(sym->etype)) {
2438 /* if this function does not call any other
2439 function then we can be economical and
2440 save only those registers that are used */
2441 if (! sym->hasFcall) {
2444 /* if any registers used */
2445 if (sym->regsUsed) {
2446 /* save the registers used */
2447 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2448 if (bitVectBitValue(sym->regsUsed,i) ||
2449 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2450 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2455 /* this function has a function call cannot
2456 determines register usage so we will have the
2458 saverbank(0,ic,FALSE);
2462 /* if callee-save to be used for this function
2463 then save the registers being used in this function */
2464 if (sym->calleeSave) {
2467 /* if any registers used */
2468 if (sym->regsUsed) {
2469 /* save the registers used */
2470 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2471 if (bitVectBitValue(sym->regsUsed,i) ||
2472 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2473 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2481 /* set the register bank to the desired value */
2482 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype)) {
2483 pic14_emitcode("push","psw");
2484 pic14_emitcode("mov","psw,#0x%02x",(SPEC_BANK(sym->etype) << 3)&0x00ff);
2487 if (IS_RENT(sym->etype) || options.stackAuto) {
2489 if (options.useXstack) {
2490 pic14_emitcode("mov","r0,%s",spname);
2491 pic14_emitcode("mov","a,_bp");
2492 pic14_emitcode("movx","@r0,a");
2493 pic14_emitcode("inc","%s",spname);
2497 /* set up the stack */
2498 pic14_emitcode ("push","_bp"); /* save the callers stack */
2500 pic14_emitcode ("mov","_bp,%s",spname);
2503 /* adjust the stack for the function */
2508 werror(W_STACK_OVERFLOW,sym->name);
2510 if (i > 3 && sym->recvSize < 4) {
2512 pic14_emitcode ("mov","a,sp");
2513 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2514 pic14_emitcode ("mov","sp,a");
2519 pic14_emitcode("inc","sp");
2524 pic14_emitcode ("mov","a,_spx");
2525 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2526 pic14_emitcode ("mov","_spx,a");
2531 /*-----------------------------------------------------------------*/
2532 /* genEndFunction - generates epilogue for functions */
2533 /*-----------------------------------------------------------------*/
2534 static void genEndFunction (iCode *ic)
2536 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2540 if (IS_RENT(sym->etype) || options.stackAuto)
2542 pic14_emitcode ("mov","%s,_bp",spname);
2545 /* if use external stack but some variables were
2546 added to the local stack then decrement the
2548 if (options.useXstack && sym->stack) {
2549 pic14_emitcode("mov","a,sp");
2550 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2551 pic14_emitcode("mov","sp,a");
2555 if ((IS_RENT(sym->etype) || options.stackAuto)) {
2556 if (options.useXstack) {
2557 pic14_emitcode("mov","r0,%s",spname);
2558 pic14_emitcode("movx","a,@r0");
2559 pic14_emitcode("mov","_bp,a");
2560 pic14_emitcode("dec","%s",spname);
2564 pic14_emitcode ("pop","_bp");
2568 /* restore the register bank */
2569 if (SPEC_BANK(sym->etype) || IS_ISR(sym->etype))
2570 pic14_emitcode ("pop","psw");
2572 if (IS_ISR(sym->etype)) {
2574 /* now we need to restore the registers */
2575 /* if this isr has no bank i.e. is going to
2576 run with bank 0 , then we need to save more
2578 if (!SPEC_BANK(sym->etype)) {
2580 /* if this function does not call any other
2581 function then we can be economical and
2582 save only those registers that are used */
2583 if (! sym->hasFcall) {
2586 /* if any registers used */
2587 if (sym->regsUsed) {
2588 /* save the registers used */
2589 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2590 if (bitVectBitValue(sym->regsUsed,i) ||
2591 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2592 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2597 /* this function has a function call cannot
2598 determines register usage so we will have the
2600 unsaverbank(0,ic,FALSE);
2604 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2606 if (options.stack10bit)
2608 pic14_emitcode ("pop", "dpx1");
2609 pic14_emitcode ("pop", "dph1");
2610 pic14_emitcode ("pop", "dpl1");
2612 pic14_emitcode ("pop", "dps");
2613 pic14_emitcode ("pop", "dpx");
2615 if (!inExcludeList("dph"))
2616 pic14_emitcode ("pop","dph");
2617 if (!inExcludeList("dpl"))
2618 pic14_emitcode ("pop","dpl");
2619 if (!inExcludeList("b"))
2620 pic14_emitcode ("pop","b");
2621 if (!inExcludeList("acc"))
2622 pic14_emitcode ("pop","acc");
2624 if (SPEC_CRTCL(sym->etype))
2625 pic14_emitcode("setb","ea");
2627 /* if debug then send end of function */
2628 /* if (options.debug && currFunc) { */
2631 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2632 FileBaseName(ic->filename),currFunc->lastLine,
2633 ic->level,ic->block);
2634 if (IS_STATIC(currFunc->etype))
2635 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2637 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2641 pic14_emitcode ("reti","");
2644 if (SPEC_CRTCL(sym->etype))
2645 pic14_emitcode("setb","ea");
2647 if (sym->calleeSave) {
2650 /* if any registers used */
2651 if (sym->regsUsed) {
2652 /* save the registers used */
2653 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2654 if (bitVectBitValue(sym->regsUsed,i) ||
2655 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2656 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2662 /* if debug then send end of function */
2665 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2666 FileBaseName(ic->filename),currFunc->lastLine,
2667 ic->level,ic->block);
2668 if (IS_STATIC(currFunc->etype))
2669 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2671 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2675 pic14_emitcode ("return","");
2676 emitpcode(POC_RETURN,NULL);
2678 /* Mark the end of a function */
2679 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2684 /*-----------------------------------------------------------------*/
2685 /* genRet - generate code for return statement */
2686 /*-----------------------------------------------------------------*/
2687 static void genRet (iCode *ic)
2689 int size,offset = 0 , pushed = 0;
2691 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2692 /* if we have no return value then
2693 just generate the "ret" */
2697 /* we have something to return then
2698 move the return value into place */
2699 aopOp(IC_LEFT(ic),ic,FALSE);
2700 size = AOP_SIZE(IC_LEFT(ic));
2704 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2706 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2708 pic14_emitcode("push","%s",l);
2711 l = aopGet(AOP(IC_LEFT(ic)),offset,
2713 if (strcmp(fReturn[offset],l)) {
2714 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2715 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2716 pic14_emitcode("movlw","%s",l);
2718 pic14_emitcode("movf","%s,w",l);
2720 pic14_emitcode("movwf","%s",fReturn[offset]);
2729 if (strcmp(fReturn[pushed],"a"))
2730 pic14_emitcode("pop",fReturn[pushed]);
2732 pic14_emitcode("pop","acc");
2735 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2738 /* generate a jump to the return label
2739 if the next is not the return statement */
2740 if (!(ic->next && ic->next->op == LABEL &&
2741 IC_LABEL(ic->next) == returnLabel))
2743 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2747 /*-----------------------------------------------------------------*/
2748 /* genLabel - generates a label */
2749 /*-----------------------------------------------------------------*/
2750 static void genLabel (iCode *ic)
2752 /* special case never generate */
2753 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2754 if (IC_LABEL(ic) == entryLabel)
2757 emitpLabel(IC_LABEL(ic)->key+100 + labelOffset);
2758 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2761 /*-----------------------------------------------------------------*/
2762 /* genGoto - generates a goto */
2763 /*-----------------------------------------------------------------*/
2765 static void genGoto (iCode *ic)
2767 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2770 /*-----------------------------------------------------------------*/
2771 /* findLabelBackwards: walks back through the iCode chain looking */
2772 /* for the given label. Returns number of iCode instructions */
2773 /* between that label and given ic. */
2774 /* Returns zero if label not found. */
2775 /*-----------------------------------------------------------------*/
2777 static int findLabelBackwards(iCode *ic, int key)
2781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2787 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2789 /* printf("findLabelBackwards = %d\n", count); */
2798 /*-----------------------------------------------------------------*/
2799 /* genMultbits :- multiplication of bits */
2800 /*-----------------------------------------------------------------*/
2801 static void genMultbits (operand *left,
2805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2807 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2808 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2809 pic14_outBitC(result);
2813 /*-----------------------------------------------------------------*/
2814 /* genMultOneByte : 8 bit multiplication & division */
2815 /*-----------------------------------------------------------------*/
2816 static void genMultOneByte (operand *left,
2820 sym_link *opetype = operandType(result);
2825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2826 /* (if two literals, the value is computed before) */
2827 /* if one literal, literal on the right */
2828 if (AOP_TYPE(left) == AOP_LIT){
2834 size = AOP_SIZE(result);
2835 /* signed or unsigned */
2836 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2837 l = aopGet(AOP(left),0,FALSE,FALSE);
2839 pic14_emitcode("mul","ab");
2840 /* if result size = 1, mul signed = mul unsigned */
2841 aopPut(AOP(result),"a",0);
2843 if (SPEC_USIGN(opetype)){
2844 aopPut(AOP(result),"b",1);
2846 /* for filling the MSBs */
2847 pic14_emitcode("clr","a");
2850 pic14_emitcode("mov","a,b");
2852 /* adjust the MSB if left or right neg */
2854 /* if one literal */
2855 if (AOP_TYPE(right) == AOP_LIT){
2856 /* AND literal negative */
2857 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2858 /* adjust MSB (c==0 after mul) */
2859 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2863 lbl = newiTempLabel(NULL);
2864 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2865 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2866 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2867 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2868 lbl = newiTempLabel(NULL);
2869 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2870 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2871 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2874 lbl = newiTempLabel(NULL);
2875 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2876 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2877 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2878 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2879 lbl = newiTempLabel(NULL);
2880 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2881 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2882 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2884 aopPut(AOP(result),"a",1);
2887 pic14_emitcode("rlc","a");
2888 pic14_emitcode("subb","a,acc");
2895 aopPut(AOP(result),"a",offset++);
2899 /*-----------------------------------------------------------------*/
2900 /* genMult - generates code for multiplication */
2901 /*-----------------------------------------------------------------*/
2902 static void genMult (iCode *ic)
2904 operand *left = IC_LEFT(ic);
2905 operand *right = IC_RIGHT(ic);
2906 operand *result= IC_RESULT(ic);
2908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2909 /* assign the amsops */
2910 aopOp (left,ic,FALSE);
2911 aopOp (right,ic,FALSE);
2912 aopOp (result,ic,TRUE);
2914 /* special cases first */
2916 if (AOP_TYPE(left) == AOP_CRY &&
2917 AOP_TYPE(right)== AOP_CRY) {
2918 genMultbits(left,right,result);
2922 /* if both are of size == 1 */
2923 if (AOP_SIZE(left) == 1 &&
2924 AOP_SIZE(right) == 1 ) {
2925 genMultOneByte(left,right,result);
2929 /* should have been converted to function call */
2933 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2934 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
2935 freeAsmop(result,NULL,ic,TRUE);
2938 /*-----------------------------------------------------------------*/
2939 /* genDivbits :- division of bits */
2940 /*-----------------------------------------------------------------*/
2941 static void genDivbits (operand *left,
2948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2949 /* the result must be bit */
2950 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
2951 l = aopGet(AOP(left),0,FALSE,FALSE);
2955 pic14_emitcode("div","ab");
2956 pic14_emitcode("rrc","a");
2957 aopPut(AOP(result),"c",0);
2960 /*-----------------------------------------------------------------*/
2961 /* genDivOneByte : 8 bit division */
2962 /*-----------------------------------------------------------------*/
2963 static void genDivOneByte (operand *left,
2967 sym_link *opetype = operandType(result);
2972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2973 size = AOP_SIZE(result) - 1;
2975 /* signed or unsigned */
2976 if (SPEC_USIGN(opetype)) {
2977 /* unsigned is easy */
2978 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2979 l = aopGet(AOP(left),0,FALSE,FALSE);
2981 pic14_emitcode("div","ab");
2982 aopPut(AOP(result),"a",0);
2984 aopPut(AOP(result),zero,offset++);
2988 /* signed is a little bit more difficult */
2990 /* save the signs of the operands */
2991 l = aopGet(AOP(left),0,FALSE,FALSE);
2993 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
2994 pic14_emitcode("push","acc"); /* save it on the stack */
2996 /* now sign adjust for both left & right */
2997 l = aopGet(AOP(right),0,FALSE,FALSE);
2999 lbl = newiTempLabel(NULL);
3000 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3001 pic14_emitcode("cpl","a");
3002 pic14_emitcode("inc","a");
3003 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3004 pic14_emitcode("mov","b,a");
3006 /* sign adjust left side */
3007 l = aopGet(AOP(left),0,FALSE,FALSE);
3010 lbl = newiTempLabel(NULL);
3011 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3012 pic14_emitcode("cpl","a");
3013 pic14_emitcode("inc","a");
3014 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3016 /* now the division */
3017 pic14_emitcode("div","ab");
3018 /* we are interested in the lower order
3020 pic14_emitcode("mov","b,a");
3021 lbl = newiTempLabel(NULL);
3022 pic14_emitcode("pop","acc");
3023 /* if there was an over flow we don't
3024 adjust the sign of the result */
3025 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3026 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3028 pic14_emitcode("clr","a");
3029 pic14_emitcode("subb","a,b");
3030 pic14_emitcode("mov","b,a");
3031 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3033 /* now we are done */
3034 aopPut(AOP(result),"b",0);
3036 pic14_emitcode("mov","c,b.7");
3037 pic14_emitcode("subb","a,acc");
3040 aopPut(AOP(result),"a",offset++);
3044 /*-----------------------------------------------------------------*/
3045 /* genDiv - generates code for division */
3046 /*-----------------------------------------------------------------*/
3047 static void genDiv (iCode *ic)
3049 operand *left = IC_LEFT(ic);
3050 operand *right = IC_RIGHT(ic);
3051 operand *result= IC_RESULT(ic);
3053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3054 /* assign the amsops */
3055 aopOp (left,ic,FALSE);
3056 aopOp (right,ic,FALSE);
3057 aopOp (result,ic,TRUE);
3059 /* special cases first */
3061 if (AOP_TYPE(left) == AOP_CRY &&
3062 AOP_TYPE(right)== AOP_CRY) {
3063 genDivbits(left,right,result);
3067 /* if both are of size == 1 */
3068 if (AOP_SIZE(left) == 1 &&
3069 AOP_SIZE(right) == 1 ) {
3070 genDivOneByte(left,right,result);
3074 /* should have been converted to function call */
3077 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3078 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3079 freeAsmop(result,NULL,ic,TRUE);
3082 /*-----------------------------------------------------------------*/
3083 /* genModbits :- modulus of bits */
3084 /*-----------------------------------------------------------------*/
3085 static void genModbits (operand *left,
3092 /* the result must be bit */
3093 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3094 l = aopGet(AOP(left),0,FALSE,FALSE);
3098 pic14_emitcode("div","ab");
3099 pic14_emitcode("mov","a,b");
3100 pic14_emitcode("rrc","a");
3101 aopPut(AOP(result),"c",0);
3104 /*-----------------------------------------------------------------*/
3105 /* genModOneByte : 8 bit modulus */
3106 /*-----------------------------------------------------------------*/
3107 static void genModOneByte (operand *left,
3111 sym_link *opetype = operandType(result);
3115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3116 /* signed or unsigned */
3117 if (SPEC_USIGN(opetype)) {
3118 /* unsigned is easy */
3119 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3120 l = aopGet(AOP(left),0,FALSE,FALSE);
3122 pic14_emitcode("div","ab");
3123 aopPut(AOP(result),"b",0);
3127 /* signed is a little bit more difficult */
3129 /* save the signs of the operands */
3130 l = aopGet(AOP(left),0,FALSE,FALSE);
3133 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3134 pic14_emitcode("push","acc"); /* save it on the stack */
3136 /* now sign adjust for both left & right */
3137 l = aopGet(AOP(right),0,FALSE,FALSE);
3140 lbl = newiTempLabel(NULL);
3141 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3142 pic14_emitcode("cpl","a");
3143 pic14_emitcode("inc","a");
3144 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3145 pic14_emitcode("mov","b,a");
3147 /* sign adjust left side */
3148 l = aopGet(AOP(left),0,FALSE,FALSE);
3151 lbl = newiTempLabel(NULL);
3152 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3153 pic14_emitcode("cpl","a");
3154 pic14_emitcode("inc","a");
3155 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3157 /* now the multiplication */
3158 pic14_emitcode("div","ab");
3159 /* we are interested in the lower order
3161 lbl = newiTempLabel(NULL);
3162 pic14_emitcode("pop","acc");
3163 /* if there was an over flow we don't
3164 adjust the sign of the result */
3165 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3166 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3168 pic14_emitcode("clr","a");
3169 pic14_emitcode("subb","a,b");
3170 pic14_emitcode("mov","b,a");
3171 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3173 /* now we are done */
3174 aopPut(AOP(result),"b",0);
3178 /*-----------------------------------------------------------------*/
3179 /* genMod - generates code for division */
3180 /*-----------------------------------------------------------------*/
3181 static void genMod (iCode *ic)
3183 operand *left = IC_LEFT(ic);
3184 operand *right = IC_RIGHT(ic);
3185 operand *result= IC_RESULT(ic);
3187 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3188 /* assign the amsops */
3189 aopOp (left,ic,FALSE);
3190 aopOp (right,ic,FALSE);
3191 aopOp (result,ic,TRUE);
3193 /* special cases first */
3195 if (AOP_TYPE(left) == AOP_CRY &&
3196 AOP_TYPE(right)== AOP_CRY) {
3197 genModbits(left,right,result);
3201 /* if both are of size == 1 */
3202 if (AOP_SIZE(left) == 1 &&
3203 AOP_SIZE(right) == 1 ) {
3204 genModOneByte(left,right,result);
3208 /* should have been converted to function call */
3212 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3213 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3214 freeAsmop(result,NULL,ic,TRUE);
3217 /*-----------------------------------------------------------------*/
3218 /* genIfxJump :- will create a jump depending on the ifx */
3219 /*-----------------------------------------------------------------*/
3220 static void genIfxJump (iCode *ic, char *jval)
3223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3224 /* if true label then we jump if condition
3226 if ( IC_TRUE(ic) ) {
3228 if(strcmp(jval,"a") == 0)
3230 else if (strcmp(jval,"c") == 0)
3233 //pCodeOp *p = popGetWithString(jval);
3235 //emitpcode(POC_BTFSC, p);
3236 emitpcode(POC_BTFSC, newpCodeOpBit(jval,0));
3237 //pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval);
3240 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3241 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3245 /* false label is present */
3246 if(strcmp(jval,"a") == 0)
3248 else if (strcmp(jval,"c") == 0)
3251 //pCodeOp *p = popGetWithString(jval);
3253 //emitpcode(POC_BTFSS, p);
3254 emitpcode(POC_BTFSS, newpCodeOpBit(jval,0));
3256 // pic14_emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval);
3259 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3260 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3265 /* mark the icode as generated */
3269 /*-----------------------------------------------------------------*/
3271 /*-----------------------------------------------------------------*/
3272 static void genSkip(iCode *ifx,int status_bit)
3277 if ( IC_TRUE(ifx) ) {
3278 switch(status_bit) {
3293 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3294 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3298 switch(status_bit) {
3312 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3313 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3319 /*-----------------------------------------------------------------*/
3321 /*-----------------------------------------------------------------*/
3322 static void genSkipc(iCode *ifx, int condition)
3333 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3335 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3338 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3340 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3344 /*-----------------------------------------------------------------*/
3346 /*-----------------------------------------------------------------*/
3347 static void genSkipz(iCode *ifx, int condition)
3358 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3360 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3363 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3365 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3368 /*-----------------------------------------------------------------*/
3369 /* genCmp :- greater or less than comparison */
3370 /*-----------------------------------------------------------------*/
3371 static void genCmp (operand *left,operand *right,
3372 operand *result, iCode *ifx, int sign)
3374 int size, offset = 0 ;
3375 unsigned long lit = 0L,i = 0;
3377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3378 /* if left & right are bit variables */
3379 if (AOP_TYPE(left) == AOP_CRY &&
3380 AOP_TYPE(right) == AOP_CRY ) {
3381 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3382 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3384 /* subtract right from left if at the
3385 end the carry flag is set then we know that
3386 left is greater than right */
3387 size = max(AOP_SIZE(left),AOP_SIZE(right));
3389 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3390 if((size == 1) && !sign &&
3391 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3392 symbol *lbl = newiTempLabel(NULL);
3393 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3394 aopGet(AOP(left),offset,FALSE,FALSE),
3395 aopGet(AOP(right),offset,FALSE,FALSE),
3397 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3400 if(AOP_TYPE(right) == AOP_LIT) {
3402 DEBUGpic14_emitcode(";right lit","%d",sign);
3404 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3407 i = (lit >> (size*8)) & 0xff;
3409 emitpcode(POC_MOVFW, popGet(AOP(left),size,FALSE,FALSE));
3410 pic14_emitcode("movf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3411 genSkipz(ifx,IC_TRUE(ifx) == NULL);
3413 emitpcode(POC_MOVLW, popGetLit(i));
3414 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3416 pic14_emitcode("movlw","0x%x",i);
3417 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),size,FALSE,FALSE));
3418 genSkipc(ifx,IC_TRUE(ifx) == NULL);
3425 if(AOP_TYPE(left) == AOP_LIT) {
3427 DEBUGpic14_emitcode(";left lit","%d",sign);
3429 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit))+1;
3433 i = (lit >> (size*8)) & 0xff;
3435 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3436 pic14_emitcode("movf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3437 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3438 } else if( i == 1 ) {
3439 emitpcode(POC_DECFW, popGet(AOP(right),size,FALSE,FALSE));
3440 pic14_emitcode("decf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3441 genSkipz(ifx,IC_TRUE(ifx) != NULL);
3444 emitpcode(POC_MOVLW, popGetLit(i));
3445 emitpcode(POC_SUBFW, popGet(AOP(right),size,FALSE,FALSE));
3447 pic14_emitcode("movlw","0x%x",i);
3448 pic14_emitcode("subwf","%s,w",aopGet(AOP(right),size,FALSE,FALSE));
3449 genSkipc(ifx,IC_TRUE(ifx) != NULL);
3458 DEBUGpic14_emitcode(";sign","%d",sign);
3460 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3461 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3463 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3464 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3469 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3471 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3472 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3475 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3477 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3478 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3486 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3487 pic14_outBitC(result);
3489 /* if the result is used in the next
3490 ifx conditional branch then generate
3491 code a little differently */
3493 genIfxJump (ifx,"c");
3495 pic14_outBitC(result);
3496 /* leave the result in acc */
3501 /*-----------------------------------------------------------------*/
3502 /* genCmpGt :- greater than comparison */
3503 /*-----------------------------------------------------------------*/
3504 static void genCmpGt (iCode *ic, iCode *ifx)
3506 operand *left, *right, *result;
3507 sym_link *letype , *retype;
3510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3512 right= IC_RIGHT(ic);
3513 result = IC_RESULT(ic);
3515 letype = getSpec(operandType(left));
3516 retype =getSpec(operandType(right));
3517 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3518 /* assign the amsops */
3519 aopOp (left,ic,FALSE);
3520 aopOp (right,ic,FALSE);
3521 aopOp (result,ic,TRUE);
3523 genCmp(right, left, result, ifx, sign);
3525 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3526 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527 freeAsmop(result,NULL,ic,TRUE);
3530 /*-----------------------------------------------------------------*/
3531 /* genCmpLt - less than comparisons */
3532 /*-----------------------------------------------------------------*/
3533 static void genCmpLt (iCode *ic, iCode *ifx)
3535 operand *left, *right, *result;
3536 sym_link *letype , *retype;
3539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3541 right= IC_RIGHT(ic);
3542 result = IC_RESULT(ic);
3544 letype = getSpec(operandType(left));
3545 retype =getSpec(operandType(right));
3546 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3548 /* assign the amsops */
3549 aopOp (left,ic,FALSE);
3550 aopOp (right,ic,FALSE);
3551 aopOp (result,ic,TRUE);
3553 genCmp(left, right, result, ifx, sign);
3555 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3556 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3557 freeAsmop(result,NULL,ic,TRUE);
3560 /*-----------------------------------------------------------------*/
3561 /* gencjneshort - compare and jump if not equal */
3562 /*-----------------------------------------------------------------*/
3563 static void gencjneshort(operand *left, operand *right, symbol *lbl)
3565 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3567 unsigned long lit = 0L;
3569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3570 /* if the left side is a literal or
3571 if the right is in a pointer register and left
3573 if ((AOP_TYPE(left) == AOP_LIT) ||
3574 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3579 if(AOP_TYPE(right) == AOP_LIT)
3580 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3582 /* if the right side is a literal then anything goes */
3583 if (AOP_TYPE(right) == AOP_LIT &&
3584 AOP_TYPE(left) != AOP_DIR ) {
3587 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3588 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3590 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3593 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3599 /* if the right side is in a register or in direct space or
3600 if the left is a pointer register & right is not */
3601 else if (AOP_TYPE(right) == AOP_REG ||
3602 AOP_TYPE(right) == AOP_DIR ||
3603 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3604 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3606 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3607 ( (lit & 0xff) != 0)) {
3608 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3609 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3612 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3615 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3618 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
3619 if((AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) &&
3620 ((unsigned int)((lit >> (offset*8)) & 0x0FFL) == 0))
3621 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
3623 pic14_emitcode("cjne","a,%s,%05d_DS_",
3624 aopGet(AOP(right),offset,FALSE,TRUE),
3630 /* right is a pointer reg need both a & b */
3632 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3634 pic14_emitcode("mov","b,%s",l);
3635 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3636 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3642 /*-----------------------------------------------------------------*/
3643 /* gencjne - compare and jump if not equal */
3644 /*-----------------------------------------------------------------*/
3645 static void gencjne(operand *left, operand *right, symbol *lbl)
3647 symbol *tlbl = newiTempLabel(NULL);
3649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3650 gencjneshort(left, right, lbl);
3652 pic14_emitcode("mov","a,%s",one);
3653 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3654 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3655 pic14_emitcode("clr","a");
3656 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3660 /*-----------------------------------------------------------------*/
3661 /* genCmpEq - generates code for equal to */
3662 /*-----------------------------------------------------------------*/
3663 static void genCmpEq (iCode *ic, iCode *ifx)
3665 operand *left, *right, *result;
3666 unsigned long lit = 0L;
3669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3671 DEBUGpic14_emitcode ("; ifx is non-null","");
3673 DEBUGpic14_emitcode ("; ifx is null","");
3675 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3676 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3677 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3679 size = max(AOP_SIZE(left),AOP_SIZE(right));
3681 /* if literal, literal on the right or
3682 if the right is in a pointer register and left
3684 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3685 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3686 operand *t = IC_RIGHT(ic);
3687 IC_RIGHT(ic) = IC_LEFT(ic);
3691 if(ifx && !AOP_SIZE(result)){
3693 /* if they are both bit variables */
3694 if (AOP_TYPE(left) == AOP_CRY &&
3695 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3696 if(AOP_TYPE(right) == AOP_LIT){
3697 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3699 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3700 pic14_emitcode("cpl","c");
3701 } else if(lit == 1L) {
3702 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3704 pic14_emitcode("clr","c");
3706 /* AOP_TYPE(right) == AOP_CRY */
3708 symbol *lbl = newiTempLabel(NULL);
3709 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3710 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3711 pic14_emitcode("cpl","c");
3712 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3714 /* if true label then we jump if condition
3716 tlbl = newiTempLabel(NULL);
3717 if ( IC_TRUE(ifx) ) {
3718 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
3719 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
3721 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
3722 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
3724 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
3727 /* They're not both bit variables. Is the right a literal? */
3728 if(AOP_TYPE(right) == AOP_LIT) {
3730 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3735 int h = (lit>>8) & 0xff;
3738 /* Check special cases for integers */
3739 switch(lit & 0xffff) {
3741 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3742 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3743 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3744 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3749 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3750 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3751 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3752 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3757 emitpcode(POC_DECFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3758 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3759 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3760 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3765 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3766 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3767 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3768 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3773 emitpcode(POC_INCFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3774 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3775 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3776 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3782 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3783 emitpcode(POC_XORLW,popGetLit(l));
3784 emitpcode(POC_IORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3786 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3787 pic14_emitcode("xorlw","0x%x",l);
3788 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3791 } else if (l == 0) {
3792 emitpcode(POC_MOVFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3793 emitpcode(POC_XORLW,popGetLit(h));
3794 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3796 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3797 pic14_emitcode("xorlw","0x%x",h);
3798 pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3802 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3803 emitpcode(POC_XORLW,popGetLit(l));
3804 emitpcode(POC_MOVLW,popGetLit(h));
3806 emitpcode(POC_XORFW,popGet(AOP(left),offset+1,FALSE,FALSE));
3808 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3809 pic14_emitcode("xorlw","0x%x",l);
3810 pic14_emitcode("movlw","0x%x",h);
3812 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset+1,FALSE,FALSE));
3829 switch(lit & 0xff) {
3831 if ( IC_TRUE(ifx) ) {
3833 pic14_emitcode("decf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3835 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
3837 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3839 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3841 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3842 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3844 pic14_emitcode("decfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3845 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3849 if ( IC_TRUE(ifx) ) {
3850 pic14_emitcode("incf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3852 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
3854 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3856 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3858 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
3859 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3861 pic14_emitcode("incfsz","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3862 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3866 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3867 //pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3869 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3870 //pic14_emitcode("xorlw","0x%x",lit & 0xff);
3875 // pic14_emitcode("goto","_%05d_DS_",tlbl->key+100+labelOffset);
3876 //pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3881 } else if(AOP_TYPE(right) == AOP_CRY ) {
3882 /* we know the left is not a bit, but that the right is */
3883 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3884 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
3885 popGet(AOP(right),offset,FALSE,FALSE));
3886 emitpcode(POC_XORLW,popGetLit(1));
3888 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3890 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
3891 AOP(right)->aopu.aop_dir,
3892 AOP(right)->aopu.aop_dir);
3894 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
3895 AOP(right)->aopu.aop_dir,
3896 AOP(right)->aopu.aop_dir);
3898 pic14_emitcode("xorlw","1");
3900 /* if the two are equal, then W will be 0 and the Z bit is set
3901 * we could test Z now, or go ahead and check the high order bytes if
3902 * the variable we're comparing is larger than a byte. */
3905 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
3906 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3908 if ( IC_TRUE(ifx) ) {
3910 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3911 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3914 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3915 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3919 /* They're both variables that are larger than bits */
3922 tlbl = newiTempLabel(NULL);
3925 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3926 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3928 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3929 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3931 if ( IC_TRUE(ifx) ) {
3934 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
3935 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
3938 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3939 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3943 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3944 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3948 if(s>1 && IC_TRUE(ifx)) {
3949 emitpLabel(tlbl->key+100+labelOffset);
3950 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
3954 /* mark the icode as generated */
3959 /* if they are both bit variables */
3960 if (AOP_TYPE(left) == AOP_CRY &&
3961 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3962 if(AOP_TYPE(right) == AOP_LIT){
3963 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3965 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3966 pic14_emitcode("cpl","c");
3967 } else if(lit == 1L) {
3968 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3970 pic14_emitcode("clr","c");
3972 /* AOP_TYPE(right) == AOP_CRY */
3974 symbol *lbl = newiTempLabel(NULL);
3975 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
3976 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
3977 pic14_emitcode("cpl","c");
3978 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3981 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
3982 pic14_outBitC(result);
3986 genIfxJump (ifx,"c");
3989 /* if the result is used in an arithmetic operation
3990 then put the result in place */
3991 pic14_outBitC(result);
3993 gencjne(left,right,newiTempLabel(NULL));
3994 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3995 aopPut(AOP(result),"a",0);
3999 genIfxJump (ifx,"a");
4002 /* if the result is used in an arithmetic operation
4003 then put the result in place */
4004 if (AOP_TYPE(result) != AOP_CRY)
4005 pic14_outAcc(result);
4006 /* leave the result in acc */
4010 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4011 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4012 freeAsmop(result,NULL,ic,TRUE);
4015 /*-----------------------------------------------------------------*/
4016 /* ifxForOp - returns the icode containing the ifx for operand */
4017 /*-----------------------------------------------------------------*/
4018 static iCode *ifxForOp ( operand *op, iCode *ic )
4020 /* if true symbol then needs to be assigned */
4021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4022 if (IS_TRUE_SYMOP(op))
4025 /* if this has register type condition and
4026 the next instruction is ifx with the same operand
4027 and live to of the operand is upto the ifx only then */
4029 ic->next->op == IFX &&
4030 IC_COND(ic->next)->key == op->key &&
4031 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4036 /*-----------------------------------------------------------------*/
4037 /* genAndOp - for && operation */
4038 /*-----------------------------------------------------------------*/
4039 static void genAndOp (iCode *ic)
4041 operand *left,*right, *result;
4044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4045 /* note here that && operations that are in an
4046 if statement are taken away by backPatchLabels
4047 only those used in arthmetic operations remain */
4048 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4049 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4050 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4052 /* if both are bit variables */
4053 if (AOP_TYPE(left) == AOP_CRY &&
4054 AOP_TYPE(right) == AOP_CRY ) {
4055 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4056 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4057 pic14_outBitC(result);
4059 tlbl = newiTempLabel(NULL);
4060 pic14_toBoolean(left);
4061 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4062 pic14_toBoolean(right);
4063 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4064 pic14_outBitAcc(result);
4067 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4068 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4069 freeAsmop(result,NULL,ic,TRUE);
4073 /*-----------------------------------------------------------------*/
4074 /* genOrOp - for || operation */
4075 /*-----------------------------------------------------------------*/
4078 modified this code, but it doesn't appear to ever get called
4081 static void genOrOp (iCode *ic)
4083 operand *left,*right, *result;
4086 /* note here that || operations that are in an
4087 if statement are taken away by backPatchLabels
4088 only those used in arthmetic operations remain */
4089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4090 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4091 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4092 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4094 /* if both are bit variables */
4095 if (AOP_TYPE(left) == AOP_CRY &&
4096 AOP_TYPE(right) == AOP_CRY ) {
4097 pic14_emitcode("clrc","");
4098 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4099 AOP(left)->aopu.aop_dir,
4100 AOP(left)->aopu.aop_dir);
4101 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4102 AOP(right)->aopu.aop_dir,
4103 AOP(right)->aopu.aop_dir);
4104 pic14_emitcode("setc","");
4107 tlbl = newiTempLabel(NULL);
4108 pic14_toBoolean(left);
4110 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4111 pic14_toBoolean(right);
4112 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4114 pic14_outBitAcc(result);
4117 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4118 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4119 freeAsmop(result,NULL,ic,TRUE);
4122 /*-----------------------------------------------------------------*/
4123 /* isLiteralBit - test if lit == 2^n */
4124 /*-----------------------------------------------------------------*/
4125 static int isLiteralBit(unsigned long lit)
4127 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4128 0x100L,0x200L,0x400L,0x800L,
4129 0x1000L,0x2000L,0x4000L,0x8000L,
4130 0x10000L,0x20000L,0x40000L,0x80000L,
4131 0x100000L,0x200000L,0x400000L,0x800000L,
4132 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4133 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4137 for(idx = 0; idx < 32; idx++)
4143 /*-----------------------------------------------------------------*/
4144 /* continueIfTrue - */
4145 /*-----------------------------------------------------------------*/
4146 static void continueIfTrue (iCode *ic)
4148 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4150 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4154 /*-----------------------------------------------------------------*/
4156 /*-----------------------------------------------------------------*/
4157 static void jumpIfTrue (iCode *ic)
4159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4161 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4165 /*-----------------------------------------------------------------*/
4166 /* jmpTrueOrFalse - */
4167 /*-----------------------------------------------------------------*/
4168 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4170 // ugly but optimized by peephole
4171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4173 symbol *nlbl = newiTempLabel(NULL);
4174 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4175 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4176 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4177 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4180 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4181 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4186 /*-----------------------------------------------------------------*/
4187 /* genAnd - code for and */
4188 /*-----------------------------------------------------------------*/
4189 static void genAnd (iCode *ic, iCode *ifx)
4191 operand *left, *right, *result;
4193 unsigned long lit = 0L;
4197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4198 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4199 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4200 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4203 pic14_emitcode("","; Type res[%d] = l[%d]&r[%d]",
4205 AOP_TYPE(left), AOP_TYPE(right));
4206 pic14_emitcode("","; Size res[%d] = l[%d]&r[%d]",
4208 AOP_SIZE(left), AOP_SIZE(right));
4211 /* if left is a literal & right is not then exchange them */
4212 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4213 AOP_NEEDSACC(left)) {
4214 operand *tmp = right ;
4219 /* if result = right then exchange them */
4220 if(pic14_sameRegs(AOP(result),AOP(right))){
4221 operand *tmp = right ;
4226 /* if right is bit then exchange them */
4227 if (AOP_TYPE(right) == AOP_CRY &&
4228 AOP_TYPE(left) != AOP_CRY){
4229 operand *tmp = right ;
4233 if(AOP_TYPE(right) == AOP_LIT)
4234 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4236 size = AOP_SIZE(result);
4239 // result = bit & yy;
4240 if (AOP_TYPE(left) == AOP_CRY){
4241 // c = bit & literal;
4242 if(AOP_TYPE(right) == AOP_LIT){
4244 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4247 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4250 if(size && (AOP_TYPE(result) == AOP_CRY)){
4251 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4254 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4258 pic14_emitcode("clr","c");
4261 if (AOP_TYPE(right) == AOP_CRY){
4263 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4264 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4267 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4269 pic14_emitcode("rrc","a");
4270 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4276 pic14_outBitC(result);
4278 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4279 genIfxJump(ifx, "c");
4283 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4284 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4285 if((AOP_TYPE(right) == AOP_LIT) &&
4286 (AOP_TYPE(result) == AOP_CRY) &&
4287 (AOP_TYPE(left) != AOP_CRY)){
4288 int posbit = isLiteralBit(lit);
4292 MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4295 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4299 sprintf(buffer,"acc.%d",posbit&0x07);
4300 genIfxJump(ifx, buffer);
4305 symbol *tlbl = newiTempLabel(NULL);
4306 int sizel = AOP_SIZE(left);
4308 pic14_emitcode("setb","c");
4310 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4311 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4313 if((posbit = isLiteralBit(bytelit)) != 0)
4314 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4316 if(bytelit != 0x0FFL)
4317 pic14_emitcode("anl","a,%s",
4318 aopGet(AOP(right),offset,FALSE,TRUE));
4319 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4324 // bit = left & literal
4326 pic14_emitcode("clr","c");
4327 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4329 // if(left & literal)
4332 jmpTrueOrFalse(ifx, tlbl);
4336 pic14_outBitC(result);
4340 /* if left is same as result */
4341 if(pic14_sameRegs(AOP(result),AOP(left))){
4342 for(;size--; offset++,lit>>=8) {
4343 if(AOP_TYPE(right) == AOP_LIT){
4344 switch(lit & 0xff) {
4346 /* and'ing with 0 has clears the result */
4347 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4350 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4355 int p = my_powof2( (~lit) & 0xff );
4357 /* only one bit is set in the literal, so use a bcf instruction */
4358 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4360 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4361 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4366 if (AOP_TYPE(left) == AOP_ACC)
4367 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4369 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4370 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4377 // left & result in different registers
4378 if(AOP_TYPE(result) == AOP_CRY){
4380 // if(size), result in bit
4381 // if(!size && ifx), conditional oper: if(left & right)
4382 symbol *tlbl = newiTempLabel(NULL);
4383 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4385 pic14_emitcode("setb","c");
4387 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4388 pic14_emitcode("anl","a,%s",
4389 aopGet(AOP(left),offset,FALSE,FALSE));
4390 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4395 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4396 pic14_outBitC(result);
4398 jmpTrueOrFalse(ifx, tlbl);
4400 for(;(size--);offset++) {
4402 // result = left & right
4403 if(AOP_TYPE(right) == AOP_LIT){
4404 int t = (lit >> (offset*8)) & 0x0FFL;
4407 pic14_emitcode("clrf","%s",
4408 aopGet(AOP(result),offset,FALSE,FALSE));
4411 pic14_emitcode("movf","%s,w",
4412 aopGet(AOP(left),offset,FALSE,FALSE));
4413 pic14_emitcode("movwf","%s",
4414 aopGet(AOP(result),offset,FALSE,FALSE));
4417 pic14_emitcode("movlw","0x%x",t);
4418 pic14_emitcode("andwf","%s,w",
4419 aopGet(AOP(left),offset,FALSE,FALSE));
4420 pic14_emitcode("movwf","%s",
4421 aopGet(AOP(result),offset,FALSE,FALSE));
4427 if (AOP_TYPE(left) == AOP_ACC)
4428 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4430 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4431 pic14_emitcode("andwf","%s,w",
4432 aopGet(AOP(left),offset,FALSE,FALSE));
4434 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4440 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442 freeAsmop(result,NULL,ic,TRUE);
4445 /*-----------------------------------------------------------------*/
4446 /* genOr - code for or */
4447 /*-----------------------------------------------------------------*/
4448 static void genOr (iCode *ic, iCode *ifx)
4450 operand *left, *right, *result;
4452 unsigned long lit = 0L;
4454 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4456 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4457 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4458 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4461 /* if left is a literal & right is not then exchange them */
4462 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4463 AOP_NEEDSACC(left)) {
4464 operand *tmp = right ;
4469 /* if result = right then exchange them */
4470 if(pic14_sameRegs(AOP(result),AOP(right))){
4471 operand *tmp = right ;
4476 /* if right is bit then exchange them */
4477 if (AOP_TYPE(right) == AOP_CRY &&
4478 AOP_TYPE(left) != AOP_CRY){
4479 operand *tmp = right ;
4484 if(AOP_TYPE(right) == AOP_LIT)
4485 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4487 size = AOP_SIZE(result);
4491 if (AOP_TYPE(left) == AOP_CRY){
4492 if(AOP_TYPE(right) == AOP_LIT){
4493 // c = bit & literal;
4495 // lit != 0 => result = 1
4496 if(AOP_TYPE(result) == AOP_CRY){
4498 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4499 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4500 // AOP(result)->aopu.aop_dir,
4501 // AOP(result)->aopu.aop_dir);
4503 continueIfTrue(ifx);
4507 // lit == 0 => result = left
4508 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4510 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4513 if (AOP_TYPE(right) == AOP_CRY){
4514 if(pic14_sameRegs(AOP(result),AOP(left))){
4516 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4517 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4518 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4520 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4521 AOP(result)->aopu.aop_dir,
4522 AOP(result)->aopu.aop_dir);
4523 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4524 AOP(right)->aopu.aop_dir,
4525 AOP(right)->aopu.aop_dir);
4526 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4527 AOP(result)->aopu.aop_dir,
4528 AOP(result)->aopu.aop_dir);
4531 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4532 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4533 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4534 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4536 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4537 AOP(result)->aopu.aop_dir,
4538 AOP(result)->aopu.aop_dir);
4539 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4540 AOP(right)->aopu.aop_dir,
4541 AOP(right)->aopu.aop_dir);
4542 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4543 AOP(left)->aopu.aop_dir,
4544 AOP(left)->aopu.aop_dir);
4545 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4546 AOP(result)->aopu.aop_dir,
4547 AOP(result)->aopu.aop_dir);
4552 symbol *tlbl = newiTempLabel(NULL);
4553 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4554 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4555 pic14_emitcode(";XXX setb","c");
4556 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4557 AOP(left)->aopu.aop_dir,tlbl->key+100);
4558 pic14_toBoolean(right);
4559 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4560 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4561 jmpTrueOrFalse(ifx, tlbl);
4565 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4572 pic14_outBitC(result);
4574 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4575 genIfxJump(ifx, "c");
4579 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4580 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4581 if((AOP_TYPE(right) == AOP_LIT) &&
4582 (AOP_TYPE(result) == AOP_CRY) &&
4583 (AOP_TYPE(left) != AOP_CRY)){
4585 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4588 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4590 continueIfTrue(ifx);
4593 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4594 // lit = 0, result = boolean(left)
4596 pic14_emitcode(";XXX setb","c");
4597 pic14_toBoolean(right);
4599 symbol *tlbl = newiTempLabel(NULL);
4600 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4602 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4604 genIfxJump (ifx,"a");
4608 pic14_outBitC(result);
4612 /* if left is same as result */
4613 if(pic14_sameRegs(AOP(result),AOP(left))){
4614 for(;size--; offset++,lit>>=8) {
4615 if(AOP_TYPE(right) == AOP_LIT){
4616 if((lit & 0xff) == 0)
4617 /* or'ing with 0 has no effect */
4620 int p = my_powof2(lit & 0xff);
4622 /* only one bit is set in the literal, so use a bsf instruction */
4623 emitpcode(POC_BSF, popGet(AOP(left),offset,FALSE,FALSE));
4624 pic14_emitcode("bsf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4626 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4627 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4629 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4630 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
4635 if (AOP_TYPE(left) == AOP_ACC) {
4636 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4637 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4639 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4640 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4642 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4643 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4649 // left & result in different registers
4650 if(AOP_TYPE(result) == AOP_CRY){
4652 // if(size), result in bit
4653 // if(!size && ifx), conditional oper: if(left | right)
4654 symbol *tlbl = newiTempLabel(NULL);
4655 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4656 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4659 pic14_emitcode(";XXX setb","c");
4661 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4662 pic14_emitcode(";XXX orl","a,%s",
4663 aopGet(AOP(left),offset,FALSE,FALSE));
4664 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4669 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4670 pic14_outBitC(result);
4672 jmpTrueOrFalse(ifx, tlbl);
4673 } else for(;(size--);offset++){
4675 // result = left & right
4676 if(AOP_TYPE(right) == AOP_LIT){
4677 int t = (lit >> (offset*8)) & 0x0FFL;
4680 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
4681 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4683 pic14_emitcode("movf","%s,w",
4684 aopGet(AOP(left),offset,FALSE,FALSE));
4685 pic14_emitcode("movwf","%s",
4686 aopGet(AOP(result),offset,FALSE,FALSE));
4689 emitpcode(POC_MOVLW, popGetLit(t));
4690 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4691 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4693 pic14_emitcode("movlw","0x%x",t);
4694 pic14_emitcode("iorwf","%s,w",
4695 aopGet(AOP(left),offset,FALSE,FALSE));
4696 pic14_emitcode("movwf","%s",
4697 aopGet(AOP(result),offset,FALSE,FALSE));
4703 // faster than result <- left, anl result,right
4704 // and better if result is SFR
4705 if (AOP_TYPE(left) == AOP_ACC) {
4706 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
4707 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4709 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4710 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
4712 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4713 pic14_emitcode("iorwf","%s,w",
4714 aopGet(AOP(left),offset,FALSE,FALSE));
4716 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
4717 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4722 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4723 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4724 freeAsmop(result,NULL,ic,TRUE);
4727 /*-----------------------------------------------------------------*/
4728 /* genXor - code for xclusive or */
4729 /*-----------------------------------------------------------------*/
4730 static void genXor (iCode *ic, iCode *ifx)
4732 operand *left, *right, *result;
4734 unsigned long lit = 0L;
4736 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4738 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4739 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4740 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4742 /* if left is a literal & right is not ||
4743 if left needs acc & right does not */
4744 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4745 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
4746 operand *tmp = right ;
4751 /* if result = right then exchange them */
4752 if(pic14_sameRegs(AOP(result),AOP(right))){
4753 operand *tmp = right ;
4758 /* if right is bit then exchange them */
4759 if (AOP_TYPE(right) == AOP_CRY &&
4760 AOP_TYPE(left) != AOP_CRY){
4761 operand *tmp = right ;
4765 if(AOP_TYPE(right) == AOP_LIT)
4766 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4768 size = AOP_SIZE(result);
4772 if (AOP_TYPE(left) == AOP_CRY){
4773 if(AOP_TYPE(right) == AOP_LIT){
4774 // c = bit & literal;
4776 // lit>>1 != 0 => result = 1
4777 if(AOP_TYPE(result) == AOP_CRY){
4779 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
4781 continueIfTrue(ifx);
4784 pic14_emitcode("setb","c");
4788 // lit == 0, result = left
4789 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4791 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4793 // lit == 1, result = not(left)
4794 if(size && pic14_sameRegs(AOP(result),AOP(left))){
4795 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
4798 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4799 pic14_emitcode("cpl","c");
4806 symbol *tlbl = newiTempLabel(NULL);
4807 if (AOP_TYPE(right) == AOP_CRY){
4809 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4812 int sizer = AOP_SIZE(right);
4814 // if val>>1 != 0, result = 1
4815 pic14_emitcode("setb","c");
4817 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
4819 // test the msb of the lsb
4820 pic14_emitcode("anl","a,#0xfe");
4821 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4825 pic14_emitcode("rrc","a");
4827 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
4828 pic14_emitcode("cpl","c");
4829 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
4834 pic14_outBitC(result);
4836 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4837 genIfxJump(ifx, "c");
4841 if(pic14_sameRegs(AOP(result),AOP(left))){
4842 /* if left is same as result */
4843 for(;size--; offset++) {
4844 if(AOP_TYPE(right) == AOP_LIT){
4845 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
4848 if (IS_AOP_PREG(left)) {
4849 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4850 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4851 aopPut(AOP(result),"a",offset);
4853 pic14_emitcode("xrl","%s,%s",
4854 aopGet(AOP(left),offset,FALSE,TRUE),
4855 aopGet(AOP(right),offset,FALSE,FALSE));
4857 if (AOP_TYPE(left) == AOP_ACC)
4858 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
4860 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4861 if (IS_AOP_PREG(left)) {
4862 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
4863 aopPut(AOP(result),"a",offset);
4865 pic14_emitcode("xrl","%s,a",
4866 aopGet(AOP(left),offset,FALSE,TRUE));
4871 // left & result in different registers
4872 if(AOP_TYPE(result) == AOP_CRY){
4874 // if(size), result in bit
4875 // if(!size && ifx), conditional oper: if(left ^ right)
4876 symbol *tlbl = newiTempLabel(NULL);
4877 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4879 pic14_emitcode("setb","c");
4881 if((AOP_TYPE(right) == AOP_LIT) &&
4882 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
4883 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
4885 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4886 pic14_emitcode("xrl","a,%s",
4887 aopGet(AOP(left),offset,FALSE,FALSE));
4889 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4894 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4895 pic14_outBitC(result);
4897 jmpTrueOrFalse(ifx, tlbl);
4898 } else for(;(size--);offset++){
4900 // result = left & right
4901 if(AOP_TYPE(right) == AOP_LIT){
4902 int t = (lit >> (offset*8)) & 0x0FFL;
4905 pic14_emitcode("movf","%s,w",
4906 aopGet(AOP(left),offset,FALSE,FALSE));
4907 pic14_emitcode("movwf","%s",
4908 aopGet(AOP(result),offset,FALSE,FALSE));
4911 pic14_emitcode("comf","%s,w",
4912 aopGet(AOP(left),offset,FALSE,FALSE));
4913 pic14_emitcode("movwf","%s",
4914 aopGet(AOP(result),offset,FALSE,FALSE));
4917 pic14_emitcode("movlw","0x%x",t);
4918 pic14_emitcode("xorwf","%s,w",
4919 aopGet(AOP(left),offset,FALSE,FALSE));
4920 pic14_emitcode("movwf","%s",
4921 aopGet(AOP(result),offset,FALSE,FALSE));
4927 // faster than result <- left, anl result,right
4928 // and better if result is SFR
4929 if (AOP_TYPE(left) == AOP_ACC)
4930 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4932 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4933 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4935 if ( AOP_TYPE(result) != AOP_ACC)
4936 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4941 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4942 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4943 freeAsmop(result,NULL,ic,TRUE);
4946 /*-----------------------------------------------------------------*/
4947 /* genInline - write the inline code out */
4948 /*-----------------------------------------------------------------*/
4949 static void genInline (iCode *ic)
4951 char *buffer, *bp, *bp1;
4953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4955 _G.inLine += (!options.asmpeep);
4957 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
4958 strcpy(buffer,IC_INLINE(ic));
4960 /* emit each line as a code */
4964 pic14_emitcode(bp1,"");
4971 pic14_emitcode(bp1,"");
4978 pic14_emitcode(bp1,"");
4979 /* pic14_emitcode("",buffer); */
4980 _G.inLine -= (!options.asmpeep);
4983 /*-----------------------------------------------------------------*/
4984 /* genRRC - rotate right with carry */
4985 /*-----------------------------------------------------------------*/
4986 static void genRRC (iCode *ic)
4988 operand *left , *result ;
4989 int size, offset = 0;
4992 /* rotate right with carry */
4994 result=IC_RESULT(ic);
4995 aopOp (left,ic,FALSE);
4996 aopOp (result,ic,FALSE);
4998 /* move it to the result */
4999 size = AOP_SIZE(result);
5003 l = aopGet(AOP(left),offset,FALSE,FALSE);
5005 pic14_emitcode("rrc","a");
5006 if (AOP_SIZE(result) > 1)
5007 aopPut(AOP(result),"a",offset--);
5009 /* now we need to put the carry into the
5010 highest order byte of the result */
5011 if (AOP_SIZE(result) > 1) {
5012 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5015 pic14_emitcode("mov","acc.7,c");
5016 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5017 freeAsmop(left,NULL,ic,TRUE);
5018 freeAsmop(result,NULL,ic,TRUE);
5021 /*-----------------------------------------------------------------*/
5022 /* genRLC - generate code for rotate left with carry */
5023 /*-----------------------------------------------------------------*/
5024 static void genRLC (iCode *ic)
5026 operand *left , *result ;
5027 int size, offset = 0;
5030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5031 /* rotate right with carry */
5033 result=IC_RESULT(ic);
5034 aopOp (left,ic,FALSE);
5035 aopOp (result,ic,FALSE);
5037 /* move it to the result */
5038 size = AOP_SIZE(result);
5041 l = aopGet(AOP(left),offset,FALSE,FALSE);
5043 pic14_emitcode("add","a,acc");
5044 if (AOP_SIZE(result) > 1)
5045 aopPut(AOP(result),"a",offset++);
5047 l = aopGet(AOP(left),offset,FALSE,FALSE);
5049 pic14_emitcode("rlc","a");
5050 if (AOP_SIZE(result) > 1)
5051 aopPut(AOP(result),"a",offset++);
5054 /* now we need to put the carry into the
5055 highest order byte of the result */
5056 if (AOP_SIZE(result) > 1) {
5057 l = aopGet(AOP(result),0,FALSE,FALSE);
5060 pic14_emitcode("mov","acc.0,c");
5061 aopPut(AOP(result),"a",0);
5062 freeAsmop(left,NULL,ic,TRUE);
5063 freeAsmop(result,NULL,ic,TRUE);
5066 /*-----------------------------------------------------------------*/
5067 /* genGetHbit - generates code get highest order bit */
5068 /*-----------------------------------------------------------------*/
5069 static void genGetHbit (iCode *ic)
5071 operand *left, *result;
5073 result=IC_RESULT(ic);
5074 aopOp (left,ic,FALSE);
5075 aopOp (result,ic,FALSE);
5077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5078 /* get the highest order byte into a */
5079 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5080 if(AOP_TYPE(result) == AOP_CRY){
5081 pic14_emitcode("rlc","a");
5082 pic14_outBitC(result);
5085 pic14_emitcode("rl","a");
5086 pic14_emitcode("anl","a,#0x01");
5087 pic14_outAcc(result);
5091 freeAsmop(left,NULL,ic,TRUE);
5092 freeAsmop(result,NULL,ic,TRUE);
5095 /*-----------------------------------------------------------------*/
5096 /* AccRol - rotate left accumulator by known count */
5097 /*-----------------------------------------------------------------*/
5098 static void AccRol (int shCount)
5100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5101 shCount &= 0x0007; // shCount : 0..7
5106 pic14_emitcode("rl","a");
5109 pic14_emitcode("rl","a");
5110 pic14_emitcode("rl","a");
5113 pic14_emitcode("swap","a");
5114 pic14_emitcode("rr","a");
5117 pic14_emitcode("swap","a");
5120 pic14_emitcode("swap","a");
5121 pic14_emitcode("rl","a");
5124 pic14_emitcode("rr","a");
5125 pic14_emitcode("rr","a");
5128 pic14_emitcode("rr","a");
5133 /*-----------------------------------------------------------------*/
5134 /* AccLsh - left shift accumulator by known count */
5135 /*-----------------------------------------------------------------*/
5136 static void AccLsh (int shCount)
5138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 pic14_emitcode("add","a,acc");
5144 pic14_emitcode("add","a,acc");
5145 pic14_emitcode("add","a,acc");
5147 /* rotate left accumulator */
5149 /* and kill the lower order bits */
5150 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5155 /*-----------------------------------------------------------------*/
5156 /* AccRsh - right shift accumulator by known count */
5157 /*-----------------------------------------------------------------*/
5158 static void AccRsh (int shCount)
5160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5164 pic14_emitcode("rrc","a");
5166 /* rotate right accumulator */
5167 AccRol(8 - shCount);
5168 /* and kill the higher order bits */
5169 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5174 /*-----------------------------------------------------------------*/
5175 /* AccSRsh - signed right shift accumulator by known count */
5176 /*-----------------------------------------------------------------*/
5177 static void AccSRsh (int shCount)
5180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5183 pic14_emitcode("mov","c,acc.7");
5184 pic14_emitcode("rrc","a");
5185 } else if(shCount == 2){
5186 pic14_emitcode("mov","c,acc.7");
5187 pic14_emitcode("rrc","a");
5188 pic14_emitcode("mov","c,acc.7");
5189 pic14_emitcode("rrc","a");
5191 tlbl = newiTempLabel(NULL);
5192 /* rotate right accumulator */
5193 AccRol(8 - shCount);
5194 /* and kill the higher order bits */
5195 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5196 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5197 pic14_emitcode("orl","a,#0x%02x",
5198 (unsigned char)~SRMask[shCount]);
5199 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5204 /*-----------------------------------------------------------------*/
5205 /* shiftR1Left2Result - shift right one byte from left to result */
5206 /*-----------------------------------------------------------------*/
5207 static void shiftR1Left2Result (operand *left, int offl,
5208 operand *result, int offr,
5209 int shCount, int sign)
5211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5212 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5213 /* shift right accumulator */
5218 aopPut(AOP(result),"a",offr);
5221 /*-----------------------------------------------------------------*/
5222 /* shiftL1Left2Result - shift left one byte from left to result */
5223 /*-----------------------------------------------------------------*/
5224 static void shiftL1Left2Result (operand *left, int offl,
5225 operand *result, int offr, int shCount)
5228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5229 l = aopGet(AOP(left),offl,FALSE,FALSE);
5231 /* shift left accumulator */
5233 aopPut(AOP(result),"a",offr);
5236 /*-----------------------------------------------------------------*/
5237 /* movLeft2Result - move byte from left to result */
5238 /*-----------------------------------------------------------------*/
5239 static void movLeft2Result (operand *left, int offl,
5240 operand *result, int offr, int sign)
5243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5244 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5245 l = aopGet(AOP(left),offl,FALSE,FALSE);
5247 if (*l == '@' && (IS_AOP_PREG(result))) {
5248 pic14_emitcode("mov","a,%s",l);
5249 aopPut(AOP(result),"a",offr);
5252 aopPut(AOP(result),l,offr);
5254 /* MSB sign in acc.7 ! */
5255 if(pic14_getDataSize(left) == offl+1){
5256 pic14_emitcode("mov","a,%s",l);
5257 aopPut(AOP(result),"a",offr);
5264 /*-----------------------------------------------------------------*/
5265 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5266 /*-----------------------------------------------------------------*/
5267 static void AccAXRrl1 (char *x)
5269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5270 pic14_emitcode("rrc","a");
5271 pic14_emitcode("xch","a,%s", x);
5272 pic14_emitcode("rrc","a");
5273 pic14_emitcode("xch","a,%s", x);
5276 /*-----------------------------------------------------------------*/
5277 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5278 /*-----------------------------------------------------------------*/
5279 static void AccAXLrl1 (char *x)
5281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5282 pic14_emitcode("xch","a,%s",x);
5283 pic14_emitcode("rlc","a");
5284 pic14_emitcode("xch","a,%s",x);
5285 pic14_emitcode("rlc","a");
5288 /*-----------------------------------------------------------------*/
5289 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5290 /*-----------------------------------------------------------------*/
5291 static void AccAXLsh1 (char *x)
5293 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5294 pic14_emitcode("xch","a,%s",x);
5295 pic14_emitcode("add","a,acc");
5296 pic14_emitcode("xch","a,%s",x);
5297 pic14_emitcode("rlc","a");
5300 /*-----------------------------------------------------------------*/
5301 /* AccAXLsh - left shift a:x by known count (0..7) */
5302 /*-----------------------------------------------------------------*/
5303 static void AccAXLsh (char *x, int shCount)
5305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5318 case 5 : // AAAAABBB:CCCCCDDD
5319 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5320 pic14_emitcode("anl","a,#0x%02x",
5321 SLMask[shCount]); // BBB00000:CCCCCDDD
5322 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5323 AccRol(shCount); // DDDCCCCC:BBB00000
5324 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5325 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5326 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5327 pic14_emitcode("anl","a,#0x%02x",
5328 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5329 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5330 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5332 case 6 : // AAAAAABB:CCCCCCDD
5333 pic14_emitcode("anl","a,#0x%02x",
5334 SRMask[shCount]); // 000000BB:CCCCCCDD
5335 pic14_emitcode("mov","c,acc.0"); // c = B
5336 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5337 AccAXRrl1(x); // BCCCCCCD:D000000B
5338 AccAXRrl1(x); // BBCCCCCC:DD000000
5340 case 7 : // a:x <<= 7
5341 pic14_emitcode("anl","a,#0x%02x",
5342 SRMask[shCount]); // 0000000B:CCCCCCCD
5343 pic14_emitcode("mov","c,acc.0"); // c = B
5344 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5345 AccAXRrl1(x); // BCCCCCCC:D0000000
5352 /*-----------------------------------------------------------------*/
5353 /* AccAXRsh - right shift a:x known count (0..7) */
5354 /*-----------------------------------------------------------------*/
5355 static void AccAXRsh (char *x, int shCount)
5357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5363 AccAXRrl1(x); // 0->a:x
5367 AccAXRrl1(x); // 0->a:x
5369 AccAXRrl1(x); // 0->a:x
5373 case 5 : // AAAAABBB:CCCCCDDD = a:x
5374 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5375 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5376 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5377 pic14_emitcode("anl","a,#0x%02x",
5378 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5379 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5380 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5381 pic14_emitcode("anl","a,#0x%02x",
5382 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5383 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5384 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5385 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5387 case 6 : // AABBBBBB:CCDDDDDD
5388 pic14_emitcode("mov","c,acc.7");
5389 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5390 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5391 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5392 pic14_emitcode("anl","a,#0x%02x",
5393 SRMask[shCount]); // 000000AA:BBBBBBCC
5395 case 7 : // ABBBBBBB:CDDDDDDD
5396 pic14_emitcode("mov","c,acc.7"); // c = A
5397 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5398 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5399 pic14_emitcode("anl","a,#0x%02x",
5400 SRMask[shCount]); // 0000000A:BBBBBBBC
5407 /*-----------------------------------------------------------------*/
5408 /* AccAXRshS - right shift signed a:x known count (0..7) */
5409 /*-----------------------------------------------------------------*/
5410 static void AccAXRshS (char *x, int shCount)
5413 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5418 pic14_emitcode("mov","c,acc.7");
5419 AccAXRrl1(x); // s->a:x
5422 pic14_emitcode("mov","c,acc.7");
5423 AccAXRrl1(x); // s->a:x
5424 pic14_emitcode("mov","c,acc.7");
5425 AccAXRrl1(x); // s->a:x
5429 case 5 : // AAAAABBB:CCCCCDDD = a:x
5430 tlbl = newiTempLabel(NULL);
5431 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5432 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5433 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5434 pic14_emitcode("anl","a,#0x%02x",
5435 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5436 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5437 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5438 pic14_emitcode("anl","a,#0x%02x",
5439 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5440 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5441 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5442 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5443 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5444 pic14_emitcode("orl","a,#0x%02x",
5445 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5446 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5447 break; // SSSSAAAA:BBBCCCCC
5448 case 6 : // AABBBBBB:CCDDDDDD
5449 tlbl = newiTempLabel(NULL);
5450 pic14_emitcode("mov","c,acc.7");
5451 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5452 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5453 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5454 pic14_emitcode("anl","a,#0x%02x",
5455 SRMask[shCount]); // 000000AA:BBBBBBCC
5456 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5457 pic14_emitcode("orl","a,#0x%02x",
5458 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5459 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5461 case 7 : // ABBBBBBB:CDDDDDDD
5462 tlbl = newiTempLabel(NULL);
5463 pic14_emitcode("mov","c,acc.7"); // c = A
5464 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5465 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5466 pic14_emitcode("anl","a,#0x%02x",
5467 SRMask[shCount]); // 0000000A:BBBBBBBC
5468 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5469 pic14_emitcode("orl","a,#0x%02x",
5470 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5471 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5478 /*-----------------------------------------------------------------*/
5479 /* shiftL2Left2Result - shift left two bytes from left to result */
5480 /*-----------------------------------------------------------------*/
5481 static void shiftL2Left2Result (operand *left, int offl,
5482 operand *result, int offr, int shCount)
5484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5485 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5486 ((offl + MSB16) == offr)){
5487 /* don't crash result[offr] */
5488 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5489 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5491 movLeft2Result(left,offl, result, offr, 0);
5492 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5494 /* ax << shCount (x = lsb(result))*/
5495 AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5496 aopPut(AOP(result),"a",offr+MSB16);
5500 /*-----------------------------------------------------------------*/
5501 /* shiftR2Left2Result - shift right two bytes from left to result */
5502 /*-----------------------------------------------------------------*/
5503 static void shiftR2Left2Result (operand *left, int offl,
5504 operand *result, int offr,
5505 int shCount, int sign)
5507 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5508 if(pic14_sameRegs(AOP(result), AOP(left)) &&
5509 ((offl + MSB16) == offr)){
5510 /* don't crash result[offr] */
5511 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5512 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5514 movLeft2Result(left,offl, result, offr, 0);
5515 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
5517 /* a:x >> shCount (x = lsb(result))*/
5519 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5521 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
5522 if(pic14_getDataSize(result) > 1)
5523 aopPut(AOP(result),"a",offr+MSB16);
5526 /*-----------------------------------------------------------------*/
5527 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
5528 /*-----------------------------------------------------------------*/
5529 static void shiftLLeftOrResult (operand *left, int offl,
5530 operand *result, int offr, int shCount)
5532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5533 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5534 /* shift left accumulator */
5536 /* or with result */
5537 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5538 /* back to result */
5539 aopPut(AOP(result),"a",offr);
5542 /*-----------------------------------------------------------------*/
5543 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
5544 /*-----------------------------------------------------------------*/
5545 static void shiftRLeftOrResult (operand *left, int offl,
5546 operand *result, int offr, int shCount)
5548 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5549 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5550 /* shift right accumulator */
5552 /* or with result */
5553 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
5554 /* back to result */
5555 aopPut(AOP(result),"a",offr);
5558 /*-----------------------------------------------------------------*/
5559 /* genlshOne - left shift a one byte quantity by known count */
5560 /*-----------------------------------------------------------------*/
5561 static void genlshOne (operand *result, operand *left, int shCount)
5563 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5564 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5567 /*-----------------------------------------------------------------*/
5568 /* genlshTwo - left shift two bytes by known amount != 0 */
5569 /*-----------------------------------------------------------------*/
5570 static void genlshTwo (operand *result,operand *left, int shCount)
5574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5575 size = pic14_getDataSize(result);
5577 /* if shCount >= 8 */
5583 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5585 movLeft2Result(left, LSB, result, MSB16, 0);
5587 aopPut(AOP(result),zero,LSB);
5590 /* 1 <= shCount <= 7 */
5593 shiftL1Left2Result(left, LSB, result, LSB, shCount);
5595 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5599 /*-----------------------------------------------------------------*/
5600 /* shiftLLong - shift left one long from left to result */
5601 /* offl = LSB or MSB16 */
5602 /*-----------------------------------------------------------------*/
5603 static void shiftLLong (operand *left, operand *result, int offr )
5606 int size = AOP_SIZE(result);
5608 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5609 if(size >= LSB+offr){
5610 l = aopGet(AOP(left),LSB,FALSE,FALSE);
5612 pic14_emitcode("add","a,acc");
5613 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5614 size >= MSB16+offr && offr != LSB )
5615 pic14_emitcode("xch","a,%s",
5616 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
5618 aopPut(AOP(result),"a",LSB+offr);
5621 if(size >= MSB16+offr){
5622 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
5623 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
5626 pic14_emitcode("rlc","a");
5627 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5628 size >= MSB24+offr && offr != LSB)
5629 pic14_emitcode("xch","a,%s",
5630 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
5632 aopPut(AOP(result),"a",MSB16+offr);
5635 if(size >= MSB24+offr){
5636 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
5637 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
5640 pic14_emitcode("rlc","a");
5641 if (pic14_sameRegs(AOP(left),AOP(result)) &&
5642 size >= MSB32+offr && offr != LSB )
5643 pic14_emitcode("xch","a,%s",
5644 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
5646 aopPut(AOP(result),"a",MSB24+offr);
5649 if(size > MSB32+offr){
5650 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
5651 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
5654 pic14_emitcode("rlc","a");
5655 aopPut(AOP(result),"a",MSB32+offr);
5658 aopPut(AOP(result),zero,LSB);
5661 /*-----------------------------------------------------------------*/
5662 /* genlshFour - shift four byte by a known amount != 0 */
5663 /*-----------------------------------------------------------------*/
5664 static void genlshFour (operand *result, operand *left, int shCount)
5668 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5669 size = AOP_SIZE(result);
5671 /* if shifting more that 3 bytes */
5672 if (shCount >= 24 ) {
5675 /* lowest order of left goes to the highest
5676 order of the destination */
5677 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
5679 movLeft2Result(left, LSB, result, MSB32, 0);
5680 aopPut(AOP(result),zero,LSB);
5681 aopPut(AOP(result),zero,MSB16);
5682 aopPut(AOP(result),zero,MSB32);
5686 /* more than two bytes */
5687 else if ( shCount >= 16 ) {
5688 /* lower order two bytes goes to higher order two bytes */
5690 /* if some more remaining */
5692 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
5694 movLeft2Result(left, MSB16, result, MSB32, 0);
5695 movLeft2Result(left, LSB, result, MSB24, 0);
5697 aopPut(AOP(result),zero,MSB16);
5698 aopPut(AOP(result),zero,LSB);
5702 /* if more than 1 byte */
5703 else if ( shCount >= 8 ) {
5704 /* lower order three bytes goes to higher order three bytes */
5708 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5710 movLeft2Result(left, LSB, result, MSB16, 0);
5712 else{ /* size = 4 */
5714 movLeft2Result(left, MSB24, result, MSB32, 0);
5715 movLeft2Result(left, MSB16, result, MSB24, 0);
5716 movLeft2Result(left, LSB, result, MSB16, 0);
5717 aopPut(AOP(result),zero,LSB);
5719 else if(shCount == 1)
5720 shiftLLong(left, result, MSB16);
5722 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
5723 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
5724 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
5725 aopPut(AOP(result),zero,LSB);
5730 /* 1 <= shCount <= 7 */
5731 else if(shCount <= 2){
5732 shiftLLong(left, result, LSB);
5734 shiftLLong(result, result, LSB);
5736 /* 3 <= shCount <= 7, optimize */
5738 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
5739 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
5740 shiftL2Left2Result(left, LSB, result, LSB, shCount);
5744 /*-----------------------------------------------------------------*/
5745 /* genLeftShiftLiteral - left shifting by known count */
5746 /*-----------------------------------------------------------------*/
5747 static void genLeftShiftLiteral (operand *left,
5752 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
5755 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5756 freeAsmop(right,NULL,ic,TRUE);
5758 aopOp(left,ic,FALSE);
5759 aopOp(result,ic,FALSE);
5761 size = getSize(operandType(result));
5764 pic14_emitcode("; shift left ","result %d, left %d",size,
5768 /* I suppose that the left size >= result size */
5771 movLeft2Result(left, size, result, size, 0);
5775 else if(shCount >= (size * 8))
5777 aopPut(AOP(result),zero,size);
5781 genlshOne (result,left,shCount);
5786 genlshTwo (result,left,shCount);
5790 genlshFour (result,left,shCount);
5794 freeAsmop(left,NULL,ic,TRUE);
5795 freeAsmop(result,NULL,ic,TRUE);
5798 /*-----------------------------------------------------------------*/
5799 /* genLeftShift - generates code for left shifting */
5800 /*-----------------------------------------------------------------*/
5801 static void genLeftShift (iCode *ic)
5803 operand *left,*right, *result;
5806 symbol *tlbl , *tlbl1;
5808 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5810 right = IC_RIGHT(ic);
5812 result = IC_RESULT(ic);
5814 aopOp(right,ic,FALSE);
5816 /* if the shift count is known then do it
5817 as efficiently as possible */
5818 if (AOP_TYPE(right) == AOP_LIT) {
5819 genLeftShiftLiteral (left,right,result,ic);
5823 /* shift count is unknown then we have to form
5824 a loop get the loop count in B : Note: we take
5825 only the lower order byte since shifting
5826 more that 32 bits make no sense anyway, ( the
5827 largest size of an object can be only 32 bits ) */
5829 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
5830 pic14_emitcode("inc","b");
5831 freeAsmop (right,NULL,ic,TRUE);
5832 aopOp(left,ic,FALSE);
5833 aopOp(result,ic,FALSE);
5835 /* now move the left to the result if they are not the
5837 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
5838 AOP_SIZE(result) > 1) {
5840 size = AOP_SIZE(result);
5843 l = aopGet(AOP(left),offset,FALSE,TRUE);
5844 if (*l == '@' && (IS_AOP_PREG(result))) {
5846 pic14_emitcode("mov","a,%s",l);
5847 aopPut(AOP(result),"a",offset);
5849 aopPut(AOP(result),l,offset);
5854 tlbl = newiTempLabel(NULL);
5855 size = AOP_SIZE(result);
5857 tlbl1 = newiTempLabel(NULL);
5859 /* if it is only one byte then */
5861 symbol *tlbl1 = newiTempLabel(NULL);
5863 l = aopGet(AOP(left),0,FALSE,FALSE);
5865 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5866 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5867 pic14_emitcode("add","a,acc");
5868 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5869 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5870 aopPut(AOP(result),"a",0);
5874 reAdjustPreg(AOP(result));
5876 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
5877 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5878 l = aopGet(AOP(result),offset,FALSE,FALSE);
5880 pic14_emitcode("add","a,acc");
5881 aopPut(AOP(result),"a",offset++);
5883 l = aopGet(AOP(result),offset,FALSE,FALSE);
5885 pic14_emitcode("rlc","a");
5886 aopPut(AOP(result),"a",offset++);
5888 reAdjustPreg(AOP(result));
5890 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
5891 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
5893 freeAsmop(left,NULL,ic,TRUE);
5894 freeAsmop(result,NULL,ic,TRUE);
5897 /*-----------------------------------------------------------------*/
5898 /* genrshOne - right shift a one byte quantity by known count */
5899 /*-----------------------------------------------------------------*/
5900 static void genrshOne (operand *result, operand *left,
5901 int shCount, int sign)
5903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5904 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
5907 /*-----------------------------------------------------------------*/
5908 /* genrshTwo - right shift two bytes by known amount != 0 */
5909 /*-----------------------------------------------------------------*/
5910 static void genrshTwo (operand *result,operand *left,
5911 int shCount, int sign)
5913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5914 /* if shCount >= 8 */
5918 shiftR1Left2Result(left, MSB16, result, LSB,
5921 movLeft2Result(left, MSB16, result, LSB, sign);
5922 addSign(result, MSB16, sign);
5925 /* 1 <= shCount <= 7 */
5927 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
5930 /*-----------------------------------------------------------------*/
5931 /* shiftRLong - shift right one long from left to result */
5932 /* offl = LSB or MSB16 */
5933 /*-----------------------------------------------------------------*/
5934 static void shiftRLong (operand *left, int offl,
5935 operand *result, int sign)
5937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5939 pic14_emitcode("clr","c");
5940 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
5942 pic14_emitcode("mov","c,acc.7");
5943 pic14_emitcode("rrc","a");
5944 aopPut(AOP(result),"a",MSB32-offl);
5946 /* add sign of "a" */
5947 addSign(result, MSB32, sign);
5949 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
5950 pic14_emitcode("rrc","a");
5951 aopPut(AOP(result),"a",MSB24-offl);
5953 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
5954 pic14_emitcode("rrc","a");
5955 aopPut(AOP(result),"a",MSB16-offl);
5958 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
5959 pic14_emitcode("rrc","a");
5960 aopPut(AOP(result),"a",LSB);
5964 /*-----------------------------------------------------------------*/
5965 /* genrshFour - shift four byte by a known amount != 0 */
5966 /*-----------------------------------------------------------------*/
5967 static void genrshFour (operand *result, operand *left,
5968 int shCount, int sign)
5970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5971 /* if shifting more that 3 bytes */
5972 if(shCount >= 24 ) {
5975 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
5977 movLeft2Result(left, MSB32, result, LSB, sign);
5978 addSign(result, MSB16, sign);
5980 else if(shCount >= 16){
5983 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
5985 movLeft2Result(left, MSB24, result, LSB, 0);
5986 movLeft2Result(left, MSB32, result, MSB16, sign);
5988 addSign(result, MSB24, sign);
5990 else if(shCount >= 8){
5993 shiftRLong(left, MSB16, result, sign);
5994 else if(shCount == 0){
5995 movLeft2Result(left, MSB16, result, LSB, 0);
5996 movLeft2Result(left, MSB24, result, MSB16, 0);
5997 movLeft2Result(left, MSB32, result, MSB24, sign);
5998 addSign(result, MSB32, sign);
6001 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6002 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6003 /* the last shift is signed */
6004 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6005 addSign(result, MSB32, sign);
6008 else{ /* 1 <= shCount <= 7 */
6010 shiftRLong(left, LSB, result, sign);
6012 shiftRLong(result, LSB, result, sign);
6015 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6016 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6017 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6022 /*-----------------------------------------------------------------*/
6023 /* genRightShiftLiteral - right shifting by known count */
6024 /*-----------------------------------------------------------------*/
6025 static void genRightShiftLiteral (operand *left,
6031 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6034 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6035 freeAsmop(right,NULL,ic,TRUE);
6037 aopOp(left,ic,FALSE);
6038 aopOp(result,ic,FALSE);
6041 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6045 size = pic14_getDataSize(left);
6046 /* test the LEFT size !!! */
6048 /* I suppose that the left size >= result size */
6050 size = pic14_getDataSize(result);
6052 movLeft2Result(left, size, result, size, 0);
6055 else if(shCount >= (size * 8)){
6057 /* get sign in acc.7 */
6058 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6059 addSign(result, LSB, sign);
6063 genrshOne (result,left,shCount,sign);
6067 genrshTwo (result,left,shCount,sign);
6071 genrshFour (result,left,shCount,sign);
6077 freeAsmop(left,NULL,ic,TRUE);
6078 freeAsmop(result,NULL,ic,TRUE);
6082 /*-----------------------------------------------------------------*/
6083 /* genSignedRightShift - right shift of signed number */
6084 /*-----------------------------------------------------------------*/
6085 static void genSignedRightShift (iCode *ic)
6087 operand *right, *left, *result;
6090 symbol *tlbl, *tlbl1 ;
6092 /* we do it the hard way put the shift count in b
6093 and loop thru preserving the sign */
6094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 right = IC_RIGHT(ic);
6098 result = IC_RESULT(ic);
6100 aopOp(right,ic,FALSE);
6103 if ( AOP_TYPE(right) == AOP_LIT) {
6104 genRightShiftLiteral (left,right,result,ic,1);
6107 /* shift count is unknown then we have to form
6108 a loop get the loop count in B : Note: we take
6109 only the lower order byte since shifting
6110 more that 32 bits make no sense anyway, ( the
6111 largest size of an object can be only 32 bits ) */
6113 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6114 pic14_emitcode("inc","b");
6115 freeAsmop (right,NULL,ic,TRUE);
6116 aopOp(left,ic,FALSE);
6117 aopOp(result,ic,FALSE);
6119 /* now move the left to the result if they are not the
6121 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6122 AOP_SIZE(result) > 1) {
6124 size = AOP_SIZE(result);
6127 l = aopGet(AOP(left),offset,FALSE,TRUE);
6128 if (*l == '@' && IS_AOP_PREG(result)) {
6130 pic14_emitcode("mov","a,%s",l);
6131 aopPut(AOP(result),"a",offset);
6133 aopPut(AOP(result),l,offset);
6138 /* mov the highest order bit to OVR */
6139 tlbl = newiTempLabel(NULL);
6140 tlbl1= newiTempLabel(NULL);
6142 size = AOP_SIZE(result);
6144 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6145 pic14_emitcode("rlc","a");
6146 pic14_emitcode("mov","ov,c");
6147 /* if it is only one byte then */
6149 l = aopGet(AOP(left),0,FALSE,FALSE);
6151 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6152 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6153 pic14_emitcode("mov","c,ov");
6154 pic14_emitcode("rrc","a");
6155 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6156 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6157 aopPut(AOP(result),"a",0);
6161 reAdjustPreg(AOP(result));
6162 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6163 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6164 pic14_emitcode("mov","c,ov");
6166 l = aopGet(AOP(result),offset,FALSE,FALSE);
6168 pic14_emitcode("rrc","a");
6169 aopPut(AOP(result),"a",offset--);
6171 reAdjustPreg(AOP(result));
6172 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6173 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6176 freeAsmop(left,NULL,ic,TRUE);
6177 freeAsmop(result,NULL,ic,TRUE);
6180 /*-----------------------------------------------------------------*/
6181 /* genRightShift - generate code for right shifting */
6182 /*-----------------------------------------------------------------*/
6183 static void genRightShift (iCode *ic)
6185 operand *right, *left, *result;
6189 symbol *tlbl, *tlbl1 ;
6191 /* if signed then we do it the hard way preserve the
6192 sign bit moving it inwards */
6193 retype = getSpec(operandType(IC_RESULT(ic)));
6194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6196 if (!SPEC_USIGN(retype)) {
6197 genSignedRightShift (ic);
6201 /* signed & unsigned types are treated the same : i.e. the
6202 signed is NOT propagated inwards : quoting from the
6203 ANSI - standard : "for E1 >> E2, is equivalent to division
6204 by 2**E2 if unsigned or if it has a non-negative value,
6205 otherwise the result is implementation defined ", MY definition
6206 is that the sign does not get propagated */
6208 right = IC_RIGHT(ic);
6210 result = IC_RESULT(ic);
6212 aopOp(right,ic,FALSE);
6214 /* if the shift count is known then do it
6215 as efficiently as possible */
6216 if (AOP_TYPE(right) == AOP_LIT) {
6217 genRightShiftLiteral (left,right,result,ic, 0);
6221 /* shift count is unknown then we have to form
6222 a loop get the loop count in B : Note: we take
6223 only the lower order byte since shifting
6224 more that 32 bits make no sense anyway, ( the
6225 largest size of an object can be only 32 bits ) */
6227 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6228 pic14_emitcode("inc","b");
6229 freeAsmop (right,NULL,ic,TRUE);
6230 aopOp(left,ic,FALSE);
6231 aopOp(result,ic,FALSE);
6233 /* now move the left to the result if they are not the
6235 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6236 AOP_SIZE(result) > 1) {
6238 size = AOP_SIZE(result);
6241 l = aopGet(AOP(left),offset,FALSE,TRUE);
6242 if (*l == '@' && IS_AOP_PREG(result)) {
6244 pic14_emitcode("mov","a,%s",l);
6245 aopPut(AOP(result),"a",offset);
6247 aopPut(AOP(result),l,offset);
6252 tlbl = newiTempLabel(NULL);
6253 tlbl1= newiTempLabel(NULL);
6254 size = AOP_SIZE(result);
6257 /* if it is only one byte then */
6259 l = aopGet(AOP(left),0,FALSE,FALSE);
6261 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6262 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6264 pic14_emitcode("rrc","a");
6265 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6266 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6267 aopPut(AOP(result),"a",0);
6271 reAdjustPreg(AOP(result));
6272 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6273 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6276 l = aopGet(AOP(result),offset,FALSE,FALSE);
6278 pic14_emitcode("rrc","a");
6279 aopPut(AOP(result),"a",offset--);
6281 reAdjustPreg(AOP(result));
6283 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6284 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6287 freeAsmop(left,NULL,ic,TRUE);
6288 freeAsmop(result,NULL,ic,TRUE);
6291 /*-----------------------------------------------------------------*/
6292 /* genUnpackBits - generates code for unpacking bits */
6293 /*-----------------------------------------------------------------*/
6294 static void genUnpackBits (operand *result, char *rname, int ptype)
6301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6302 etype = getSpec(operandType(result));
6304 /* read the first byte */
6309 pic14_emitcode("mov","a,@%s",rname);
6313 pic14_emitcode("movx","a,@%s",rname);
6317 pic14_emitcode("movx","a,@dptr");
6321 pic14_emitcode("clr","a");
6322 pic14_emitcode("movc","a","@a+dptr");
6326 pic14_emitcode("lcall","__gptrget");
6330 /* if we have bitdisplacement then it fits */
6331 /* into this byte completely or if length is */
6332 /* less than a byte */
6333 if ((shCnt = SPEC_BSTR(etype)) ||
6334 (SPEC_BLEN(etype) <= 8)) {
6336 /* shift right acc */
6339 pic14_emitcode("anl","a,#0x%02x",
6340 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6341 aopPut(AOP(result),"a",offset);
6345 /* bit field did not fit in a byte */
6346 rlen = SPEC_BLEN(etype) - 8;
6347 aopPut(AOP(result),"a",offset++);
6354 pic14_emitcode("inc","%s",rname);
6355 pic14_emitcode("mov","a,@%s",rname);
6359 pic14_emitcode("inc","%s",rname);
6360 pic14_emitcode("movx","a,@%s",rname);
6364 pic14_emitcode("inc","dptr");
6365 pic14_emitcode("movx","a,@dptr");
6369 pic14_emitcode("clr","a");
6370 pic14_emitcode("inc","dptr");
6371 pic14_emitcode("movc","a","@a+dptr");
6375 pic14_emitcode("inc","dptr");
6376 pic14_emitcode("lcall","__gptrget");
6381 /* if we are done */
6385 aopPut(AOP(result),"a",offset++);
6390 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
6391 aopPut(AOP(result),"a",offset);
6398 /*-----------------------------------------------------------------*/
6399 /* genDataPointerGet - generates code when ptr offset is known */
6400 /*-----------------------------------------------------------------*/
6401 static void genDataPointerGet (operand *left,
6405 int size , offset = 0;
6408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6411 /* optimization - most of the time, left and result are the same
6412 * address, but different types. for the pic code, we could omit
6416 aopOp(result,ic,TRUE);
6418 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
6420 size = AOP_SIZE(result);
6423 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
6427 freeAsmop(left,NULL,ic,TRUE);
6428 freeAsmop(result,NULL,ic,TRUE);
6431 /*-----------------------------------------------------------------*/
6432 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
6433 /*-----------------------------------------------------------------*/
6434 static void genNearPointerGet (operand *left,
6441 sym_link *rtype, *retype;
6442 sym_link *ltype = operandType(left);
6445 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6447 rtype = operandType(result);
6448 retype= getSpec(rtype);
6450 aopOp(left,ic,FALSE);
6452 /* if left is rematerialisable and
6453 result is not bit variable type and
6454 the left is pointer to data space i.e
6455 lower 128 bytes of space */
6456 if (AOP_TYPE(left) == AOP_IMMD &&
6457 !IS_BITVAR(retype) &&
6458 DCL_TYPE(ltype) == POINTER) {
6459 genDataPointerGet (left,result,ic);
6463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6465 /* if the value is already in a pointer register
6466 then don't need anything more */
6467 if (!AOP_INPREG(AOP(left))) {
6468 /* otherwise get a free pointer register */
6469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6471 preg = getFreePtr(ic,&aop,FALSE);
6472 pic14_emitcode("mov","%s,%s",
6474 aopGet(AOP(left),0,FALSE,TRUE));
6475 rname = preg->name ;
6477 rname = aopGet(AOP(left),0,FALSE,FALSE);
6479 freeAsmop(left,NULL,ic,TRUE);
6480 aopOp (result,ic,FALSE);
6482 /* if bitfield then unpack the bits */
6483 if (IS_BITVAR(retype))
6484 genUnpackBits (result,rname,POINTER);
6486 /* we have can just get the values */
6487 int size = AOP_SIZE(result);
6490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6492 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
6494 pic14_emitcode("mov","a,@%s",rname);
6495 aopPut(AOP(result),"a",offset);
6497 sprintf(buffer,"@%s",rname);
6498 aopPut(AOP(result),buffer,offset);
6502 pic14_emitcode("inc","%s",rname);
6506 /* now some housekeeping stuff */
6508 /* we had to allocate for this iCode */
6509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6510 freeAsmop(NULL,aop,ic,TRUE);
6512 /* we did not allocate which means left
6513 already in a pointer register, then
6514 if size > 0 && this could be used again
6515 we have to point it back to where it
6517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6518 if (AOP_SIZE(result) > 1 &&
6519 !OP_SYMBOL(left)->remat &&
6520 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6522 int size = AOP_SIZE(result) - 1;
6524 pic14_emitcode("dec","%s",rname);
6529 freeAsmop(result,NULL,ic,TRUE);
6533 /*-----------------------------------------------------------------*/
6534 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
6535 /*-----------------------------------------------------------------*/
6536 static void genPagedPointerGet (operand *left,
6543 sym_link *rtype, *retype;
6545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6547 rtype = operandType(result);
6548 retype= getSpec(rtype);
6550 aopOp(left,ic,FALSE);
6552 /* if the value is already in a pointer register
6553 then don't need anything more */
6554 if (!AOP_INPREG(AOP(left))) {
6555 /* otherwise get a free pointer register */
6557 preg = getFreePtr(ic,&aop,FALSE);
6558 pic14_emitcode("mov","%s,%s",
6560 aopGet(AOP(left),0,FALSE,TRUE));
6561 rname = preg->name ;
6563 rname = aopGet(AOP(left),0,FALSE,FALSE);
6565 freeAsmop(left,NULL,ic,TRUE);
6566 aopOp (result,ic,FALSE);
6568 /* if bitfield then unpack the bits */
6569 if (IS_BITVAR(retype))
6570 genUnpackBits (result,rname,PPOINTER);
6572 /* we have can just get the values */
6573 int size = AOP_SIZE(result);
6578 pic14_emitcode("movx","a,@%s",rname);
6579 aopPut(AOP(result),"a",offset);
6584 pic14_emitcode("inc","%s",rname);
6588 /* now some housekeeping stuff */
6590 /* we had to allocate for this iCode */
6591 freeAsmop(NULL,aop,ic,TRUE);
6593 /* we did not allocate which means left
6594 already in a pointer register, then
6595 if size > 0 && this could be used again
6596 we have to point it back to where it
6598 if (AOP_SIZE(result) > 1 &&
6599 !OP_SYMBOL(left)->remat &&
6600 ( OP_SYMBOL(left)->liveTo > ic->seq ||
6602 int size = AOP_SIZE(result) - 1;
6604 pic14_emitcode("dec","%s",rname);
6609 freeAsmop(result,NULL,ic,TRUE);
6614 /*-----------------------------------------------------------------*/
6615 /* genFarPointerGet - gget value from far space */
6616 /*-----------------------------------------------------------------*/
6617 static void genFarPointerGet (operand *left,
6618 operand *result, iCode *ic)
6621 sym_link *retype = getSpec(operandType(result));
6623 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6625 aopOp(left,ic,FALSE);
6627 /* if the operand is already in dptr
6628 then we do nothing else we move the value to dptr */
6629 if (AOP_TYPE(left) != AOP_STR) {
6630 /* if this is remateriazable */
6631 if (AOP_TYPE(left) == AOP_IMMD)
6632 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6633 else { /* we need to get it byte by byte */
6634 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6635 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6636 if (options.model == MODEL_FLAT24)
6638 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6642 /* so dptr know contains the address */
6643 freeAsmop(left,NULL,ic,TRUE);
6644 aopOp(result,ic,FALSE);
6646 /* if bit then unpack */
6647 if (IS_BITVAR(retype))
6648 genUnpackBits(result,"dptr",FPOINTER);
6650 size = AOP_SIZE(result);
6654 pic14_emitcode("movx","a,@dptr");
6655 aopPut(AOP(result),"a",offset++);
6657 pic14_emitcode("inc","dptr");
6661 freeAsmop(result,NULL,ic,TRUE);
6664 /*-----------------------------------------------------------------*/
6665 /* pic14_emitcodePointerGet - gget value from code space */
6666 /*-----------------------------------------------------------------*/
6667 static void pic14_emitcodePointerGet (operand *left,
6668 operand *result, iCode *ic)
6671 sym_link *retype = getSpec(operandType(result));
6673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6675 aopOp(left,ic,FALSE);
6677 /* if the operand is already in dptr
6678 then we do nothing else we move the value to dptr */
6679 if (AOP_TYPE(left) != AOP_STR) {
6680 /* if this is remateriazable */
6681 if (AOP_TYPE(left) == AOP_IMMD)
6682 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6683 else { /* we need to get it byte by byte */
6684 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6685 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6686 if (options.model == MODEL_FLAT24)
6688 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6692 /* so dptr know contains the address */
6693 freeAsmop(left,NULL,ic,TRUE);
6694 aopOp(result,ic,FALSE);
6696 /* if bit then unpack */
6697 if (IS_BITVAR(retype))
6698 genUnpackBits(result,"dptr",CPOINTER);
6700 size = AOP_SIZE(result);
6704 pic14_emitcode("clr","a");
6705 pic14_emitcode("movc","a,@a+dptr");
6706 aopPut(AOP(result),"a",offset++);
6708 pic14_emitcode("inc","dptr");
6712 freeAsmop(result,NULL,ic,TRUE);
6715 /*-----------------------------------------------------------------*/
6716 /* genGenPointerGet - gget value from generic pointer space */
6717 /*-----------------------------------------------------------------*/
6718 static void genGenPointerGet (operand *left,
6719 operand *result, iCode *ic)
6722 sym_link *retype = getSpec(operandType(result));
6724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6725 aopOp(left,ic,FALSE);
6727 /* if the operand is already in dptr
6728 then we do nothing else we move the value to dptr */
6729 if (AOP_TYPE(left) != AOP_STR) {
6730 /* if this is remateriazable */
6731 if (AOP_TYPE(left) == AOP_IMMD) {
6732 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
6733 pic14_emitcode("mov","b,#%d",pointerCode(retype));
6735 else { /* we need to get it byte by byte */
6736 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6737 //emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
6738 //emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
6739 pic14_emitcode("movf","%s,w",aopGet(AOP(left),0,FALSE,FALSE));
6740 pic14_emitcode("movwf","FSR");
6742 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
6743 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
6744 if (options.model == MODEL_FLAT24)
6746 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
6747 pic14_emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
6751 pic14_emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
6756 /* so dptr know contains the address */
6757 freeAsmop(left,NULL,ic,TRUE);
6758 aopOp(result,ic,FALSE);
6760 /* if bit then unpack */
6761 if (IS_BITVAR(retype))
6762 genUnpackBits(result,"dptr",GPOINTER);
6764 size = AOP_SIZE(result);
6768 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
6770 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
6772 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
6774 pic14_emitcode("movf","indf,w");
6775 pic14_emitcode("movwf","%s",
6776 aopGet(AOP(result),offset++,FALSE,FALSE));
6778 pic14_emitcode("incf","fsr,f");
6783 freeAsmop(result,NULL,ic,TRUE);
6786 /*-----------------------------------------------------------------*/
6787 /* genPointerGet - generate code for pointer get */
6788 /*-----------------------------------------------------------------*/
6789 static void genPointerGet (iCode *ic)
6791 operand *left, *result ;
6792 sym_link *type, *etype;
6795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6798 result = IC_RESULT(ic) ;
6800 /* depending on the type of pointer we need to
6801 move it to the correct pointer register */
6802 type = operandType(left);
6803 etype = getSpec(type);
6804 /* if left is of type of pointer then it is simple */
6805 if (IS_PTR(type) && !IS_FUNC(type->next))
6806 p_type = DCL_TYPE(type);
6808 /* we have to go by the storage class */
6809 p_type = PTR_TYPE(SPEC_OCLS(etype));
6811 /* if (SPEC_OCLS(etype)->codesp ) { */
6812 /* p_type = CPOINTER ; */
6815 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
6816 /* p_type = FPOINTER ; */
6818 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
6819 /* p_type = PPOINTER; */
6821 /* if (SPEC_OCLS(etype) == idata ) */
6822 /* p_type = IPOINTER; */
6824 /* p_type = POINTER ; */
6827 /* now that we have the pointer type we assign
6828 the pointer values */
6833 genNearPointerGet (left,result,ic);
6837 genPagedPointerGet(left,result,ic);
6841 genFarPointerGet (left,result,ic);
6845 pic14_emitcodePointerGet (left,result,ic);
6849 genGenPointerGet (left,result,ic);
6855 /*-----------------------------------------------------------------*/
6856 /* genPackBits - generates code for packed bit storage */
6857 /*-----------------------------------------------------------------*/
6858 static void genPackBits (sym_link *etype ,
6860 char *rname, int p_type)
6868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6869 blen = SPEC_BLEN(etype);
6870 bstr = SPEC_BSTR(etype);
6872 l = aopGet(AOP(right),offset++,FALSE,FALSE);
6875 /* if the bit lenth is less than or */
6876 /* it exactly fits a byte then */
6877 if (SPEC_BLEN(etype) <= 8 ) {
6878 shCount = SPEC_BSTR(etype) ;
6880 /* shift left acc */
6883 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
6888 pic14_emitcode ("mov","b,a");
6889 pic14_emitcode("mov","a,@%s",rname);
6893 pic14_emitcode ("mov","b,a");
6894 pic14_emitcode("movx","a,@dptr");
6898 pic14_emitcode ("push","b");
6899 pic14_emitcode ("push","acc");
6900 pic14_emitcode ("lcall","__gptrget");
6901 pic14_emitcode ("pop","b");
6905 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
6906 ((unsigned char)(0xFF << (blen+bstr)) |
6907 (unsigned char)(0xFF >> (8-bstr)) ) );
6908 pic14_emitcode ("orl","a,b");
6909 if (p_type == GPOINTER)
6910 pic14_emitcode("pop","b");
6916 pic14_emitcode("mov","@%s,a",rname);
6920 pic14_emitcode("movx","@dptr,a");
6924 DEBUGpic14_emitcode(";lcall","__gptrput");
6929 if ( SPEC_BLEN(etype) <= 8 )
6932 pic14_emitcode("inc","%s",rname);
6933 rLen = SPEC_BLEN(etype) ;
6935 /* now generate for lengths greater than one byte */
6938 l = aopGet(AOP(right),offset++,FALSE,TRUE);
6948 pic14_emitcode("mov","@%s,a",rname);
6950 pic14_emitcode("mov","@%s,%s",rname,l);
6955 pic14_emitcode("movx","@dptr,a");
6960 DEBUGpic14_emitcode(";lcall","__gptrput");
6963 pic14_emitcode ("inc","%s",rname);
6968 /* last last was not complete */
6970 /* save the byte & read byte */
6973 pic14_emitcode ("mov","b,a");
6974 pic14_emitcode("mov","a,@%s",rname);
6978 pic14_emitcode ("mov","b,a");
6979 pic14_emitcode("movx","a,@dptr");
6983 pic14_emitcode ("push","b");
6984 pic14_emitcode ("push","acc");
6985 pic14_emitcode ("lcall","__gptrget");
6986 pic14_emitcode ("pop","b");
6990 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
6991 pic14_emitcode ("orl","a,b");
6994 if (p_type == GPOINTER)
6995 pic14_emitcode("pop","b");
7000 pic14_emitcode("mov","@%s,a",rname);
7004 pic14_emitcode("movx","@dptr,a");
7008 DEBUGpic14_emitcode(";lcall","__gptrput");
7012 /*-----------------------------------------------------------------*/
7013 /* genDataPointerSet - remat pointer to data space */
7014 /*-----------------------------------------------------------------*/
7015 static void genDataPointerSet(operand *right,
7019 int size, offset = 0 ;
7020 char *l, buffer[256];
7022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7023 aopOp(right,ic,FALSE);
7025 l = aopGet(AOP(result),0,FALSE,TRUE);
7026 size = AOP_SIZE(right);
7027 // tsd, was l+1 - the underline `_' prefix was being stripped
7030 sprintf(buffer,"(%s + %d)",l,offset);
7032 sprintf(buffer,"%s",l);
7034 if (AOP_TYPE(right) == AOP_LIT) {
7035 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7036 lit = lit >> (8*offset);
7038 pic14_emitcode("movlw","%d",lit);
7039 pic14_emitcode("movwf","%s",buffer);
7041 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7042 emitpcode(POC_MOVWF, popRegFromString(buffer));
7045 pic14_emitcode("clrf","%s",buffer);
7046 emitpcode(POC_CLRF, popRegFromString(buffer));
7049 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7050 pic14_emitcode("movwf","%s",buffer);
7052 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7053 emitpcode(POC_MOVWF, popRegFromString(buffer));
7060 freeAsmop(right,NULL,ic,TRUE);
7061 freeAsmop(result,NULL,ic,TRUE);
7064 /*-----------------------------------------------------------------*/
7065 /* genNearPointerSet - pic14_emitcode for near pointer put */
7066 /*-----------------------------------------------------------------*/
7067 static void genNearPointerSet (operand *right,
7074 sym_link *ptype = operandType(result);
7077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7078 retype= getSpec(operandType(right));
7080 aopOp(result,ic,FALSE);
7082 /* if the result is rematerializable &
7083 in data space & not a bit variable */
7084 if (AOP_TYPE(result) == AOP_IMMD &&
7085 DCL_TYPE(ptype) == POINTER &&
7086 !IS_BITVAR(retype)) {
7087 genDataPointerSet (right,result,ic);
7091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7093 /* if the value is already in a pointer register
7094 then don't need anything more */
7095 if (!AOP_INPREG(AOP(result))) {
7096 /* otherwise get a free pointer register */
7097 //aop = newAsmop(0);
7098 //preg = getFreePtr(ic,&aop,FALSE);
7099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7100 //pic14_emitcode("mov","%s,%s",
7102 // aopGet(AOP(result),0,FALSE,TRUE));
7103 //rname = preg->name ;
7104 pic14_emitcode("movwf","fsr");
7106 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7108 freeAsmop(result,NULL,ic,TRUE);
7109 aopOp (right,ic,FALSE);
7110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7112 /* if bitfield then unpack the bits */
7113 if (IS_BITVAR(retype)) {
7114 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7115 "The programmer is obviously confused");
7116 //genPackBits (retype,right,rname,POINTER);
7120 /* we have can just get the values */
7121 int size = AOP_SIZE(right);
7124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7126 l = aopGet(AOP(right),offset,FALSE,TRUE);
7129 //pic14_emitcode("mov","@%s,a",rname);
7130 pic14_emitcode("movf","indf,w ;1");
7133 if (AOP_TYPE(right) == AOP_LIT) {
7134 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7136 pic14_emitcode("movlw","%s",l);
7137 pic14_emitcode("movwf","indf ;2");
7139 pic14_emitcode("clrf","indf");
7141 pic14_emitcode("movf","%s,w",l);
7142 pic14_emitcode("movwf","indf ;2");
7144 //pic14_emitcode("mov","@%s,%s",rname,l);
7147 pic14_emitcode("incf","fsr,f ;3");
7148 //pic14_emitcode("inc","%s",rname);
7153 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7154 /* now some housekeeping stuff */
7156 /* we had to allocate for this iCode */
7157 freeAsmop(NULL,aop,ic,TRUE);
7159 /* we did not allocate which means left
7160 already in a pointer register, then
7161 if size > 0 && this could be used again
7162 we have to point it back to where it
7164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7165 if (AOP_SIZE(right) > 1 &&
7166 !OP_SYMBOL(result)->remat &&
7167 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7169 int size = AOP_SIZE(right) - 1;
7171 pic14_emitcode("decf","fsr,f");
7172 //pic14_emitcode("dec","%s",rname);
7176 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7178 freeAsmop(right,NULL,ic,TRUE);
7183 /*-----------------------------------------------------------------*/
7184 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7185 /*-----------------------------------------------------------------*/
7186 static void genPagedPointerSet (operand *right,
7195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7197 retype= getSpec(operandType(right));
7199 aopOp(result,ic,FALSE);
7201 /* if the value is already in a pointer register
7202 then don't need anything more */
7203 if (!AOP_INPREG(AOP(result))) {
7204 /* otherwise get a free pointer register */
7206 preg = getFreePtr(ic,&aop,FALSE);
7207 pic14_emitcode("mov","%s,%s",
7209 aopGet(AOP(result),0,FALSE,TRUE));
7210 rname = preg->name ;
7212 rname = aopGet(AOP(result),0,FALSE,FALSE);
7214 freeAsmop(result,NULL,ic,TRUE);
7215 aopOp (right,ic,FALSE);
7217 /* if bitfield then unpack the bits */
7218 if (IS_BITVAR(retype))
7219 genPackBits (retype,right,rname,PPOINTER);
7221 /* we have can just get the values */
7222 int size = AOP_SIZE(right);
7226 l = aopGet(AOP(right),offset,FALSE,TRUE);
7229 pic14_emitcode("movx","@%s,a",rname);
7232 pic14_emitcode("inc","%s",rname);
7238 /* now some housekeeping stuff */
7240 /* we had to allocate for this iCode */
7241 freeAsmop(NULL,aop,ic,TRUE);
7243 /* we did not allocate which means left
7244 already in a pointer register, then
7245 if size > 0 && this could be used again
7246 we have to point it back to where it
7248 if (AOP_SIZE(right) > 1 &&
7249 !OP_SYMBOL(result)->remat &&
7250 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7252 int size = AOP_SIZE(right) - 1;
7254 pic14_emitcode("dec","%s",rname);
7259 freeAsmop(right,NULL,ic,TRUE);
7264 /*-----------------------------------------------------------------*/
7265 /* genFarPointerSet - set value from far space */
7266 /*-----------------------------------------------------------------*/
7267 static void genFarPointerSet (operand *right,
7268 operand *result, iCode *ic)
7271 sym_link *retype = getSpec(operandType(right));
7273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7274 aopOp(result,ic,FALSE);
7276 /* if the operand is already in dptr
7277 then we do nothing else we move the value to dptr */
7278 if (AOP_TYPE(result) != AOP_STR) {
7279 /* if this is remateriazable */
7280 if (AOP_TYPE(result) == AOP_IMMD)
7281 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7282 else { /* we need to get it byte by byte */
7283 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7284 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7285 if (options.model == MODEL_FLAT24)
7287 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7291 /* so dptr know contains the address */
7292 freeAsmop(result,NULL,ic,TRUE);
7293 aopOp(right,ic,FALSE);
7295 /* if bit then unpack */
7296 if (IS_BITVAR(retype))
7297 genPackBits(retype,right,"dptr",FPOINTER);
7299 size = AOP_SIZE(right);
7303 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7305 pic14_emitcode("movx","@dptr,a");
7307 pic14_emitcode("inc","dptr");
7311 freeAsmop(right,NULL,ic,TRUE);
7314 /*-----------------------------------------------------------------*/
7315 /* genGenPointerSet - set value from generic pointer space */
7316 /*-----------------------------------------------------------------*/
7317 static void genGenPointerSet (operand *right,
7318 operand *result, iCode *ic)
7321 sym_link *retype = getSpec(operandType(right));
7323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7325 aopOp(result,ic,FALSE);
7327 /* if the operand is already in dptr
7328 then we do nothing else we move the value to dptr */
7329 if (AOP_TYPE(result) != AOP_STR) {
7330 /* if this is remateriazable */
7331 if (AOP_TYPE(result) == AOP_IMMD) {
7332 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7333 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7335 else { /* we need to get it byte by byte */
7336 char *l = aopGet(AOP(result),0,FALSE,FALSE);
7339 emitpcode(POC_MOVLW ,popGet(AOP(result),0,FALSE,FALSE));
7340 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7343 pic14_emitcode("movlw","%s",aopGet(AOP(result),0,FALSE,FALSE));
7345 pic14_emitcode("movwf","INDF");
7348 /* so dptr know contains the address */
7349 freeAsmop(result,NULL,ic,TRUE);
7350 aopOp(right,ic,FALSE);
7352 /* if bit then unpack */
7353 if (IS_BITVAR(retype))
7354 genPackBits(retype,right,"dptr",GPOINTER);
7356 size = AOP_SIZE(right);
7360 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7362 pic14_emitcode("incf","fsr,f");
7363 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
7364 pic14_emitcode("movwf","indf");
7366 //DEBUGpic14_emitcode(";lcall","__gptrput");
7368 // pic14_emitcode("inc","dptr");
7372 freeAsmop(right,NULL,ic,TRUE);
7375 /*-----------------------------------------------------------------*/
7376 /* genPointerSet - stores the value into a pointer location */
7377 /*-----------------------------------------------------------------*/
7378 static void genPointerSet (iCode *ic)
7380 operand *right, *result ;
7381 sym_link *type, *etype;
7384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7386 right = IC_RIGHT(ic);
7387 result = IC_RESULT(ic) ;
7389 /* depending on the type of pointer we need to
7390 move it to the correct pointer register */
7391 type = operandType(result);
7392 etype = getSpec(type);
7393 /* if left is of type of pointer then it is simple */
7394 if (IS_PTR(type) && !IS_FUNC(type->next)) {
7395 p_type = DCL_TYPE(type);
7398 /* we have to go by the storage class */
7399 p_type = PTR_TYPE(SPEC_OCLS(etype));
7401 /* if (SPEC_OCLS(etype)->codesp ) { */
7402 /* p_type = CPOINTER ; */
7405 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7406 /* p_type = FPOINTER ; */
7408 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7409 /* p_type = PPOINTER ; */
7411 /* if (SPEC_OCLS(etype) == idata ) */
7412 /* p_type = IPOINTER ; */
7414 /* p_type = POINTER ; */
7417 /* now that we have the pointer type we assign
7418 the pointer values */
7423 genNearPointerSet (right,result,ic);
7427 genPagedPointerSet (right,result,ic);
7431 genFarPointerSet (right,result,ic);
7435 genGenPointerSet (right,result,ic);
7441 /*-----------------------------------------------------------------*/
7442 /* genIfx - generate code for Ifx statement */
7443 /*-----------------------------------------------------------------*/
7444 static void genIfx (iCode *ic, iCode *popIc)
7446 operand *cond = IC_COND(ic);
7449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7450 aopOp(cond,ic,FALSE);
7452 /* get the value into acc */
7453 if (AOP_TYPE(cond) != AOP_CRY)
7454 pic14_toBoolean(cond);
7457 /* the result is now in the accumulator */
7458 freeAsmop(cond,NULL,ic,TRUE);
7460 /* if there was something to be popped then do it */
7464 /* if the condition is a bit variable */
7465 if (isbit && IS_ITEMP(cond) &&
7467 genIfxJump(ic,SPIL_LOC(cond)->rname);
7468 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
7472 if (isbit && !IS_ITEMP(cond))
7473 DEBUGpic14_emitcode ("; isbit OP_SYM","%s",OP_SYMBOL(cond)->rname);
7475 DEBUGpic14_emitcode ("; isbit","a");
7478 if (isbit && !IS_ITEMP(cond))
7479 genIfxJump(ic,OP_SYMBOL(cond)->rname);
7486 /*-----------------------------------------------------------------*/
7487 /* genAddrOf - generates code for address of */
7488 /*-----------------------------------------------------------------*/
7489 static void genAddrOf (iCode *ic)
7491 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
7494 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7496 aopOp(IC_RESULT(ic),ic,FALSE);
7498 /* if the operand is on the stack then we
7499 need to get the stack offset of this
7502 /* if it has an offset then we need to compute
7505 pic14_emitcode("mov","a,_bp");
7506 pic14_emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
7507 aopPut(AOP(IC_RESULT(ic)),"a",0);
7509 /* we can just move _bp */
7510 aopPut(AOP(IC_RESULT(ic)),"_bp",0);
7512 /* fill the result with zero */
7513 size = AOP_SIZE(IC_RESULT(ic)) - 1;
7516 if (options.stack10bit && size < (FPTRSIZE - 1))
7519 "*** warning: pointer to stack var truncated.\n");
7526 if (options.stack10bit && offset == 2)
7528 aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
7532 aopPut(AOP(IC_RESULT(ic)),zero,offset++);
7539 /* object not on stack then we need the name */
7540 size = AOP_SIZE(IC_RESULT(ic));
7544 char s[SDCC_NAME_MAX];
7546 sprintf(s,"#(%s >> %d)",
7550 sprintf(s,"#%s",sym->rname);
7551 aopPut(AOP(IC_RESULT(ic)),s,offset++);
7555 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
7560 /*-----------------------------------------------------------------*/
7561 /* genFarFarAssign - assignment when both are in far space */
7562 /*-----------------------------------------------------------------*/
7563 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
7565 int size = AOP_SIZE(right);
7568 /* first push the right side on to the stack */
7570 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7572 pic14_emitcode ("push","acc");
7575 freeAsmop(right,NULL,ic,FALSE);
7576 /* now assign DPTR to result */
7577 aopOp(result,ic,FALSE);
7578 size = AOP_SIZE(result);
7580 pic14_emitcode ("pop","acc");
7581 aopPut(AOP(result),"a",--offset);
7583 freeAsmop(result,NULL,ic,FALSE);
7588 /*-----------------------------------------------------------------*/
7589 /* genAssign - generate code for assignment */
7590 /*-----------------------------------------------------------------*/
7591 static void genAssign (iCode *ic)
7593 operand *result, *right;
7595 unsigned long lit = 0L;
7597 result = IC_RESULT(ic);
7598 right = IC_RIGHT(ic) ;
7600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7602 /* if they are the same */
7603 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
7606 aopOp(right,ic,FALSE);
7607 aopOp(result,ic,TRUE);
7609 /* if they are the same registers */
7610 if (pic14_sameRegs(AOP(right),AOP(result)))
7613 /* if the result is a bit */
7614 if (AOP_TYPE(result) == AOP_CRY) {
7616 /* if the right size is a literal then
7617 we know what the value is */
7618 if (AOP_TYPE(right) == AOP_LIT) {
7620 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7621 popGet(AOP(result),0,FALSE,FALSE));
7623 if (((int) operandLitValue(right)))
7624 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7625 AOP(result)->aopu.aop_dir,
7626 AOP(result)->aopu.aop_dir);
7628 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7629 AOP(result)->aopu.aop_dir,
7630 AOP(result)->aopu.aop_dir);
7634 /* the right is also a bit variable */
7635 if (AOP_TYPE(right) == AOP_CRY) {
7636 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7637 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7638 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7640 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
7641 AOP(result)->aopu.aop_dir,
7642 AOP(result)->aopu.aop_dir);
7643 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
7644 AOP(right)->aopu.aop_dir,
7645 AOP(right)->aopu.aop_dir);
7646 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
7647 AOP(result)->aopu.aop_dir,
7648 AOP(result)->aopu.aop_dir);
7653 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
7654 pic14_toBoolean(right);
7656 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
7657 //aopPut(AOP(result),"a",0);
7661 /* bit variables done */
7663 size = AOP_SIZE(result);
7665 if(AOP_TYPE(right) == AOP_LIT)
7666 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
7667 if((AOP_TYPE(result) != AOP_REG) &&
7668 (AOP_TYPE(right) == AOP_LIT) &&
7669 !IS_FLOAT(operandType(right)) &&
7673 if((unsigned int)((lit >> (size*8)) & 0x0FFL)== 0) {
7674 //pic14_emitcode("clrf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7675 emitpcode(POC_CLRF,popGet(AOP(result),size,FALSE,FALSE));
7677 emitpcode(POC_MOVLW,popGet(AOP(right),size,FALSE,FALSE));
7678 emitpcode(POC_MOVWF,popGet(AOP(result),size,FALSE,FALSE));
7679 //pic14_emitcode("movlw","%s", aopGet(AOP(right),size,FALSE,FALSE));
7680 //pic14_emitcode("movwf","%s", aopGet(AOP(result),size,FALSE,FALSE));
7685 if(AOP_TYPE(right) == AOP_LIT) {
7686 emitpcode(POC_MOVLW, popGet(AOP(right),offset,FALSE,FALSE));
7687 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7689 } else if (AOP_TYPE(right) == AOP_CRY) {
7690 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
7692 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
7693 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
7696 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7697 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
7700 //pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE));
7706 freeAsmop (right,NULL,ic,FALSE);
7707 freeAsmop (result,NULL,ic,TRUE);
7710 /*-----------------------------------------------------------------*/
7711 /* genJumpTab - genrates code for jump table */
7712 /*-----------------------------------------------------------------*/
7713 static void genJumpTab (iCode *ic)
7718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7720 aopOp(IC_JTCOND(ic),ic,FALSE);
7721 /* get the condition into accumulator */
7722 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
7724 /* multiply by three */
7725 pic14_emitcode("add","a,acc");
7726 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
7727 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
7729 jtab = newiTempLabel(NULL);
7730 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
7731 pic14_emitcode("jmp","@a+dptr");
7732 pic14_emitcode("","%05d_DS_:",jtab->key+100);
7733 /* now generate the jump labels */
7734 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
7735 jtab = setNextItem(IC_JTLABELS(ic)))
7736 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
7740 /*-----------------------------------------------------------------*/
7741 /* genMixedOperation - gen code for operators between mixed types */
7742 /*-----------------------------------------------------------------*/
7744 TSD - Written for the PIC port - but this unfortunately is buggy.
7745 This routine is good in that it is able to efficiently promote
7746 types to different (larger) sizes. Unfortunately, the temporary
7747 variables that are optimized out by this routine are sometimes
7748 used in other places. So until I know how to really parse the
7749 iCode tree, I'm going to not be using this routine :(.
7751 static int genMixedOperation (iCode *ic)
7754 operand *result = IC_RESULT(ic);
7755 sym_link *ctype = operandType(IC_LEFT(ic));
7756 operand *right = IC_RIGHT(ic);
7762 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
7764 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7770 nextright = IC_RIGHT(nextic);
7771 nextleft = IC_LEFT(nextic);
7772 nextresult = IC_RESULT(nextic);
7774 aopOp(right,ic,FALSE);
7775 aopOp(result,ic,FALSE);
7776 aopOp(nextright, nextic, FALSE);
7777 aopOp(nextleft, nextic, FALSE);
7778 aopOp(nextresult, nextic, FALSE);
7780 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
7786 pic14_emitcode(";remove right +","");
7788 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
7794 pic14_emitcode(";remove left +","");
7798 big = AOP_SIZE(nextleft);
7799 small = AOP_SIZE(nextright);
7801 switch(nextic->op) {
7804 pic14_emitcode(";optimize a +","");
7805 /* if unsigned or not an integral type */
7806 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
7807 pic14_emitcode(";add a bit to something","");
7810 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
7812 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
7813 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
7814 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
7816 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
7824 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7825 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7826 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7829 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7831 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7832 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
7833 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
7834 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7835 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
7838 pic14_emitcode("rlf","known_zero,w");
7845 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
7846 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
7847 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7849 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
7859 freeAsmop(right,NULL,ic,TRUE);
7860 freeAsmop(result,NULL,ic,TRUE);
7861 freeAsmop(nextright,NULL,ic,TRUE);
7862 freeAsmop(nextleft,NULL,ic,TRUE);
7864 nextic->generated = 1;
7871 /*-----------------------------------------------------------------*/
7872 /* genCast - gen code for casting */
7873 /*-----------------------------------------------------------------*/
7874 static void genCast (iCode *ic)
7876 operand *result = IC_RESULT(ic);
7877 sym_link *ctype = operandType(IC_LEFT(ic));
7878 operand *right = IC_RIGHT(ic);
7881 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
7882 /* if they are equivalent then do nothing */
7883 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
7886 aopOp(right,ic,FALSE) ;
7887 aopOp(result,ic,FALSE);
7889 /* if the result is a bit */
7890 if (AOP_TYPE(result) == AOP_CRY) {
7891 /* if the right size is a literal then
7892 we know what the value is */
7893 if (AOP_TYPE(right) == AOP_LIT) {
7895 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
7896 popGet(AOP(result),0,FALSE,FALSE));
7898 if (((int) operandLitValue(right)))
7899 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
7900 AOP(result)->aopu.aop_dir,
7901 AOP(result)->aopu.aop_dir);
7903 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
7904 AOP(result)->aopu.aop_dir,
7905 AOP(result)->aopu.aop_dir);
7910 /* the right is also a bit variable */
7911 if (AOP_TYPE(right) == AOP_CRY) {
7914 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
7916 pic14_emitcode("clrc","");
7917 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
7918 AOP(right)->aopu.aop_dir,
7919 AOP(right)->aopu.aop_dir);
7920 aopPut(AOP(result),"c",0);
7925 pic14_toBoolean(right);
7926 aopPut(AOP(result),"a",0);
7930 /* if they are the same size : or less */
7931 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
7933 /* if they are in the same place */
7934 if (pic14_sameRegs(AOP(right),AOP(result)))
7937 /* if they in different places then copy */
7938 size = AOP_SIZE(result);
7942 aopGet(AOP(right),offset,FALSE,FALSE),
7950 /* if the result is of type pointer */
7951 if (IS_PTR(ctype)) {
7954 sym_link *type = operandType(right);
7955 sym_link *etype = getSpec(type);
7957 /* pointer to generic pointer */
7958 if (IS_GENPTR(ctype)) {
7962 p_type = DCL_TYPE(type);
7964 /* we have to go by the storage class */
7965 p_type = PTR_TYPE(SPEC_OCLS(etype));
7967 /* if (SPEC_OCLS(etype)->codesp ) */
7968 /* p_type = CPOINTER ; */
7970 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7971 /* p_type = FPOINTER ; */
7973 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7974 /* p_type = PPOINTER; */
7976 /* if (SPEC_OCLS(etype) == idata ) */
7977 /* p_type = IPOINTER ; */
7979 /* p_type = POINTER ; */
7982 /* the first two bytes are known */
7983 size = GPTRSIZE - 1;
7987 aopGet(AOP(right),offset,FALSE,FALSE),
7991 /* the last byte depending on type */
8008 /* this should never happen */
8009 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8010 "got unknown pointer type");
8013 aopPut(AOP(result),l, GPTRSIZE - 1);
8017 /* just copy the pointers */
8018 size = AOP_SIZE(result);
8022 aopGet(AOP(right),offset,FALSE,FALSE),
8030 if (AOP_TYPE(right) == AOP_CRY) {
8032 size = AOP_SIZE(right);
8034 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8035 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8036 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8038 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8039 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8040 AOP(right)->aopu.aop_dir,
8041 AOP(right)->aopu.aop_dir);
8042 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8044 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8045 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8050 /* so we now know that the size of destination is greater
8051 than the size of the source.
8052 Now, if the next iCode is an operator then we might be
8053 able to optimize the operation without performing a cast.
8055 if(genMixedOperation(ic))
8059 /* we move to result for the size of source */
8060 size = AOP_SIZE(right);
8063 pic14_emitcode(";","%d",__LINE__);
8065 aopGet(AOP(right),offset,FALSE,FALSE),
8070 /* now depending on the sign of the destination */
8071 size = AOP_SIZE(result) - AOP_SIZE(right);
8072 /* if unsigned or not an integral type */
8073 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8075 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8076 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8080 /* we need to extend the sign :{ */
8081 //char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,FALSE,FALSE);
8084 emitpcode(POC_CLRW, NULL);
8085 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8086 emitpcode(POC_MOVLW, popGetLit(0xff));
8088 pic14_emitcode("clrw","");
8089 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8090 AOP(right)->aopu.aop_dir,
8091 AOP(right)->aopu.aop_dir);
8092 pic14_emitcode("movlw","0xff");
8094 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8095 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8097 // aopPut(AOP(result),"a",offset++);
8102 /* we are done hurray !!!! */
8105 freeAsmop(right,NULL,ic,TRUE);
8106 freeAsmop(result,NULL,ic,TRUE);
8110 /*-----------------------------------------------------------------*/
8111 /* genDjnz - generate decrement & jump if not zero instrucion */
8112 /*-----------------------------------------------------------------*/
8113 static int genDjnz (iCode *ic, iCode *ifx)
8116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8121 /* if the if condition has a false label
8122 then we cannot save */
8126 /* if the minus is not of the form
8128 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8129 !IS_OP_LITERAL(IC_RIGHT(ic)))
8132 if (operandLitValue(IC_RIGHT(ic)) != 1)
8135 /* if the size of this greater than one then no
8137 if (getSize(operandType(IC_RESULT(ic))) > 1)
8140 /* otherwise we can save BIG */
8141 lbl = newiTempLabel(NULL);
8142 lbl1= newiTempLabel(NULL);
8144 aopOp(IC_RESULT(ic),ic,FALSE);
8146 if (IS_AOP_PREG(IC_RESULT(ic))) {
8147 pic14_emitcode("dec","%s",
8148 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8149 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8150 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8154 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8155 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8157 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8158 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8161 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8162 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8163 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8164 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8167 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8172 /*-----------------------------------------------------------------*/
8173 /* genReceive - generate code for a receive iCode */
8174 /*-----------------------------------------------------------------*/
8175 static void genReceive (iCode *ic)
8177 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8179 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8180 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8181 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8183 int size = getSize(operandType(IC_RESULT(ic)));
8184 int offset = fReturnSizePic - size;
8186 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8187 fReturn[fReturnSizePic - offset - 1] : "acc"));
8190 aopOp(IC_RESULT(ic),ic,FALSE);
8191 size = AOP_SIZE(IC_RESULT(ic));
8194 pic14_emitcode ("pop","acc");
8195 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8200 aopOp(IC_RESULT(ic),ic,FALSE);
8202 assignResultValue(IC_RESULT(ic));
8205 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8208 /*-----------------------------------------------------------------*/
8209 /* genpic14Code - generate code for pic14 based controllers */
8210 /*-----------------------------------------------------------------*/
8212 * At this point, ralloc.c has gone through the iCode and attempted
8213 * to optimize in a way suitable for a PIC. Now we've got to generate
8214 * PIC instructions that correspond to the iCode.
8216 * Once the instructions are generated, we'll pass through both the
8217 * peep hole optimizer and the pCode optimizer.
8218 *-----------------------------------------------------------------*/
8220 void genpic14Code (iCode *lic)
8225 lineHead = lineCurr = NULL;
8227 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8230 /* if debug information required */
8231 /* if (options.debug && currFunc) { */
8233 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8235 if (IS_STATIC(currFunc->etype)) {
8236 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8237 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8239 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8240 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8246 for (ic = lic ; ic ; ic = ic->next ) {
8248 DEBUGpic14_emitcode(";ic","");
8249 if ( cln != ic->lineno ) {
8250 if ( options.debug ) {
8252 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8253 FileBaseName(ic->filename),ic->lineno,
8254 ic->level,ic->block);
8257 pic14_emitcode(";","%s %d",FileBaseName(ic->filename),ic->lineno);
8260 /* if the result is marked as
8261 spilt and rematerializable or code for
8262 this has already been generated then
8264 if (resultRemat(ic) || ic->generated )
8267 /* depending on the operation */
8286 /* IPOP happens only when trying to restore a
8287 spilt live range, if there is an ifx statement
8288 following this pop then the if statement might
8289 be using some of the registers being popped which
8290 would destory the contents of the register so
8291 we need to check for this condition and handle it */
8293 ic->next->op == IFX &&
8294 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8295 genIfx (ic->next,ic);
8313 genEndFunction (ic);
8333 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
8350 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
8354 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
8361 /* note these two are xlated by algebraic equivalence
8362 during parsing SDCC.y */
8363 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8364 "got '>=' or '<=' shouldn't have come here");
8368 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
8380 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
8384 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
8388 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
8415 case GET_VALUE_AT_ADDRESS:
8420 if (POINTER_SET(ic))
8447 addSet(&_G.sendSet,ic);
8456 /* now we are ready to call the
8457 peep hole optimizer */
8458 if (!options.nopeep) {
8459 printf("peep hole optimizing\n");
8460 peepHole (&lineHead);
8462 /* now do the actual printing */
8463 printLine (lineHead,codeOutFile);
8465 printf("printing pBlock\n\n");
8466 printpBlock(stdout,pb);