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"
63 if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
64 DEBUGpic14_emitcode ("; ","result %s",
65 AopType(AOP_TYPE(IC_RESULT(ic))));
67 if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
68 DEBUGpic14_emitcode ("; ","left %s",
69 AopType(AOP_TYPE(IC_LEFT(ic))));
71 if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
72 DEBUGpic14_emitcode ("; ","right %s",
73 AopType(AOP_TYPE(IC_RIGHT(ic))));
77 static int labelOffset=0;
78 static int debug_verbose=1;
79 static int optimized_for_speed = 0;
81 /* max_key keeps track of the largest label number used in
82 a function. This is then used to adjust the label offset
83 for the next function.
86 unsigned int pic14aopLiteral (value *val, int offset);
87 const char *AopType(short type);
89 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
91 /* this is the down and dirty file with all kinds of
92 kludgy & hacky stuff. This is what it is all about
93 CODE GENERATION for a specific MCU . some of the
94 routines may be reusable, will have to see */
96 static char *zero = "#0x00";
97 static char *one = "#0x01";
98 static char *spname = "sp";
100 char *fReturnpic14[] = {"FSR","dph","b","a" };
101 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
102 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
103 static char **fReturn = fReturnpic14;
105 static char *accUse[] = {"a","b"};
107 //static short rbank = -1;
119 /* Resolved ifx structure. This structure stores information
120 about an iCode ifx that makes it easier to generate code.
122 typedef struct resolvedIfx {
123 symbol *lbl; /* pointer to a label */
124 int condition; /* true or false ifx */
125 int generated; /* set true when the code associated with the ifx
129 extern int pic14_ptrRegReq ;
130 extern int pic14_nRegs;
131 extern FILE *codeOutFile;
132 static void saverbank (int, iCode *,bool);
134 static lineNode *lineHead = NULL;
135 static lineNode *lineCurr = NULL;
137 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
138 0xE0, 0xC0, 0x80, 0x00};
139 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
140 0x07, 0x03, 0x01, 0x00};
144 /*-----------------------------------------------------------------*/
145 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
146 /* exponent of 2 is returned, otherwise -1 is */
148 /* note that this is similar to the function `powof2' in SDCCsymt */
152 /*-----------------------------------------------------------------*/
153 static int my_powof2 (unsigned long num)
156 if( (num & (num-1)) == 0) {
169 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
172 char lb[INITIAL_INLINEASM];
182 sprintf(lb,"%s\t",inst);
184 sprintf(lb,"%s",inst);
185 vsprintf(lb+(strlen(lb)),fmt,ap);
189 while (isspace(*lbp)) lbp++;
192 lineCurr = (lineCurr ?
193 connectLine(lineCurr,newLineNode(lb)) :
194 (lineHead = newLineNode(lb)));
195 lineCurr->isInline = _G.inLine;
196 lineCurr->isDebug = _G.debugLine;
198 addpCode2pBlock(pb,newpCodeCharP(lb));
204 static void emitpLabel(int key)
206 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
209 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
213 addpCode2pBlock(pb,newpCode(poc,pcop));
215 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
218 void emitpcodeNULLop(PIC_OPCODE poc)
221 addpCode2pBlock(pb,newpCode(poc,NULL));
225 /*-----------------------------------------------------------------*/
226 /* pic14_emitcode - writes the code into a file : for now it is simple */
227 /*-----------------------------------------------------------------*/
228 void pic14_emitcode (char *inst,char *fmt, ...)
231 char lb[INITIAL_INLINEASM];
238 sprintf(lb,"%s\t",inst);
240 sprintf(lb,"%s",inst);
241 vsprintf(lb+(strlen(lb)),fmt,ap);
245 while (isspace(*lbp)) lbp++;
248 lineCurr = (lineCurr ?
249 connectLine(lineCurr,newLineNode(lb)) :
250 (lineHead = newLineNode(lb)));
251 lineCurr->isInline = _G.inLine;
252 lineCurr->isDebug = _G.debugLine;
255 addpCode2pBlock(pb,newpCodeCharP(lb));
261 /*-----------------------------------------------------------------*/
262 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
263 /*-----------------------------------------------------------------*/
264 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
266 bool r0iu = FALSE , r1iu = FALSE;
267 bool r0ou = FALSE , r1ou = FALSE;
269 /* the logic: if r0 & r1 used in the instruction
270 then we are in trouble otherwise */
272 /* first check if r0 & r1 are used by this
273 instruction, in which case we are in trouble */
274 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
275 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
280 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
281 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
283 /* if no usage of r0 then return it */
284 if (!r0iu && !r0ou) {
285 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
286 (*aopp)->type = AOP_R0;
288 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
291 /* if no usage of r1 then return it */
292 if (!r1iu && !r1ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
294 (*aopp)->type = AOP_R1;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
299 /* now we know they both have usage */
300 /* if r0 not used in this instruction */
302 /* push it if not already pushed */
304 pic14_emitcode ("push","%s",
305 pic14_regWithIdx(R0_IDX)->dname);
309 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
310 (*aopp)->type = AOP_R0;
312 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
315 /* if r1 not used then */
318 /* push it if not already pushed */
320 pic14_emitcode ("push","%s",
321 pic14_regWithIdx(R1_IDX)->dname);
325 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
326 (*aopp)->type = AOP_R1;
327 return pic14_regWithIdx(R1_IDX);
331 /* I said end of world but not quite end of world yet */
332 /* if this is a result then we can push it on the stack*/
334 (*aopp)->type = AOP_STK;
338 /* other wise this is true end of the world */
339 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
340 "getFreePtr should never reach here");
344 /*-----------------------------------------------------------------*/
345 /* newAsmop - creates a new asmOp */
346 /*-----------------------------------------------------------------*/
347 asmop *newAsmop (short type)
351 aop = Safe_calloc(1,sizeof(asmop));
356 static void genSetDPTR(int n)
360 pic14_emitcode(";", "Select standard DPTR");
361 pic14_emitcode("mov", "dps, #0x00");
365 pic14_emitcode(";", "Select alternate DPTR");
366 pic14_emitcode("mov", "dps, #0x01");
370 /*-----------------------------------------------------------------*/
371 /* resolveIfx - converts an iCode ifx into a form more useful for */
372 /* generating code */
373 /*-----------------------------------------------------------------*/
374 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
379 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
381 resIfx->condition = 1; /* assume that the ifx is true */
382 resIfx->generated = 0; /* indicate that the ifx has not been used */
385 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
386 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
387 __FUNCTION__,__LINE__,resIfx->lbl->key);
390 resIfx->lbl = IC_TRUE(ifx);
392 resIfx->lbl = IC_FALSE(ifx);
393 resIfx->condition = 0;
396 DEBUGpic14_emitcode("; ***","ifx true is non-null");
398 DEBUGpic14_emitcode("; ***","ifx false is non-null");
401 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
404 /*-----------------------------------------------------------------*/
405 /* pointerCode - returns the code for a pointer type */
406 /*-----------------------------------------------------------------*/
407 static int pointerCode (sym_link *etype)
410 return PTR_TYPE(SPEC_OCLS(etype));
414 /*-----------------------------------------------------------------*/
415 /* aopForSym - for a true symbol */
416 /*-----------------------------------------------------------------*/
417 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
420 memmap *space= SPEC_OCLS(sym->etype);
422 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
423 /* if already has one */
427 /* assign depending on the storage class */
428 /* if it is on the stack or indirectly addressable */
429 /* space we need to assign either r0 or r1 to it */
430 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
431 sym->aop = aop = newAsmop(0);
432 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
433 aop->size = getSize(sym->type);
435 /* now assign the address of the variable to
436 the pointer register */
437 if (aop->type != AOP_STK) {
441 pic14_emitcode("push","acc");
443 pic14_emitcode("mov","a,_bp");
444 pic14_emitcode("add","a,#0x%02x",
446 ((char)(sym->stack - _G.nRegsSaved )) :
447 ((char)sym->stack)) & 0xff);
448 pic14_emitcode("mov","%s,a",
449 aop->aopu.aop_ptr->name);
452 pic14_emitcode("pop","acc");
454 pic14_emitcode("mov","%s,#%s",
455 aop->aopu.aop_ptr->name,
457 aop->paged = space->paged;
459 aop->aopu.aop_stk = sym->stack;
463 if (sym->onStack && options.stack10bit)
465 /* It's on the 10 bit stack, which is located in
469 //DEBUGpic14_emitcode(";","%d",__LINE__);
472 pic14_emitcode("push","acc");
474 pic14_emitcode("mov","a,_bp");
475 pic14_emitcode("add","a,#0x%02x",
477 ((char)(sym->stack - _G.nRegsSaved )) :
478 ((char)sym->stack)) & 0xff);
481 pic14_emitcode ("mov","dpx1,#0x40");
482 pic14_emitcode ("mov","dph1,#0x00");
483 pic14_emitcode ("mov","dpl1, a");
487 pic14_emitcode("pop","acc");
489 sym->aop = aop = newAsmop(AOP_DPTR2);
490 aop->size = getSize(sym->type);
494 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 /* if in bit space */
496 if (IN_BITSPACE(space)) {
497 sym->aop = aop = newAsmop (AOP_CRY);
498 aop->aopu.aop_dir = sym->rname ;
499 aop->size = getSize(sym->type);
500 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
503 /* if it is in direct space */
504 if (IN_DIRSPACE(space)) {
505 sym->aop = aop = newAsmop (AOP_DIR);
506 aop->aopu.aop_dir = sym->rname ;
507 aop->size = getSize(sym->type);
508 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
512 /* special case for a function */
513 if (IS_FUNC(sym->type)) {
514 sym->aop = aop = newAsmop(AOP_IMMD);
515 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
516 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
517 strcpy(aop->aopu.aop_immd,sym->rname);
518 aop->size = FPTRSIZE;
523 /* only remaining is far space */
524 /* in which case DPTR gets the address */
525 sym->aop = aop = newAsmop(AOP_DPTR);
526 pic14_emitcode ("mov","dptr,#%s", sym->rname);
527 aop->size = getSize(sym->type);
529 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
530 /* if it is in code space */
531 if (IN_CODESPACE(space))
537 /*-----------------------------------------------------------------*/
538 /* aopForRemat - rematerialzes an object */
539 /*-----------------------------------------------------------------*/
540 static asmop *aopForRemat (symbol *sym)
542 iCode *ic = sym->rematiCode;
543 asmop *aop = newAsmop(AOP_IMMD);
545 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
548 val += (int) operandLitValue(IC_RIGHT(ic));
549 else if (ic->op == '-')
550 val -= (int) operandLitValue(IC_RIGHT(ic));
554 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
558 sprintf(buffer,"(%s %c 0x%04x)",
559 OP_SYMBOL(IC_LEFT(ic))->rname,
560 val >= 0 ? '+' : '-',
563 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
565 //DEBUGpic14_emitcode(";","%s",buffer);
566 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
567 strcpy(aop->aopu.aop_immd,buffer);
571 int aopIdx (asmop *aop, int offset)
576 if(aop->type != AOP_REG)
579 return aop->aopu.aop_reg[offset]->rIdx;
582 /*-----------------------------------------------------------------*/
583 /* regsInCommon - two operands have some registers in common */
584 /*-----------------------------------------------------------------*/
585 static bool regsInCommon (operand *op1, operand *op2)
590 /* if they have registers in common */
591 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
594 sym1 = OP_SYMBOL(op1);
595 sym2 = OP_SYMBOL(op2);
597 if (sym1->nRegs == 0 || sym2->nRegs == 0)
600 for (i = 0 ; i < sym1->nRegs ; i++) {
605 for (j = 0 ; j < sym2->nRegs ;j++ ) {
609 if (sym2->regs[j] == sym1->regs[i])
617 /*-----------------------------------------------------------------*/
618 /* operandsEqu - equivalent */
619 /*-----------------------------------------------------------------*/
620 static bool operandsEqu ( operand *op1, operand *op2)
624 /* if they not symbols */
625 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
628 sym1 = OP_SYMBOL(op1);
629 sym2 = OP_SYMBOL(op2);
631 /* if both are itemps & one is spilt
632 and the other is not then false */
633 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
634 sym1->isspilt != sym2->isspilt )
637 /* if they are the same */
641 if (strcmp(sym1->rname,sym2->rname) == 0)
645 /* if left is a tmp & right is not */
649 (sym1->usl.spillLoc == sym2))
656 (sym2->usl.spillLoc == sym1))
662 /*-----------------------------------------------------------------*/
663 /* pic14_sameRegs - two asmops have the same registers */
664 /*-----------------------------------------------------------------*/
665 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
672 if (aop1->type != AOP_REG ||
673 aop2->type != AOP_REG )
676 if (aop1->size != aop2->size )
679 for (i = 0 ; i < aop1->size ; i++ )
680 if (aop1->aopu.aop_reg[i] !=
681 aop2->aopu.aop_reg[i] )
687 /*-----------------------------------------------------------------*/
688 /* aopOp - allocates an asmop for an operand : */
689 /*-----------------------------------------------------------------*/
690 void aopOp (operand *op, iCode *ic, bool result)
699 DEBUGpic14_emitcode(";","%d",__LINE__);
700 /* if this a literal */
701 if (IS_OP_LITERAL(op)) {
702 op->aop = aop = newAsmop(AOP_LIT);
703 aop->aopu.aop_lit = op->operand.valOperand;
704 aop->size = getSize(operandType(op));
705 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
709 /* if already has a asmop then continue */
713 /* if the underlying symbol has a aop */
714 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
715 DEBUGpic14_emitcode(";","%d",__LINE__);
716 op->aop = OP_SYMBOL(op)->aop;
720 /* if this is a true symbol */
721 if (IS_TRUE_SYMOP(op)) {
722 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
723 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
727 /* this is a temporary : this has
733 e) can be a return use only */
738 /* if the type is a conditional */
739 if (sym->regType == REG_CND) {
740 DEBUGpic14_emitcode(";","%d",__LINE__);
741 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
746 /* if it is spilt then two situations
748 b) has a spill location */
749 if (sym->isspilt || sym->nRegs == 0) {
751 DEBUGpic14_emitcode(";","%d",__LINE__);
752 /* rematerialize it NOW */
754 sym->aop = op->aop = aop =
756 aop->size = getSize(sym->type);
757 DEBUGpic14_emitcode(";","%d",__LINE__);
763 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
764 aop->size = getSize(sym->type);
765 for ( i = 0 ; i < 2 ; i++ )
766 aop->aopu.aop_str[i] = accUse[i];
767 DEBUGpic14_emitcode(";","%d",__LINE__);
773 aop = op->aop = sym->aop = newAsmop(AOP_STR);
774 aop->size = getSize(sym->type);
775 for ( i = 0 ; i < fReturnSizePic ; i++ )
776 aop->aopu.aop_str[i] = fReturn[i];
777 DEBUGpic14_emitcode(";","%d",__LINE__);
781 /* else spill location */
782 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
783 sym->aop = op->aop = aop =
784 aopForSym(ic,sym->usl.spillLoc,result);
785 aop->size = getSize(sym->type);
789 /* must be in a register */
790 sym->aop = op->aop = aop = newAsmop(AOP_REG);
791 aop->size = sym->nRegs;
792 for ( i = 0 ; i < sym->nRegs ;i++)
793 aop->aopu.aop_reg[i] = sym->regs[i];
796 /*-----------------------------------------------------------------*/
797 /* freeAsmop - free up the asmop given to an operand */
798 /*----------------------------------------------------------------*/
799 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
816 /* depending on the asmop type only three cases need work AOP_RO
817 , AOP_R1 && AOP_STK */
822 pic14_emitcode ("pop","ar0");
826 bitVectUnSetBit(ic->rUsed,R0_IDX);
832 pic14_emitcode ("pop","ar1");
836 bitVectUnSetBit(ic->rUsed,R1_IDX);
842 int stk = aop->aopu.aop_stk + aop->size;
843 bitVectUnSetBit(ic->rUsed,R0_IDX);
844 bitVectUnSetBit(ic->rUsed,R1_IDX);
846 getFreePtr(ic,&aop,FALSE);
848 if (options.stack10bit)
850 /* I'm not sure what to do here yet... */
853 "*** Warning: probably generating bad code for "
854 "10 bit stack mode.\n");
858 pic14_emitcode ("mov","a,_bp");
859 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
860 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
862 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
866 pic14_emitcode("pop","acc");
867 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
869 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
872 freeAsmop(op,NULL,ic,TRUE);
874 pic14_emitcode("pop","ar0");
879 pic14_emitcode("pop","ar1");
886 /* all other cases just dealloc */
890 OP_SYMBOL(op)->aop = NULL;
891 /* if the symbol has a spill */
893 SPIL_LOC(op)->aop = NULL;
898 /*-----------------------------------------------------------------*/
899 /* aopGet - for fetching value of the aop */
900 /*-----------------------------------------------------------------*/
901 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
906 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
907 /* offset is greater than
909 if (offset > (aop->size - 1) &&
910 aop->type != AOP_LIT)
913 /* depending on type */
918 DEBUGpic14_emitcode(";","%d",__LINE__);
919 /* if we need to increment it */
920 while (offset > aop->coff) {
921 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
925 while (offset < aop->coff) {
926 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
932 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
933 return (dname ? "acc" : "a");
935 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
936 rs = Safe_calloc(1,strlen(s)+1);
942 DEBUGpic14_emitcode(";","%d",__LINE__);
943 if (aop->type == AOP_DPTR2)
948 while (offset > aop->coff) {
949 pic14_emitcode ("inc","dptr");
953 while (offset < aop->coff) {
954 pic14_emitcode("lcall","__decdptr");
960 pic14_emitcode("clr","a");
961 pic14_emitcode("movc","a,@a+dptr");
964 pic14_emitcode("movx","a,@dptr");
967 if (aop->type == AOP_DPTR2)
972 return (dname ? "acc" : "a");
976 DEBUGpic14_emitcode(";","%d",__LINE__);
978 sprintf (s,"%s",aop->aopu.aop_immd);
981 sprintf(s,"(%s >> %d)",
987 rs = Safe_calloc(1,strlen(s)+1);
993 sprintf(s,"(%s + %d)",
997 sprintf(s,"%s",aop->aopu.aop_dir);
998 rs = Safe_calloc(1,strlen(s)+1);
1003 DEBUGpic14_emitcode(";","%d",__LINE__);
1005 return aop->aopu.aop_reg[offset]->dname;
1007 return aop->aopu.aop_reg[offset]->name;
1010 pic14_emitcode(";","%d",__LINE__);
1011 //pic14_emitcode("clr","a");
1012 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1013 //pic14_emitcode("rlc","a") ;
1014 //return (dname ? "acc" : "a");
1015 return aop->aopu.aop_dir;
1018 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1019 //if (!offset && dname)
1021 //return aop->aopu.aop_str[offset];
1022 return "AOP_accumulator_bug";
1025 DEBUGpic14_emitcode(";","%d",__LINE__);
1026 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1027 rs = Safe_calloc(1,strlen(s)+1);
1032 DEBUGpic14_emitcode(";","%d",__LINE__);
1033 aop->coff = offset ;
1034 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1038 return aop->aopu.aop_str[offset];
1042 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1043 "aopget got unsupported aop->type");
1047 /*-----------------------------------------------------------------*/
1048 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1049 /*-----------------------------------------------------------------*/
1050 pCodeOp *popGetLabel(unsigned int key)
1053 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1058 return newpCodeOpLabel(key+100+labelOffset);
1061 /*-----------------------------------------------------------------*/
1062 /* popCopyReg - copy a pcode operator */
1063 /*-----------------------------------------------------------------*/
1064 pCodeOp *popCopyReg(pCodeOpReg *pc)
1068 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1069 pcor->pcop.type = pc->pcop.type;
1070 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1071 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1073 pcor->rIdx = pc->rIdx;
1079 /*-----------------------------------------------------------------*/
1080 /* popCopy - copy a pcode operator */
1081 /*-----------------------------------------------------------------*/
1082 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1086 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1087 pcop->type = PO_BIT;
1088 if(!(pcop->name = Safe_strdup(pc->name)))
1089 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1090 ((pCodeOpBit *)pcop)->bit = bitval;
1092 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1097 /*-----------------------------------------------------------------*/
1098 /* popGet - asm operator to pcode operator conversion */
1099 /*-----------------------------------------------------------------*/
1100 pCodeOp *popGetLit(unsigned int lit)
1103 return newpCodeOpLit(lit);
1107 /*-----------------------------------------------------------------*/
1108 /* popGet - asm operator to pcode operator conversion */
1109 /*-----------------------------------------------------------------*/
1110 pCodeOp *popGetWithString(char *str)
1116 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1120 pcop = newpCodeOp(str,PO_STR);
1125 pCodeOp *popRegFromString(char *str)
1128 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1129 pcop->type = PO_GPR_REGISTER;
1131 PCOR(pcop)->rIdx = -1;
1132 PCOR(pcop)->r = NULL;
1134 DEBUGpic14_emitcode(";","%d",__LINE__);
1135 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1140 /*-----------------------------------------------------------------*/
1141 /* popGet - asm operator to pcode operator conversion */
1142 /*-----------------------------------------------------------------*/
1143 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1150 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1151 /* offset is greater than
1154 if (offset > (aop->size - 1) &&
1155 aop->type != AOP_LIT)
1156 return NULL; //zero;
1158 /* depending on type */
1159 switch (aop->type) {
1166 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1167 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1168 //pcop->type = PO_SFR_REGISTER;
1170 //PCOR(pcop)->rIdx = -1;
1171 //PCOR(pcop)->r = NULL;
1172 // Really nasty hack to check for temporary registers
1174 //pcop->name = Safe_strdup("BAD_REGISTER");
1179 DEBUGpic14_emitcode(";","%d",__LINE__);
1180 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1181 pcop->type = PO_IMMEDIATE;
1183 sprintf (s,"%s",aop->aopu.aop_immd);
1186 sprintf(s,"(%s >> %d)",
1191 aop->aopu.aop_immd);
1192 pcop->name = Safe_calloc(1,strlen(s)+1);
1193 strcpy(pcop->name,s);
1197 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1198 pcop->type = PO_DIR;
1200 sprintf(s,"(%s + %d)",
1204 sprintf(s,"%s",aop->aopu.aop_dir);
1205 pcop->name = Safe_calloc(1,strlen(s)+1);
1206 strcpy(pcop->name,s);
1211 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1213 DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1215 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1217 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1218 //pcop->type = PO_GPR_REGISTER;
1219 PCOR(pcop)->rIdx = rIdx;
1220 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1221 pcop->type = PCOR(pcop)->r->pc_type;
1224 rs = aop->aopu.aop_reg[offset]->dname;
1226 rs = aop->aopu.aop_reg[offset]->name;
1228 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1234 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1238 DEBUGpic14_emitcode(";","%d",__LINE__);
1239 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1242 DEBUGpic14_emitcode(";","%d",__LINE__);
1244 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1245 pcop->type = PO_STR;
1247 //aop->coff = offset ;
1248 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1249 sprintf(s,"%s","acc");
1251 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1252 pcop->name = Safe_calloc(1,strlen(s)+1);
1253 strcpy(pcop->name,s);
1258 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1259 "popGet got unsupported aop->type");
1262 /*-----------------------------------------------------------------*/
1263 /* aopPut - puts a string for a aop */
1264 /*-----------------------------------------------------------------*/
1265 void aopPut (asmop *aop, char *s, int offset)
1270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1272 if (aop->size && offset > ( aop->size - 1)) {
1273 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1274 "aopPut got offset > aop->size");
1278 /* will assign value to value */
1279 /* depending on where it is ofcourse */
1280 switch (aop->type) {
1283 sprintf(d,"(%s + %d)",
1284 aop->aopu.aop_dir,offset);
1286 sprintf(d,"%s",aop->aopu.aop_dir);
1289 DEBUGpic14_emitcode(";","%d",__LINE__);
1291 pic14_emitcode("movf","%s,w",s);
1292 pic14_emitcode("movwf","%s",d);
1295 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1296 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1303 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1304 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1307 strcmp(s,"r0") == 0 ||
1308 strcmp(s,"r1") == 0 ||
1309 strcmp(s,"r2") == 0 ||
1310 strcmp(s,"r3") == 0 ||
1311 strcmp(s,"r4") == 0 ||
1312 strcmp(s,"r5") == 0 ||
1313 strcmp(s,"r6") == 0 ||
1314 strcmp(s,"r7") == 0 )
1315 pic14_emitcode("mov","%s,%s ; %d",
1316 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1321 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1323 pic14_emitcode("movwf","%s",
1324 aop->aopu.aop_reg[offset]->name);
1327 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1328 pcop->type = PO_GPR_REGISTER;
1330 PCOR(pcop)->rIdx = -1;
1331 PCOR(pcop)->r = NULL;
1333 DEBUGpic14_emitcode(";","%d",__LINE__);
1334 pcop->name = Safe_strdup(s);
1335 emitpcode(POC_MOVFW,pcop);
1337 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1345 if (aop->type == AOP_DPTR2)
1351 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1352 "aopPut writting to code space");
1356 while (offset > aop->coff) {
1358 pic14_emitcode ("inc","dptr");
1361 while (offset < aop->coff) {
1363 pic14_emitcode("lcall","__decdptr");
1368 /* if not in accumulater */
1371 pic14_emitcode ("movx","@dptr,a");
1373 if (aop->type == AOP_DPTR2)
1381 while (offset > aop->coff) {
1383 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1385 while (offset < aop->coff) {
1387 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1393 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1398 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1400 if (strcmp(s,"r0") == 0 ||
1401 strcmp(s,"r1") == 0 ||
1402 strcmp(s,"r2") == 0 ||
1403 strcmp(s,"r3") == 0 ||
1404 strcmp(s,"r4") == 0 ||
1405 strcmp(s,"r5") == 0 ||
1406 strcmp(s,"r6") == 0 ||
1407 strcmp(s,"r7") == 0 ) {
1409 sprintf(buffer,"a%s",s);
1410 pic14_emitcode("mov","@%s,%s",
1411 aop->aopu.aop_ptr->name,buffer);
1413 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1418 if (strcmp(s,"a") == 0)
1419 pic14_emitcode("push","acc");
1421 pic14_emitcode("push","%s",s);
1426 /* if bit variable */
1427 if (!aop->aopu.aop_dir) {
1428 pic14_emitcode("clr","a");
1429 pic14_emitcode("rlc","a");
1432 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1435 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1438 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1440 lbl = newiTempLabel(NULL);
1442 if (strcmp(s,"a")) {
1445 pic14_emitcode("clr","c");
1446 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1447 pic14_emitcode("cpl","c");
1448 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1449 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1456 if (strcmp(aop->aopu.aop_str[offset],s))
1457 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1462 if (!offset && (strcmp(s,"acc") == 0))
1465 if (strcmp(aop->aopu.aop_str[offset],s))
1466 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1470 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1471 "aopPut got unsupported aop->type");
1477 /*-----------------------------------------------------------------*/
1478 /* reAdjustPreg - points a register back to where it should */
1479 /*-----------------------------------------------------------------*/
1480 static void reAdjustPreg (asmop *aop)
1484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1486 if ((size = aop->size) <= 1)
1489 switch (aop->type) {
1493 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1497 if (aop->type == AOP_DPTR2)
1503 pic14_emitcode("lcall","__decdptr");
1506 if (aop->type == AOP_DPTR2)
1516 /*-----------------------------------------------------------------*/
1517 /* genNotFloat - generates not for float operations */
1518 /*-----------------------------------------------------------------*/
1519 static void genNotFloat (operand *op, operand *res)
1525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1526 /* we will put 127 in the first byte of
1528 aopPut(AOP(res),"#127",0);
1529 size = AOP_SIZE(op) - 1;
1532 l = aopGet(op->aop,offset++,FALSE,FALSE);
1536 pic14_emitcode("orl","a,%s",
1538 offset++,FALSE,FALSE));
1540 tlbl = newiTempLabel(NULL);
1542 tlbl = newiTempLabel(NULL);
1543 aopPut(res->aop,one,1);
1544 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1545 aopPut(res->aop,zero,1);
1546 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1548 size = res->aop->size - 2;
1550 /* put zeros in the rest */
1552 aopPut(res->aop,zero,offset++);
1556 /*-----------------------------------------------------------------*/
1557 /* opIsGptr: returns non-zero if the passed operand is */
1558 /* a generic pointer type. */
1559 /*-----------------------------------------------------------------*/
1560 static int opIsGptr(operand *op)
1562 sym_link *type = operandType(op);
1564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1565 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1573 /*-----------------------------------------------------------------*/
1574 /* pic14_getDataSize - get the operand data size */
1575 /*-----------------------------------------------------------------*/
1576 int pic14_getDataSize(operand *op)
1578 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1581 return AOP_SIZE(op);
1583 // tsd- in the pic port, the genptr size is 1, so this code here
1584 // fails. ( in the 8051 port, the size was 4).
1587 size = AOP_SIZE(op);
1588 if (size == GPTRSIZE)
1590 sym_link *type = operandType(op);
1591 if (IS_GENPTR(type))
1593 /* generic pointer; arithmetic operations
1594 * should ignore the high byte (pointer type).
1597 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1604 /*-----------------------------------------------------------------*/
1605 /* pic14_outAcc - output Acc */
1606 /*-----------------------------------------------------------------*/
1607 void pic14_outAcc(operand *result)
1610 DEBUGpic14_emitcode ("; ***","%s %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1613 size = pic14_getDataSize(result);
1615 aopPut(AOP(result),"a",0);
1618 /* unsigned or positive */
1620 aopPut(AOP(result),zero,offset++);
1626 /*-----------------------------------------------------------------*/
1627 /* pic14_outBitC - output a bit C */
1628 /*-----------------------------------------------------------------*/
1629 void pic14_outBitC(operand *result)
1632 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1633 /* if the result is bit */
1634 if (AOP_TYPE(result) == AOP_CRY)
1635 aopPut(AOP(result),"c",0);
1637 pic14_emitcode("clr","a ; %d", __LINE__);
1638 pic14_emitcode("rlc","a");
1639 pic14_outAcc(result);
1643 /*-----------------------------------------------------------------*/
1644 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1645 /*-----------------------------------------------------------------*/
1646 void pic14_toBoolean(operand *oper)
1648 int size = AOP_SIZE(oper) - 1;
1651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1653 if ( AOP_TYPE(oper) != AOP_ACC) {
1654 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1655 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1658 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1659 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1664 /*-----------------------------------------------------------------*/
1665 /* genNot - generate code for ! operation */
1666 /*-----------------------------------------------------------------*/
1667 static void genNot (iCode *ic)
1670 sym_link *optype = operandType(IC_LEFT(ic));
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 /* assign asmOps to operand & result */
1674 aopOp (IC_LEFT(ic),ic,FALSE);
1675 aopOp (IC_RESULT(ic),ic,TRUE);
1677 /* if in bit space then a special case */
1678 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1679 pic14_emitcode("movlw","1<<%s");
1680 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1681 //pic14_emitcode("cpl","c");
1682 //pic14_outBitC(IC_RESULT(ic));
1686 /* if type float then do float */
1687 if (IS_FLOAT(optype)) {
1688 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1692 pic14_toBoolean(IC_LEFT(ic));
1694 tlbl = newiTempLabel(NULL);
1695 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1696 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1697 pic14_outBitC(IC_RESULT(ic));
1700 /* release the aops */
1701 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1702 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1706 /*-----------------------------------------------------------------*/
1707 /* genCpl - generate code for complement */
1708 /*-----------------------------------------------------------------*/
1709 static void genCpl (iCode *ic)
1715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1716 /* assign asmOps to operand & result */
1717 aopOp (IC_LEFT(ic),ic,FALSE);
1718 aopOp (IC_RESULT(ic),ic,TRUE);
1720 /* if both are in bit space then
1722 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1723 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1725 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1726 pic14_emitcode("cpl","c");
1727 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1731 size = AOP_SIZE(IC_RESULT(ic));
1733 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1735 pic14_emitcode("cpl","a");
1736 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1741 /* release the aops */
1742 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1743 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1746 /*-----------------------------------------------------------------*/
1747 /* genUminusFloat - unary minus for floating points */
1748 /*-----------------------------------------------------------------*/
1749 static void genUminusFloat(operand *op,operand *result)
1751 int size ,offset =0 ;
1754 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1755 /* for this we just need to flip the
1756 first it then copy the rest in place */
1757 size = AOP_SIZE(op) - 1;
1758 l = aopGet(AOP(op),3,FALSE,FALSE);
1762 pic14_emitcode("cpl","acc.7");
1763 aopPut(AOP(result),"a",3);
1767 aopGet(AOP(op),offset,FALSE,FALSE),
1773 /*-----------------------------------------------------------------*/
1774 /* genUminus - unary minus code generation */
1775 /*-----------------------------------------------------------------*/
1776 static void genUminus (iCode *ic)
1779 sym_link *optype, *rtype;
1782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1784 aopOp(IC_LEFT(ic),ic,FALSE);
1785 aopOp(IC_RESULT(ic),ic,TRUE);
1787 /* if both in bit space then special
1789 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1790 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1792 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1793 pic14_emitcode("cpl","c");
1794 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1798 optype = operandType(IC_LEFT(ic));
1799 rtype = operandType(IC_RESULT(ic));
1801 /* if float then do float stuff */
1802 if (IS_FLOAT(optype)) {
1803 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1807 /* otherwise subtract from zero */
1808 size = AOP_SIZE(IC_LEFT(ic));
1812 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1813 if (!strcmp(l,"a")) {
1814 pic14_emitcode("cpl","a");
1815 pic14_emitcode("inc","a");
1817 pic14_emitcode("clr","a");
1818 pic14_emitcode("subb","a,%s",l);
1820 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1823 /* if any remaining bytes in the result */
1824 /* we just need to propagate the sign */
1825 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1826 pic14_emitcode("rlc","a");
1827 pic14_emitcode("subb","a,acc");
1829 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1833 /* release the aops */
1834 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1835 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1838 /*-----------------------------------------------------------------*/
1839 /* saveRegisters - will look for a call and save the registers */
1840 /*-----------------------------------------------------------------*/
1841 static void saveRegisters(iCode *lic)
1848 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1850 for (ic = lic ; ic ; ic = ic->next)
1851 if (ic->op == CALL || ic->op == PCALL)
1855 fprintf(stderr,"found parameter push with no function call\n");
1859 /* if the registers have been saved already then
1861 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1864 /* find the registers in use at this time
1865 and push them away to safety */
1866 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1870 if (options.useXstack) {
1871 if (bitVectBitValue(rsave,R0_IDX))
1872 pic14_emitcode("mov","b,r0");
1873 pic14_emitcode("mov","r0,%s",spname);
1874 for (i = 0 ; i < pic14_nRegs ; i++) {
1875 if (bitVectBitValue(rsave,i)) {
1877 pic14_emitcode("mov","a,b");
1879 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1880 pic14_emitcode("movx","@r0,a");
1881 pic14_emitcode("inc","r0");
1884 pic14_emitcode("mov","%s,r0",spname);
1885 if (bitVectBitValue(rsave,R0_IDX))
1886 pic14_emitcode("mov","r0,b");
1888 for (i = 0 ; i < pic14_nRegs ; i++) {
1889 if (bitVectBitValue(rsave,i))
1890 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1893 dtype = operandType(IC_LEFT(ic));
1895 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1896 IFFUNC_ISISR(currFunc->type) &&
1899 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1902 /*-----------------------------------------------------------------*/
1903 /* unsaveRegisters - pop the pushed registers */
1904 /*-----------------------------------------------------------------*/
1905 static void unsaveRegisters (iCode *ic)
1910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1911 /* find the registers in use at this time
1912 and push them away to safety */
1913 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1916 if (options.useXstack) {
1917 pic14_emitcode("mov","r0,%s",spname);
1918 for (i = pic14_nRegs ; i >= 0 ; i--) {
1919 if (bitVectBitValue(rsave,i)) {
1920 pic14_emitcode("dec","r0");
1921 pic14_emitcode("movx","a,@r0");
1923 pic14_emitcode("mov","b,a");
1925 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1929 pic14_emitcode("mov","%s,r0",spname);
1930 if (bitVectBitValue(rsave,R0_IDX))
1931 pic14_emitcode("mov","r0,b");
1933 for (i = pic14_nRegs ; i >= 0 ; i--) {
1934 if (bitVectBitValue(rsave,i))
1935 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1941 /*-----------------------------------------------------------------*/
1943 /*-----------------------------------------------------------------*/
1944 static void pushSide(operand * oper, int size)
1947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1949 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1950 if (AOP_TYPE(oper) != AOP_REG &&
1951 AOP_TYPE(oper) != AOP_DIR &&
1953 pic14_emitcode("mov","a,%s",l);
1954 pic14_emitcode("push","acc");
1956 pic14_emitcode("push","%s",l);
1960 /*-----------------------------------------------------------------*/
1961 /* assignResultValue - */
1962 /*-----------------------------------------------------------------*/
1963 static void assignResultValue(operand * oper)
1966 int size = AOP_SIZE(oper);
1968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1970 // The last byte in the assignment is in W
1971 aopPut(AOP(oper),"W",size-1);
1975 aopPut(AOP(oper),fReturn[offset],offset);
1983 /*-----------------------------------------------------------------*/
1984 /* genXpush - pushes onto the external stack */
1985 /*-----------------------------------------------------------------*/
1986 static void genXpush (iCode *ic)
1988 asmop *aop = newAsmop(0);
1990 int size,offset = 0;
1992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1993 aopOp(IC_LEFT(ic),ic,FALSE);
1994 r = getFreePtr(ic,&aop,FALSE);
1997 pic14_emitcode("mov","%s,_spx",r->name);
1999 size = AOP_SIZE(IC_LEFT(ic));
2002 char *l = aopGet(AOP(IC_LEFT(ic)),
2003 offset++,FALSE,FALSE);
2005 pic14_emitcode("movx","@%s,a",r->name);
2006 pic14_emitcode("inc","%s",r->name);
2011 pic14_emitcode("mov","_spx,%s",r->name);
2013 freeAsmop(NULL,aop,ic,TRUE);
2014 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2017 /*-----------------------------------------------------------------*/
2018 /* genIpush - genrate code for pushing this gets a little complex */
2019 /*-----------------------------------------------------------------*/
2020 static void genIpush (iCode *ic)
2022 int size, offset = 0 ;
2026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2027 /* if this is not a parm push : ie. it is spill push
2028 and spill push is always done on the local stack */
2029 if (!ic->parmPush) {
2031 /* and the item is spilt then do nothing */
2032 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2035 aopOp(IC_LEFT(ic),ic,FALSE);
2036 size = AOP_SIZE(IC_LEFT(ic));
2037 /* push it on the stack */
2039 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2044 pic14_emitcode("push","%s",l);
2049 /* this is a paramter push: in this case we call
2050 the routine to find the call and save those
2051 registers that need to be saved */
2054 /* if use external stack then call the external
2055 stack pushing routine */
2056 if (options.useXstack) {
2061 /* then do the push */
2062 aopOp(IC_LEFT(ic),ic,FALSE);
2065 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2066 size = AOP_SIZE(IC_LEFT(ic));
2069 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2070 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2071 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2073 pic14_emitcode("mov","a,%s",l);
2074 pic14_emitcode("push","acc");
2076 pic14_emitcode("push","%s",l);
2079 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2082 /*-----------------------------------------------------------------*/
2083 /* genIpop - recover the registers: can happen only for spilling */
2084 /*-----------------------------------------------------------------*/
2085 static void genIpop (iCode *ic)
2090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2091 /* if the temp was not pushed then */
2092 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2095 aopOp(IC_LEFT(ic),ic,FALSE);
2096 size = AOP_SIZE(IC_LEFT(ic));
2099 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2102 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2105 /*-----------------------------------------------------------------*/
2106 /* unsaverbank - restores the resgister bank from stack */
2107 /*-----------------------------------------------------------------*/
2108 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2116 if (options.useXstack) {
2118 r = getFreePtr(ic,&aop,FALSE);
2121 pic14_emitcode("mov","%s,_spx",r->name);
2122 pic14_emitcode("movx","a,@%s",r->name);
2123 pic14_emitcode("mov","psw,a");
2124 pic14_emitcode("dec","%s",r->name);
2127 pic14_emitcode ("pop","psw");
2130 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2131 if (options.useXstack) {
2132 pic14_emitcode("movx","a,@%s",r->name);
2133 //pic14_emitcode("mov","(%s+%d),a",
2134 // regspic14[i].base,8*bank+regspic14[i].offset);
2135 pic14_emitcode("dec","%s",r->name);
2138 pic14_emitcode("pop",""); //"(%s+%d)",
2139 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2142 if (options.useXstack) {
2144 pic14_emitcode("mov","_spx,%s",r->name);
2145 freeAsmop(NULL,aop,ic,TRUE);
2150 /*-----------------------------------------------------------------*/
2151 /* saverbank - saves an entire register bank on the stack */
2152 /*-----------------------------------------------------------------*/
2153 static void saverbank (int bank, iCode *ic, bool pushPsw)
2159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2160 if (options.useXstack) {
2163 r = getFreePtr(ic,&aop,FALSE);
2164 pic14_emitcode("mov","%s,_spx",r->name);
2168 for (i = 0 ; i < pic14_nRegs ;i++) {
2169 if (options.useXstack) {
2170 pic14_emitcode("inc","%s",r->name);
2171 //pic14_emitcode("mov","a,(%s+%d)",
2172 // regspic14[i].base,8*bank+regspic14[i].offset);
2173 pic14_emitcode("movx","@%s,a",r->name);
2175 pic14_emitcode("push","");// "(%s+%d)",
2176 //regspic14[i].base,8*bank+regspic14[i].offset);
2180 if (options.useXstack) {
2181 pic14_emitcode("mov","a,psw");
2182 pic14_emitcode("movx","@%s,a",r->name);
2183 pic14_emitcode("inc","%s",r->name);
2184 pic14_emitcode("mov","_spx,%s",r->name);
2185 freeAsmop (NULL,aop,ic,TRUE);
2188 pic14_emitcode("push","psw");
2190 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2196 /*-----------------------------------------------------------------*/
2197 /* genCall - generates a call statement */
2198 /*-----------------------------------------------------------------*/
2199 static void genCall (iCode *ic)
2203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2205 /* if caller saves & we have not saved then */
2209 /* if we are calling a function that is not using
2210 the same register bank then we need to save the
2211 destination registers on the stack */
2212 dtype = operandType(IC_LEFT(ic));
2214 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2215 IFFUNC_ISISR(currFunc->type) &&
2218 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2220 /* if send set is not empty the assign */
2224 for (sic = setFirstItem(_G.sendSet) ; sic ;
2225 sic = setNextItem(_G.sendSet)) {
2226 int size, offset = 0;
2228 aopOp(IC_LEFT(sic),sic,FALSE);
2229 size = AOP_SIZE(IC_LEFT(sic));
2231 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2233 DEBUGpic14_emitcode(";","%d - left type %d",__LINE__,AOP(IC_LEFT(sic))->type);
2235 if (strcmp(l,fReturn[offset])) {
2237 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2238 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2239 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2240 //pic14_emitcode("movlw","%s",l);
2242 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2243 //pic14_emitcode("movf","%s,w",l);
2245 // The last one is passed in W
2247 pic14_emitcode("movwf","%s",fReturn[offset]);
2251 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2256 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2257 OP_SYMBOL(IC_LEFT(ic))->rname :
2258 OP_SYMBOL(IC_LEFT(ic))->name));
2260 pic14_emitcode("call","%s",(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2261 OP_SYMBOL(IC_LEFT(ic))->rname :
2262 OP_SYMBOL(IC_LEFT(ic))->name));
2264 /* if we need assign a result value */
2265 if ((IS_ITEMP(IC_RESULT(ic)) &&
2266 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2267 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2268 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2271 aopOp(IC_RESULT(ic),ic,FALSE);
2274 assignResultValue(IC_RESULT(ic));
2276 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2279 /* adjust the stack for parameters if
2281 if (ic->parmBytes) {
2283 if (ic->parmBytes > 3) {
2284 pic14_emitcode("mov","a,%s",spname);
2285 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2286 pic14_emitcode("mov","%s,a",spname);
2288 for ( i = 0 ; i < ic->parmBytes ;i++)
2289 pic14_emitcode("dec","%s",spname);
2293 /* if register bank was saved then pop them */
2295 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2297 /* if we hade saved some registers then unsave them */
2298 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2299 unsaveRegisters (ic);
2304 /*-----------------------------------------------------------------*/
2305 /* genPcall - generates a call by pointer statement */
2306 /*-----------------------------------------------------------------*/
2307 static void genPcall (iCode *ic)
2310 symbol *rlbl = newiTempLabel(NULL);
2313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2314 /* if caller saves & we have not saved then */
2318 /* if we are calling a function that is not using
2319 the same register bank then we need to save the
2320 destination registers on the stack */
2321 dtype = operandType(IC_LEFT(ic));
2323 IFFUNC_ISISR(currFunc->type) &&
2324 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2325 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2328 /* push the return address on to the stack */
2329 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2330 pic14_emitcode("push","acc");
2331 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2332 pic14_emitcode("push","acc");
2334 if (options.model == MODEL_FLAT24)
2336 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2337 pic14_emitcode("push","acc");
2340 /* now push the calling address */
2341 aopOp(IC_LEFT(ic),ic,FALSE);
2343 pushSide(IC_LEFT(ic), FPTRSIZE);
2345 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2347 /* if send set is not empty the assign */
2351 for (sic = setFirstItem(_G.sendSet) ; sic ;
2352 sic = setNextItem(_G.sendSet)) {
2353 int size, offset = 0;
2354 aopOp(IC_LEFT(sic),sic,FALSE);
2355 size = AOP_SIZE(IC_LEFT(sic));
2357 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2359 if (strcmp(l,fReturn[offset]))
2360 pic14_emitcode("mov","%s,%s",
2365 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2370 pic14_emitcode("ret","");
2371 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2374 /* if we need assign a result value */
2375 if ((IS_ITEMP(IC_RESULT(ic)) &&
2376 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2377 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2378 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2381 aopOp(IC_RESULT(ic),ic,FALSE);
2384 assignResultValue(IC_RESULT(ic));
2386 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2389 /* adjust the stack for parameters if
2391 if (ic->parmBytes) {
2393 if (ic->parmBytes > 3) {
2394 pic14_emitcode("mov","a,%s",spname);
2395 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2396 pic14_emitcode("mov","%s,a",spname);
2398 for ( i = 0 ; i < ic->parmBytes ;i++)
2399 pic14_emitcode("dec","%s",spname);
2403 /* if register bank was saved then unsave them */
2405 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2406 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2408 /* if we hade saved some registers then
2411 unsaveRegisters (ic);
2415 /*-----------------------------------------------------------------*/
2416 /* resultRemat - result is rematerializable */
2417 /*-----------------------------------------------------------------*/
2418 static int resultRemat (iCode *ic)
2420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2421 if (SKIP_IC(ic) || ic->op == IFX)
2424 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2425 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2426 if (sym->remat && !POINTER_SET(ic))
2433 #if defined(__BORLANDC__) || defined(_MSC_VER)
2434 #define STRCASECMP stricmp
2436 #define STRCASECMP strcasecmp
2439 /*-----------------------------------------------------------------*/
2440 /* inExcludeList - return 1 if the string is in exclude Reg list */
2441 /*-----------------------------------------------------------------*/
2442 static bool inExcludeList(char *s)
2446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2447 if (options.excludeRegs[i] &&
2448 STRCASECMP(options.excludeRegs[i],"none") == 0)
2451 for ( i = 0 ; options.excludeRegs[i]; i++) {
2452 if (options.excludeRegs[i] &&
2453 STRCASECMP(s,options.excludeRegs[i]) == 0)
2459 /*-----------------------------------------------------------------*/
2460 /* genFunction - generated code for function entry */
2461 /*-----------------------------------------------------------------*/
2462 static void genFunction (iCode *ic)
2467 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2469 labelOffset += (max_key+4);
2473 /* create the function header */
2474 pic14_emitcode(";","-----------------------------------------");
2475 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2476 pic14_emitcode(";","-----------------------------------------");
2478 pic14_emitcode("","%s:",sym->rname);
2479 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2481 ftype = operandType(IC_LEFT(ic));
2483 /* if critical function then turn interrupts off */
2484 if (IFFUNC_ISCRITICAL(ftype))
2485 pic14_emitcode("clr","ea");
2487 /* here we need to generate the equates for the
2488 register bank if required */
2490 if (FUNC_REGBANK(ftype) != rbank) {
2493 rbank = FUNC_REGBANK(ftype);
2494 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2495 if (strcmp(regspic14[i].base,"0") == 0)
2496 pic14_emitcode("","%s = 0x%02x",
2498 8*rbank+regspic14[i].offset);
2500 pic14_emitcode ("","%s = %s + 0x%02x",
2503 8*rbank+regspic14[i].offset);
2508 /* if this is an interrupt service routine then
2509 save acc, b, dpl, dph */
2510 if (IFFUNC_ISISR(sym->type)) {
2512 if (!inExcludeList("acc"))
2513 pic14_emitcode ("push","acc");
2514 if (!inExcludeList("b"))
2515 pic14_emitcode ("push","b");
2516 if (!inExcludeList("dpl"))
2517 pic14_emitcode ("push","dpl");
2518 if (!inExcludeList("dph"))
2519 pic14_emitcode ("push","dph");
2520 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2522 pic14_emitcode ("push", "dpx");
2523 /* Make sure we're using standard DPTR */
2524 pic14_emitcode ("push", "dps");
2525 pic14_emitcode ("mov", "dps, #0x00");
2526 if (options.stack10bit)
2528 /* This ISR could conceivably use DPTR2. Better save it. */
2529 pic14_emitcode ("push", "dpl1");
2530 pic14_emitcode ("push", "dph1");
2531 pic14_emitcode ("push", "dpx1");
2534 /* if this isr has no bank i.e. is going to
2535 run with bank 0 , then we need to save more
2537 if (!FUNC_REGBANK(sym->type)) {
2539 /* if this function does not call any other
2540 function then we can be economical and
2541 save only those registers that are used */
2542 if (! IFFUNC_HASFCALL(sym->type)) {
2545 /* if any registers used */
2546 if (sym->regsUsed) {
2547 /* save the registers used */
2548 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2549 if (bitVectBitValue(sym->regsUsed,i) ||
2550 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2551 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2556 /* this function has a function call cannot
2557 determines register usage so we will have the
2559 saverbank(0,ic,FALSE);
2563 /* if callee-save to be used for this function
2564 then save the registers being used in this function */
2565 if (IFFUNC_CALLEESAVES(sym->type)) {
2568 /* if any registers used */
2569 if (sym->regsUsed) {
2570 /* save the registers used */
2571 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2572 if (bitVectBitValue(sym->regsUsed,i) ||
2573 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2574 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2582 /* set the register bank to the desired value */
2583 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2584 pic14_emitcode("push","psw");
2585 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2588 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2590 if (options.useXstack) {
2591 pic14_emitcode("mov","r0,%s",spname);
2592 pic14_emitcode("mov","a,_bp");
2593 pic14_emitcode("movx","@r0,a");
2594 pic14_emitcode("inc","%s",spname);
2598 /* set up the stack */
2599 pic14_emitcode ("push","_bp"); /* save the callers stack */
2601 pic14_emitcode ("mov","_bp,%s",spname);
2604 /* adjust the stack for the function */
2609 werror(W_STACK_OVERFLOW,sym->name);
2611 if (i > 3 && sym->recvSize < 4) {
2613 pic14_emitcode ("mov","a,sp");
2614 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2615 pic14_emitcode ("mov","sp,a");
2620 pic14_emitcode("inc","sp");
2625 pic14_emitcode ("mov","a,_spx");
2626 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2627 pic14_emitcode ("mov","_spx,a");
2632 /*-----------------------------------------------------------------*/
2633 /* genEndFunction - generates epilogue for functions */
2634 /*-----------------------------------------------------------------*/
2635 static void genEndFunction (iCode *ic)
2637 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2641 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2643 pic14_emitcode ("mov","%s,_bp",spname);
2646 /* if use external stack but some variables were
2647 added to the local stack then decrement the
2649 if (options.useXstack && sym->stack) {
2650 pic14_emitcode("mov","a,sp");
2651 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2652 pic14_emitcode("mov","sp,a");
2656 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2657 if (options.useXstack) {
2658 pic14_emitcode("mov","r0,%s",spname);
2659 pic14_emitcode("movx","a,@r0");
2660 pic14_emitcode("mov","_bp,a");
2661 pic14_emitcode("dec","%s",spname);
2665 pic14_emitcode ("pop","_bp");
2669 /* restore the register bank */
2670 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2671 pic14_emitcode ("pop","psw");
2673 if (IFFUNC_ISISR(sym->type)) {
2675 /* now we need to restore the registers */
2676 /* if this isr has no bank i.e. is going to
2677 run with bank 0 , then we need to save more
2679 if (!FUNC_REGBANK(sym->type)) {
2681 /* if this function does not call any other
2682 function then we can be economical and
2683 save only those registers that are used */
2684 if (! IFFUNC_HASFCALL(sym->type)) {
2687 /* if any registers used */
2688 if (sym->regsUsed) {
2689 /* save the registers used */
2690 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2691 if (bitVectBitValue(sym->regsUsed,i) ||
2692 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2693 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2698 /* this function has a function call cannot
2699 determines register usage so we will have the
2701 unsaverbank(0,ic,FALSE);
2705 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2707 if (options.stack10bit)
2709 pic14_emitcode ("pop", "dpx1");
2710 pic14_emitcode ("pop", "dph1");
2711 pic14_emitcode ("pop", "dpl1");
2713 pic14_emitcode ("pop", "dps");
2714 pic14_emitcode ("pop", "dpx");
2716 if (!inExcludeList("dph"))
2717 pic14_emitcode ("pop","dph");
2718 if (!inExcludeList("dpl"))
2719 pic14_emitcode ("pop","dpl");
2720 if (!inExcludeList("b"))
2721 pic14_emitcode ("pop","b");
2722 if (!inExcludeList("acc"))
2723 pic14_emitcode ("pop","acc");
2725 if (IFFUNC_ISCRITICAL(sym->type))
2726 pic14_emitcode("setb","ea");
2728 /* if debug then send end of function */
2729 /* if (options.debug && currFunc) { */
2732 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2733 FileBaseName(ic->filename),currFunc->lastLine,
2734 ic->level,ic->block);
2735 if (IS_STATIC(currFunc->etype))
2736 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2738 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2742 pic14_emitcode ("reti","");
2745 if (IFFUNC_ISCRITICAL(sym->type))
2746 pic14_emitcode("setb","ea");
2748 if (IFFUNC_CALLEESAVES(sym->type)) {
2751 /* if any registers used */
2752 if (sym->regsUsed) {
2753 /* save the registers used */
2754 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2755 if (bitVectBitValue(sym->regsUsed,i) ||
2756 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2757 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2763 /* if debug then send end of function */
2766 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2767 FileBaseName(ic->filename),currFunc->lastLine,
2768 ic->level,ic->block);
2769 if (IS_STATIC(currFunc->etype))
2770 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2772 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2776 pic14_emitcode ("return","");
2777 emitpcodeNULLop(POC_RETURN);
2779 /* Mark the end of a function */
2780 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2785 /*-----------------------------------------------------------------*/
2786 /* genRet - generate code for return statement */
2787 /*-----------------------------------------------------------------*/
2788 static void genRet (iCode *ic)
2790 int size,offset = 0 , pushed = 0;
2792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2793 /* if we have no return value then
2794 just generate the "ret" */
2798 /* we have something to return then
2799 move the return value into place */
2800 aopOp(IC_LEFT(ic),ic,FALSE);
2801 size = AOP_SIZE(IC_LEFT(ic));
2805 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2807 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2809 pic14_emitcode("push","%s",l);
2812 l = aopGet(AOP(IC_LEFT(ic)),offset,
2814 if (strcmp(fReturn[offset],l)) {
2815 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2816 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) )
2817 pic14_emitcode("movlw","%s",l);
2819 pic14_emitcode("movf","%s,w",l);
2821 pic14_emitcode("movwf","%s",fReturn[offset]);
2830 if (strcmp(fReturn[pushed],"a"))
2831 pic14_emitcode("pop",fReturn[pushed]);
2833 pic14_emitcode("pop","acc");
2836 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2839 /* generate a jump to the return label
2840 if the next is not the return statement */
2841 if (!(ic->next && ic->next->op == LABEL &&
2842 IC_LABEL(ic->next) == returnLabel)) {
2844 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2845 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2850 /*-----------------------------------------------------------------*/
2851 /* genLabel - generates a label */
2852 /*-----------------------------------------------------------------*/
2853 static void genLabel (iCode *ic)
2855 /* special case never generate */
2856 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2857 if (IC_LABEL(ic) == entryLabel)
2860 emitpLabel(IC_LABEL(ic)->key);
2861 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2864 /*-----------------------------------------------------------------*/
2865 /* genGoto - generates a goto */
2866 /*-----------------------------------------------------------------*/
2868 static void genGoto (iCode *ic)
2870 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2871 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2874 /*-----------------------------------------------------------------*/
2875 /* findLabelBackwards: walks back through the iCode chain looking */
2876 /* for the given label. Returns number of iCode instructions */
2877 /* between that label and given ic. */
2878 /* Returns zero if label not found. */
2879 /*-----------------------------------------------------------------*/
2881 static int findLabelBackwards(iCode *ic, int key)
2885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2891 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2893 /* printf("findLabelBackwards = %d\n", count); */
2902 /*-----------------------------------------------------------------*/
2903 /* genMultbits :- multiplication of bits */
2904 /*-----------------------------------------------------------------*/
2905 static void genMultbits (operand *left,
2909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2911 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2912 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2913 pic14_outBitC(result);
2917 /*-----------------------------------------------------------------*/
2918 /* genMultOneByte : 8 bit multiplication & division */
2919 /*-----------------------------------------------------------------*/
2920 static void genMultOneByte (operand *left,
2924 sym_link *opetype = operandType(result);
2929 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2930 /* (if two literals, the value is computed before) */
2931 /* if one literal, literal on the right */
2932 if (AOP_TYPE(left) == AOP_LIT){
2938 size = AOP_SIZE(result);
2939 /* signed or unsigned */
2940 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2941 l = aopGet(AOP(left),0,FALSE,FALSE);
2943 pic14_emitcode("mul","ab");
2944 /* if result size = 1, mul signed = mul unsigned */
2945 aopPut(AOP(result),"a",0);
2947 if (SPEC_USIGN(opetype)){
2948 aopPut(AOP(result),"b",1);
2950 /* for filling the MSBs */
2951 pic14_emitcode("clr","a");
2954 pic14_emitcode("mov","a,b");
2956 /* adjust the MSB if left or right neg */
2958 /* if one literal */
2959 if (AOP_TYPE(right) == AOP_LIT){
2960 /* AND literal negative */
2961 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2962 /* adjust MSB (c==0 after mul) */
2963 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2967 lbl = newiTempLabel(NULL);
2968 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2969 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2970 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2971 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2972 lbl = newiTempLabel(NULL);
2973 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2974 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2975 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2978 lbl = newiTempLabel(NULL);
2979 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2980 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2981 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2982 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2983 lbl = newiTempLabel(NULL);
2984 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2985 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2986 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2988 aopPut(AOP(result),"a",1);
2991 pic14_emitcode("rlc","a");
2992 pic14_emitcode("subb","a,acc");
2999 aopPut(AOP(result),"a",offset++);
3003 /*-----------------------------------------------------------------*/
3004 /* genMult - generates code for multiplication */
3005 /*-----------------------------------------------------------------*/
3006 static void genMult (iCode *ic)
3008 operand *left = IC_LEFT(ic);
3009 operand *right = IC_RIGHT(ic);
3010 operand *result= IC_RESULT(ic);
3012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3013 /* assign the amsops */
3014 aopOp (left,ic,FALSE);
3015 aopOp (right,ic,FALSE);
3016 aopOp (result,ic,TRUE);
3018 /* special cases first */
3020 if (AOP_TYPE(left) == AOP_CRY &&
3021 AOP_TYPE(right)== AOP_CRY) {
3022 genMultbits(left,right,result);
3026 /* if both are of size == 1 */
3027 if (AOP_SIZE(left) == 1 &&
3028 AOP_SIZE(right) == 1 ) {
3029 genMultOneByte(left,right,result);
3033 /* should have been converted to function call */
3037 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3038 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3039 freeAsmop(result,NULL,ic,TRUE);
3042 /*-----------------------------------------------------------------*/
3043 /* genDivbits :- division of bits */
3044 /*-----------------------------------------------------------------*/
3045 static void genDivbits (operand *left,
3052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3053 /* the result must be bit */
3054 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3055 l = aopGet(AOP(left),0,FALSE,FALSE);
3059 pic14_emitcode("div","ab");
3060 pic14_emitcode("rrc","a");
3061 aopPut(AOP(result),"c",0);
3064 /*-----------------------------------------------------------------*/
3065 /* genDivOneByte : 8 bit division */
3066 /*-----------------------------------------------------------------*/
3067 static void genDivOneByte (operand *left,
3071 sym_link *opetype = operandType(result);
3076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3077 size = AOP_SIZE(result) - 1;
3079 /* signed or unsigned */
3080 if (SPEC_USIGN(opetype)) {
3081 /* unsigned is easy */
3082 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3083 l = aopGet(AOP(left),0,FALSE,FALSE);
3085 pic14_emitcode("div","ab");
3086 aopPut(AOP(result),"a",0);
3088 aopPut(AOP(result),zero,offset++);
3092 /* signed is a little bit more difficult */
3094 /* save the signs of the operands */
3095 l = aopGet(AOP(left),0,FALSE,FALSE);
3097 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3098 pic14_emitcode("push","acc"); /* save it on the stack */
3100 /* now sign adjust for both left & right */
3101 l = aopGet(AOP(right),0,FALSE,FALSE);
3103 lbl = newiTempLabel(NULL);
3104 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3105 pic14_emitcode("cpl","a");
3106 pic14_emitcode("inc","a");
3107 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3108 pic14_emitcode("mov","b,a");
3110 /* sign adjust left side */
3111 l = aopGet(AOP(left),0,FALSE,FALSE);
3114 lbl = newiTempLabel(NULL);
3115 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3116 pic14_emitcode("cpl","a");
3117 pic14_emitcode("inc","a");
3118 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3120 /* now the division */
3121 pic14_emitcode("div","ab");
3122 /* we are interested in the lower order
3124 pic14_emitcode("mov","b,a");
3125 lbl = newiTempLabel(NULL);
3126 pic14_emitcode("pop","acc");
3127 /* if there was an over flow we don't
3128 adjust the sign of the result */
3129 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3130 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3132 pic14_emitcode("clr","a");
3133 pic14_emitcode("subb","a,b");
3134 pic14_emitcode("mov","b,a");
3135 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3137 /* now we are done */
3138 aopPut(AOP(result),"b",0);
3140 pic14_emitcode("mov","c,b.7");
3141 pic14_emitcode("subb","a,acc");
3144 aopPut(AOP(result),"a",offset++);
3148 /*-----------------------------------------------------------------*/
3149 /* genDiv - generates code for division */
3150 /*-----------------------------------------------------------------*/
3151 static void genDiv (iCode *ic)
3153 operand *left = IC_LEFT(ic);
3154 operand *right = IC_RIGHT(ic);
3155 operand *result= IC_RESULT(ic);
3157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3158 /* assign the amsops */
3159 aopOp (left,ic,FALSE);
3160 aopOp (right,ic,FALSE);
3161 aopOp (result,ic,TRUE);
3163 /* special cases first */
3165 if (AOP_TYPE(left) == AOP_CRY &&
3166 AOP_TYPE(right)== AOP_CRY) {
3167 genDivbits(left,right,result);
3171 /* if both are of size == 1 */
3172 if (AOP_SIZE(left) == 1 &&
3173 AOP_SIZE(right) == 1 ) {
3174 genDivOneByte(left,right,result);
3178 /* should have been converted to function call */
3181 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3183 freeAsmop(result,NULL,ic,TRUE);
3186 /*-----------------------------------------------------------------*/
3187 /* genModbits :- modulus of bits */
3188 /*-----------------------------------------------------------------*/
3189 static void genModbits (operand *left,
3196 /* the result must be bit */
3197 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3198 l = aopGet(AOP(left),0,FALSE,FALSE);
3202 pic14_emitcode("div","ab");
3203 pic14_emitcode("mov","a,b");
3204 pic14_emitcode("rrc","a");
3205 aopPut(AOP(result),"c",0);
3208 /*-----------------------------------------------------------------*/
3209 /* genModOneByte : 8 bit modulus */
3210 /*-----------------------------------------------------------------*/
3211 static void genModOneByte (operand *left,
3215 sym_link *opetype = operandType(result);
3219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3220 /* signed or unsigned */
3221 if (SPEC_USIGN(opetype)) {
3222 /* unsigned is easy */
3223 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3224 l = aopGet(AOP(left),0,FALSE,FALSE);
3226 pic14_emitcode("div","ab");
3227 aopPut(AOP(result),"b",0);
3231 /* signed is a little bit more difficult */
3233 /* save the signs of the operands */
3234 l = aopGet(AOP(left),0,FALSE,FALSE);
3237 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3238 pic14_emitcode("push","acc"); /* save it on the stack */
3240 /* now sign adjust for both left & right */
3241 l = aopGet(AOP(right),0,FALSE,FALSE);
3244 lbl = newiTempLabel(NULL);
3245 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3246 pic14_emitcode("cpl","a");
3247 pic14_emitcode("inc","a");
3248 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3249 pic14_emitcode("mov","b,a");
3251 /* sign adjust left side */
3252 l = aopGet(AOP(left),0,FALSE,FALSE);
3255 lbl = newiTempLabel(NULL);
3256 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3257 pic14_emitcode("cpl","a");
3258 pic14_emitcode("inc","a");
3259 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3261 /* now the multiplication */
3262 pic14_emitcode("div","ab");
3263 /* we are interested in the lower order
3265 lbl = newiTempLabel(NULL);
3266 pic14_emitcode("pop","acc");
3267 /* if there was an over flow we don't
3268 adjust the sign of the result */
3269 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3270 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3272 pic14_emitcode("clr","a");
3273 pic14_emitcode("subb","a,b");
3274 pic14_emitcode("mov","b,a");
3275 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3277 /* now we are done */
3278 aopPut(AOP(result),"b",0);
3282 /*-----------------------------------------------------------------*/
3283 /* genMod - generates code for division */
3284 /*-----------------------------------------------------------------*/
3285 static void genMod (iCode *ic)
3287 operand *left = IC_LEFT(ic);
3288 operand *right = IC_RIGHT(ic);
3289 operand *result= IC_RESULT(ic);
3291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3292 /* assign the amsops */
3293 aopOp (left,ic,FALSE);
3294 aopOp (right,ic,FALSE);
3295 aopOp (result,ic,TRUE);
3297 /* special cases first */
3299 if (AOP_TYPE(left) == AOP_CRY &&
3300 AOP_TYPE(right)== AOP_CRY) {
3301 genModbits(left,right,result);
3305 /* if both are of size == 1 */
3306 if (AOP_SIZE(left) == 1 &&
3307 AOP_SIZE(right) == 1 ) {
3308 genModOneByte(left,right,result);
3312 /* should have been converted to function call */
3316 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3317 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3318 freeAsmop(result,NULL,ic,TRUE);
3321 /*-----------------------------------------------------------------*/
3322 /* genIfxJump :- will create a jump depending on the ifx */
3323 /*-----------------------------------------------------------------*/
3325 note: May need to add parameter to indicate when a variable is in bit space.
3327 static void genIfxJump (iCode *ic, char *jval)
3330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3331 /* if true label then we jump if condition
3333 if ( IC_TRUE(ic) ) {
3335 if(strcmp(jval,"a") == 0)
3337 else if (strcmp(jval,"c") == 0)
3340 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3341 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3344 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3345 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3349 /* false label is present */
3350 if(strcmp(jval,"a") == 0)
3352 else if (strcmp(jval,"c") == 0)
3355 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3356 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3359 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3360 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3365 /* mark the icode as generated */
3369 /*-----------------------------------------------------------------*/
3371 /*-----------------------------------------------------------------*/
3372 static void genSkip(iCode *ifx,int status_bit)
3377 if ( IC_TRUE(ifx) ) {
3378 switch(status_bit) {
3393 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3394 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3398 switch(status_bit) {
3412 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3413 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3419 /*-----------------------------------------------------------------*/
3421 /*-----------------------------------------------------------------*/
3422 static void genSkipc(resolvedIfx *rifx)
3432 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3433 rifx->generated = 1;
3436 /*-----------------------------------------------------------------*/
3438 /*-----------------------------------------------------------------*/
3439 static void genSkipz(iCode *ifx, int condition)
3450 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3452 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3455 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3457 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3460 /*-----------------------------------------------------------------*/
3461 /* genCmp :- greater or less than comparison */
3462 /*-----------------------------------------------------------------*/
3463 static void genCmp (operand *left,operand *right,
3464 operand *result, iCode *ifx, int sign)
3466 int size, offset = 0 ;
3467 unsigned long lit = 0L,i = 0;
3470 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3472 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3473 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3476 resolveIfx(&rIfx,ifx);
3478 /* if left & right are bit variables */
3479 if (AOP_TYPE(left) == AOP_CRY &&
3480 AOP_TYPE(right) == AOP_CRY ) {
3481 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3482 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3484 /* subtract right from left if at the
3485 end the carry flag is set then we know that
3486 left is greater than right */
3487 size = max(AOP_SIZE(left),AOP_SIZE(right));
3489 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3490 if((size == 1) && !sign &&
3491 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3492 symbol *lbl = newiTempLabel(NULL);
3493 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3494 aopGet(AOP(left),offset,FALSE,FALSE),
3495 aopGet(AOP(right),offset,FALSE,FALSE),
3497 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3500 if(AOP_TYPE(right) == AOP_LIT) {
3501 symbol *lbl = newiTempLabel(NULL);
3503 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3505 DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3508 i = (lit >> (size*8)) & 0xff;
3511 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3513 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3515 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3518 emitpcode(POC_MOVLW, popGetLit(i));
3519 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3521 i = (lit >> (size*8)) & 0xff;
3522 emitpcode(POC_MOVLW, popGetLit(i));
3524 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3529 //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3532 emitpLabel(lbl->key);
3539 if(AOP_TYPE(left) == AOP_LIT) {
3540 //symbol *lbl = newiTempLabel(NULL);
3542 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3544 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3549 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3551 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3554 if(IC_TRUE(ifx) != NULL)
3555 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3557 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3560 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3561 emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3562 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3563 rIfx.condition ^= 1;
3564 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3568 i = (lit >> (size*8)) & 0xff;
3572 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3574 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3577 if(IC_TRUE(ifx) != NULL)
3578 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3580 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3584 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3585 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3587 i = (lit >> (size*8)) & 0xff;
3588 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3590 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3593 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3598 emitpLabel(lbl->key);
3600 if(ifx) ifx->generated = 1;
3606 DEBUGpic14_emitcode(";sign","%d",sign);
3608 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3609 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3611 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3612 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3617 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3619 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3620 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3623 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3625 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3626 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3634 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3635 pic14_outBitC(result);
3637 /* if the result is used in the next
3638 ifx conditional branch then generate
3639 code a little differently */
3641 genIfxJump (ifx,"c");
3643 pic14_outBitC(result);
3644 /* leave the result in acc */
3649 /*-----------------------------------------------------------------*/
3650 /* genCmpGt :- greater than comparison */
3651 /*-----------------------------------------------------------------*/
3652 static void genCmpGt (iCode *ic, iCode *ifx)
3654 operand *left, *right, *result;
3655 sym_link *letype , *retype;
3658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3660 right= IC_RIGHT(ic);
3661 result = IC_RESULT(ic);
3663 letype = getSpec(operandType(left));
3664 retype =getSpec(operandType(right));
3665 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3666 /* assign the amsops */
3667 aopOp (left,ic,FALSE);
3668 aopOp (right,ic,FALSE);
3669 aopOp (result,ic,TRUE);
3671 genCmp(right, left, result, ifx, sign);
3673 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3674 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3675 freeAsmop(result,NULL,ic,TRUE);
3678 /*-----------------------------------------------------------------*/
3679 /* genCmpLt - less than comparisons */
3680 /*-----------------------------------------------------------------*/
3681 static void genCmpLt (iCode *ic, iCode *ifx)
3683 operand *left, *right, *result;
3684 sym_link *letype , *retype;
3687 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3689 right= IC_RIGHT(ic);
3690 result = IC_RESULT(ic);
3692 letype = getSpec(operandType(left));
3693 retype =getSpec(operandType(right));
3694 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3696 /* assign the amsops */
3697 aopOp (left,ic,FALSE);
3698 aopOp (right,ic,FALSE);
3699 aopOp (result,ic,TRUE);
3701 genCmp(left, right, result, ifx, sign);
3703 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3704 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3705 freeAsmop(result,NULL,ic,TRUE);
3708 /*-----------------------------------------------------------------*/
3709 /* genc16bit2lit - compare a 16 bit value to a literal */
3710 /*-----------------------------------------------------------------*/
3711 static void genc16bit2lit(operand *op, int lit, int offset)
3715 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3716 if( (lit&0xff) == 0)
3721 switch( BYTEofLONG(lit,i)) {
3723 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3726 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3729 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3732 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3733 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3738 switch( BYTEofLONG(lit,i)) {
3740 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3744 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3748 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3751 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3753 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3759 /*-----------------------------------------------------------------*/
3760 /* gencjneshort - compare and jump if not equal */
3761 /*-----------------------------------------------------------------*/
3762 static void gencjne(operand *left, operand *right, iCode *ifx)
3764 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3769 unsigned long lit = 0L;
3770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3771 DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3772 AopType(AOP_TYPE(left)),
3773 aopGet(AOP(left),0,TRUE,FALSE),
3774 AopType(AOP_TYPE(right)),
3775 aopGet(AOP(right),0,FALSE,FALSE),
3778 resolveIfx(&rIfx,ifx);
3779 lbl = newiTempLabel(NULL);
3782 /* if the left side is a literal or
3783 if the right is in a pointer register and left
3785 if ((AOP_TYPE(left) == AOP_LIT) ||
3786 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3791 if(AOP_TYPE(right) == AOP_LIT)
3792 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3794 /* if the right side is a literal then anything goes */
3795 if (AOP_TYPE(right) == AOP_LIT &&
3796 AOP_TYPE(left) != AOP_DIR ) {
3799 genc16bit2lit(left, lit, 0);
3801 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3802 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3807 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3808 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3809 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3810 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3812 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3813 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3817 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3818 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3826 /* if the right side is in a register or in direct space or
3827 if the left is a pointer register & right is not */
3828 else if (AOP_TYPE(right) == AOP_REG ||
3829 AOP_TYPE(right) == AOP_DIR ||
3830 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3831 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3834 genc16bit2lit(left, lit, 0);
3836 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3837 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3842 if((AOP_TYPE(left) == AOP_DIR) &&
3843 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3845 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3846 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3848 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3850 switch (lit & 0xff) {
3852 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3855 emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3856 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3860 emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3861 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3865 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3866 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3871 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3872 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3875 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3880 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3889 } else if(AOP_TYPE(right) == AOP_REG &&
3890 AOP_TYPE(left) != AOP_DIR){
3893 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3894 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3895 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3900 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3905 /* right is a pointer reg need both a & b */
3907 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3909 pic14_emitcode("mov","b,%s",l);
3910 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3911 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3915 emitpLabel(lbl->key);
3922 /*-----------------------------------------------------------------*/
3923 /* gencjne - compare and jump if not equal */
3924 /*-----------------------------------------------------------------*/
3925 static void gencjne(operand *left, operand *right, iCode *ifx)
3927 symbol *tlbl = newiTempLabel(NULL);
3929 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3930 gencjneshort(left, right, lbl);
3932 pic14_emitcode("mov","a,%s",one);
3933 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3934 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3935 pic14_emitcode("clr","a");
3936 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
3938 emitpLabel(lbl->key);
3939 emitpLabel(tlbl->key);
3944 /*-----------------------------------------------------------------*/
3945 /* genCmpEq - generates code for equal to */
3946 /*-----------------------------------------------------------------*/
3947 static void genCmpEq (iCode *ic, iCode *ifx)
3949 operand *left, *right, *result;
3950 unsigned long lit = 0L;
3953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3956 DEBUGpic14_emitcode ("; ifx is non-null","");
3958 DEBUGpic14_emitcode ("; ifx is null","");
3960 aopOp((left=IC_LEFT(ic)),ic,FALSE);
3961 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
3962 aopOp((result=IC_RESULT(ic)),ic,TRUE);
3965 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
3966 AopType(AOP_TYPE(IC_RESULT(ic))),
3967 AopType(AOP_TYPE(IC_LEFT(ic))),
3968 AopType(AOP_TYPE(IC_RIGHT(ic))));
3970 size = max(AOP_SIZE(left),AOP_SIZE(right));
3971 DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
3972 AopType(AOP_TYPE(result)),
3973 aopGet(AOP(result),0,TRUE,FALSE),
3974 AopType(AOP_TYPE(left)),
3975 aopGet(AOP(left),0,TRUE,FALSE),
3976 AopType(AOP_TYPE(right)),
3977 aopGet(AOP(right),0,FALSE,FALSE),
3981 /* if literal, literal on the right or
3982 if the right is in a pointer register and left
3984 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
3985 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3986 operand *t = IC_RIGHT(ic);
3987 IC_RIGHT(ic) = IC_LEFT(ic);
3991 if(ifx && !AOP_SIZE(result)){
3993 /* if they are both bit variables */
3994 if (AOP_TYPE(left) == AOP_CRY &&
3995 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
3996 if(AOP_TYPE(right) == AOP_LIT){
3997 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
3999 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4000 pic14_emitcode("cpl","c");
4001 } else if(lit == 1L) {
4002 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4004 pic14_emitcode("clr","c");
4006 /* AOP_TYPE(right) == AOP_CRY */
4008 symbol *lbl = newiTempLabel(NULL);
4009 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4010 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4011 pic14_emitcode("cpl","c");
4012 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4014 /* if true label then we jump if condition
4016 tlbl = newiTempLabel(NULL);
4017 if ( IC_TRUE(ifx) ) {
4018 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4019 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4021 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4022 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4024 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4027 /* They're not both bit variables. Is the right a literal? */
4028 if(AOP_TYPE(right) == AOP_LIT) {
4029 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4035 switch(lit & 0xff) {
4037 if ( IC_TRUE(ifx) ) {
4038 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4040 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4042 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4043 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4047 if ( IC_TRUE(ifx) ) {
4048 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4050 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4052 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4053 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4057 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4059 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4064 /* end of size == 1 */
4068 genc16bit2lit(left,lit,offset);
4071 /* end of size == 2 */
4076 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4077 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4078 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4079 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4083 /* search for patterns that can be optimized */
4085 genc16bit2lit(left,lit,0);
4088 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4090 genc16bit2lit(left,lit,2);
4092 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4093 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4106 } else if(AOP_TYPE(right) == AOP_CRY ) {
4107 /* we know the left is not a bit, but that the right is */
4108 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4109 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4110 popGet(AOP(right),offset,FALSE,FALSE));
4111 emitpcode(POC_XORLW,popGetLit(1));
4113 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4115 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4116 AOP(right)->aopu.aop_dir,
4117 AOP(right)->aopu.aop_dir);
4119 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4120 AOP(right)->aopu.aop_dir,
4121 AOP(right)->aopu.aop_dir);
4123 pic14_emitcode("xorlw","1");
4125 /* if the two are equal, then W will be 0 and the Z bit is set
4126 * we could test Z now, or go ahead and check the high order bytes if
4127 * the variable we're comparing is larger than a byte. */
4130 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4131 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4133 if ( IC_TRUE(ifx) ) {
4135 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4136 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4139 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4140 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4144 /* They're both variables that are larger than bits */
4147 tlbl = newiTempLabel(NULL);
4150 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4151 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4153 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4154 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4156 if ( IC_TRUE(ifx) ) {
4159 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4160 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4163 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4164 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4168 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4169 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4173 if(s>1 && IC_TRUE(ifx)) {
4174 emitpLabel(tlbl->key);
4175 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4179 /* mark the icode as generated */
4184 /* if they are both bit variables */
4185 if (AOP_TYPE(left) == AOP_CRY &&
4186 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4187 if(AOP_TYPE(right) == AOP_LIT){
4188 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4190 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4191 pic14_emitcode("cpl","c");
4192 } else if(lit == 1L) {
4193 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4195 pic14_emitcode("clr","c");
4197 /* AOP_TYPE(right) == AOP_CRY */
4199 symbol *lbl = newiTempLabel(NULL);
4200 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4201 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4202 pic14_emitcode("cpl","c");
4203 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4206 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4207 pic14_outBitC(result);
4211 genIfxJump (ifx,"c");
4214 /* if the result is used in an arithmetic operation
4215 then put the result in place */
4216 pic14_outBitC(result);
4219 gencjne(left,right,ifx);
4222 gencjne(left,right,newiTempLabel(NULL));
4224 if(IC_TRUE(ifx)->key)
4225 gencjne(left,right,IC_TRUE(ifx)->key);
4227 gencjne(left,right,IC_FALSE(ifx)->key);
4231 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4232 aopPut(AOP(result),"a",0);
4237 genIfxJump (ifx,"a");
4241 /* if the result is used in an arithmetic operation
4242 then put the result in place */
4243 if (AOP_TYPE(result) != AOP_CRY)
4244 pic14_outAcc(result);
4245 /* leave the result in acc */
4249 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4250 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4251 freeAsmop(result,NULL,ic,TRUE);
4254 /*-----------------------------------------------------------------*/
4255 /* ifxForOp - returns the icode containing the ifx for operand */
4256 /*-----------------------------------------------------------------*/
4257 static iCode *ifxForOp ( operand *op, iCode *ic )
4259 /* if true symbol then needs to be assigned */
4260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4261 if (IS_TRUE_SYMOP(op))
4264 /* if this has register type condition and
4265 the next instruction is ifx with the same operand
4266 and live to of the operand is upto the ifx only then */
4268 ic->next->op == IFX &&
4269 IC_COND(ic->next)->key == op->key &&
4270 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4274 ic->next->op == IFX &&
4275 IC_COND(ic->next)->key == op->key) {
4276 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4280 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4282 ic->next->op == IFX)
4283 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4286 ic->next->op == IFX &&
4287 IC_COND(ic->next)->key == op->key) {
4288 DEBUGpic14_emitcode ("; "," key is okay");
4289 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4290 OP_SYMBOL(op)->liveTo,
4297 /*-----------------------------------------------------------------*/
4298 /* genAndOp - for && operation */
4299 /*-----------------------------------------------------------------*/
4300 static void genAndOp (iCode *ic)
4302 operand *left,*right, *result;
4305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4306 /* note here that && operations that are in an
4307 if statement are taken away by backPatchLabels
4308 only those used in arthmetic operations remain */
4309 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4310 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4311 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4313 /* if both are bit variables */
4314 if (AOP_TYPE(left) == AOP_CRY &&
4315 AOP_TYPE(right) == AOP_CRY ) {
4316 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4317 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4318 pic14_outBitC(result);
4320 tlbl = newiTempLabel(NULL);
4321 pic14_toBoolean(left);
4322 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4323 pic14_toBoolean(right);
4324 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4325 pic14_outBitAcc(result);
4328 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4329 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4330 freeAsmop(result,NULL,ic,TRUE);
4334 /*-----------------------------------------------------------------*/
4335 /* genOrOp - for || operation */
4336 /*-----------------------------------------------------------------*/
4339 modified this code, but it doesn't appear to ever get called
4342 static void genOrOp (iCode *ic)
4344 operand *left,*right, *result;
4347 /* note here that || operations that are in an
4348 if statement are taken away by backPatchLabels
4349 only those used in arthmetic operations remain */
4350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4351 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4352 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4353 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4355 /* if both are bit variables */
4356 if (AOP_TYPE(left) == AOP_CRY &&
4357 AOP_TYPE(right) == AOP_CRY ) {
4358 pic14_emitcode("clrc","");
4359 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4360 AOP(left)->aopu.aop_dir,
4361 AOP(left)->aopu.aop_dir);
4362 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4363 AOP(right)->aopu.aop_dir,
4364 AOP(right)->aopu.aop_dir);
4365 pic14_emitcode("setc","");
4368 tlbl = newiTempLabel(NULL);
4369 pic14_toBoolean(left);
4371 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4372 pic14_toBoolean(right);
4373 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4375 pic14_outBitAcc(result);
4378 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4379 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380 freeAsmop(result,NULL,ic,TRUE);
4383 /*-----------------------------------------------------------------*/
4384 /* isLiteralBit - test if lit == 2^n */
4385 /*-----------------------------------------------------------------*/
4386 static int isLiteralBit(unsigned long lit)
4388 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4389 0x100L,0x200L,0x400L,0x800L,
4390 0x1000L,0x2000L,0x4000L,0x8000L,
4391 0x10000L,0x20000L,0x40000L,0x80000L,
4392 0x100000L,0x200000L,0x400000L,0x800000L,
4393 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4394 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4397 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4398 for(idx = 0; idx < 32; idx++)
4404 /*-----------------------------------------------------------------*/
4405 /* continueIfTrue - */
4406 /*-----------------------------------------------------------------*/
4407 static void continueIfTrue (iCode *ic)
4409 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4411 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4415 /*-----------------------------------------------------------------*/
4417 /*-----------------------------------------------------------------*/
4418 static void jumpIfTrue (iCode *ic)
4420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4422 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4426 /*-----------------------------------------------------------------*/
4427 /* jmpTrueOrFalse - */
4428 /*-----------------------------------------------------------------*/
4429 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4431 // ugly but optimized by peephole
4432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4434 symbol *nlbl = newiTempLabel(NULL);
4435 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4436 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4437 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4438 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4441 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4442 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4447 /*-----------------------------------------------------------------*/
4448 /* genAnd - code for and */
4449 /*-----------------------------------------------------------------*/
4450 static void genAnd (iCode *ic, iCode *ifx)
4452 operand *left, *right, *result;
4454 unsigned long lit = 0L;
4459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4460 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4461 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4462 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4464 resolveIfx(&rIfx,ifx);
4466 /* if left is a literal & right is not then exchange them */
4467 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4468 AOP_NEEDSACC(left)) {
4469 operand *tmp = right ;
4474 /* if result = right then exchange them */
4475 if(pic14_sameRegs(AOP(result),AOP(right))){
4476 operand *tmp = right ;
4481 /* if right is bit then exchange them */
4482 if (AOP_TYPE(right) == AOP_CRY &&
4483 AOP_TYPE(left) != AOP_CRY){
4484 operand *tmp = right ;
4488 if(AOP_TYPE(right) == AOP_LIT)
4489 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4491 size = AOP_SIZE(result);
4493 DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4494 AopType(AOP_TYPE(result)),
4495 aopGet(AOP(result),0,TRUE,FALSE),
4496 AopType(AOP_TYPE(left)),
4497 aopGet(AOP(left),0,TRUE,FALSE),
4498 AopType(AOP_TYPE(right)),
4499 aopGet(AOP(right),0,FALSE,FALSE),
4502 // result = bit & yy;
4503 if (AOP_TYPE(left) == AOP_CRY){
4504 // c = bit & literal;
4505 if(AOP_TYPE(right) == AOP_LIT){
4507 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4510 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4513 if(size && (AOP_TYPE(result) == AOP_CRY)){
4514 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4517 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4521 pic14_emitcode("clr","c");
4524 if (AOP_TYPE(right) == AOP_CRY){
4526 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4527 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4530 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4532 pic14_emitcode("rrc","a");
4533 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4539 pic14_outBitC(result);
4541 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4542 genIfxJump(ifx, "c");
4546 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4547 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4548 if((AOP_TYPE(right) == AOP_LIT) &&
4549 (AOP_TYPE(result) == AOP_CRY) &&
4550 (AOP_TYPE(left) != AOP_CRY)){
4551 int posbit = isLiteralBit(lit);
4555 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4558 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4564 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4565 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4567 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4568 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4571 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4572 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4573 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4580 symbol *tlbl = newiTempLabel(NULL);
4581 int sizel = AOP_SIZE(left);
4583 pic14_emitcode("setb","c");
4585 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4586 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4588 if((posbit = isLiteralBit(bytelit)) != 0)
4589 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4591 if(bytelit != 0x0FFL)
4592 pic14_emitcode("anl","a,%s",
4593 aopGet(AOP(right),offset,FALSE,TRUE));
4594 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4599 // bit = left & literal
4601 pic14_emitcode("clr","c");
4602 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4604 // if(left & literal)
4607 jmpTrueOrFalse(ifx, tlbl);
4611 pic14_outBitC(result);
4615 /* if left is same as result */
4616 if(pic14_sameRegs(AOP(result),AOP(left))){
4618 for(;size--; offset++,lit>>=8) {
4619 if(AOP_TYPE(right) == AOP_LIT){
4620 switch(lit & 0xff) {
4622 /* and'ing with 0 has clears the result */
4623 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4624 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4627 /* and'ing with 0xff is a nop when the result and left are the same */
4632 int p = my_powof2( (~lit) & 0xff );
4634 /* only one bit is set in the literal, so use a bcf instruction */
4635 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4636 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4637 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4640 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4641 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4642 if(know_W != (lit&0xff))
4643 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4645 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4650 if (AOP_TYPE(left) == AOP_ACC) {
4651 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4653 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4654 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4661 // left & result in different registers
4662 if(AOP_TYPE(result) == AOP_CRY){
4664 // if(size), result in bit
4665 // if(!size && ifx), conditional oper: if(left & right)
4666 symbol *tlbl = newiTempLabel(NULL);
4667 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4669 pic14_emitcode("setb","c");
4671 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4672 pic14_emitcode("anl","a,%s",
4673 aopGet(AOP(left),offset,FALSE,FALSE));
4674 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4679 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4680 pic14_outBitC(result);
4682 jmpTrueOrFalse(ifx, tlbl);
4684 for(;(size--);offset++) {
4686 // result = left & right
4687 if(AOP_TYPE(right) == AOP_LIT){
4688 int t = (lit >> (offset*8)) & 0x0FFL;
4691 pic14_emitcode("clrf","%s",
4692 aopGet(AOP(result),offset,FALSE,FALSE));
4693 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4696 pic14_emitcode("movf","%s,w",
4697 aopGet(AOP(left),offset,FALSE,FALSE));
4698 pic14_emitcode("movwf","%s",
4699 aopGet(AOP(result),offset,FALSE,FALSE));
4700 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4701 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4704 pic14_emitcode("movlw","0x%x",t);
4705 pic14_emitcode("andwf","%s,w",
4706 aopGet(AOP(left),offset,FALSE,FALSE));
4707 pic14_emitcode("movwf","%s",
4708 aopGet(AOP(result),offset,FALSE,FALSE));
4710 emitpcode(POC_MOVLW, popGetLit(t));
4711 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4712 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4717 if (AOP_TYPE(left) == AOP_ACC) {
4718 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4719 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4721 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4722 pic14_emitcode("andwf","%s,w",
4723 aopGet(AOP(left),offset,FALSE,FALSE));
4724 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4725 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4727 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4728 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4734 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4735 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4736 freeAsmop(result,NULL,ic,TRUE);
4739 /*-----------------------------------------------------------------*/
4740 /* genOr - code for or */
4741 /*-----------------------------------------------------------------*/
4742 static void genOr (iCode *ic, iCode *ifx)
4744 operand *left, *right, *result;
4746 unsigned long lit = 0L;
4748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4750 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4751 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4752 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4755 /* if left is a literal & right is not then exchange them */
4756 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4757 AOP_NEEDSACC(left)) {
4758 operand *tmp = right ;
4763 /* if result = right then exchange them */
4764 if(pic14_sameRegs(AOP(result),AOP(right))){
4765 operand *tmp = right ;
4770 /* if right is bit then exchange them */
4771 if (AOP_TYPE(right) == AOP_CRY &&
4772 AOP_TYPE(left) != AOP_CRY){
4773 operand *tmp = right ;
4778 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4779 AopType(AOP_TYPE(result)),
4780 AopType(AOP_TYPE(left)),
4781 AopType(AOP_TYPE(right)));
4783 if(AOP_TYPE(right) == AOP_LIT)
4784 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4786 size = AOP_SIZE(result);
4790 if (AOP_TYPE(left) == AOP_CRY){
4791 if(AOP_TYPE(right) == AOP_LIT){
4792 // c = bit & literal;
4794 // lit != 0 => result = 1
4795 if(AOP_TYPE(result) == AOP_CRY){
4797 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4798 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4799 // AOP(result)->aopu.aop_dir,
4800 // AOP(result)->aopu.aop_dir);
4802 continueIfTrue(ifx);
4806 // lit == 0 => result = left
4807 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4809 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4812 if (AOP_TYPE(right) == AOP_CRY){
4813 if(pic14_sameRegs(AOP(result),AOP(left))){
4815 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4816 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4817 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4819 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4820 AOP(result)->aopu.aop_dir,
4821 AOP(result)->aopu.aop_dir);
4822 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4823 AOP(right)->aopu.aop_dir,
4824 AOP(right)->aopu.aop_dir);
4825 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4826 AOP(result)->aopu.aop_dir,
4827 AOP(result)->aopu.aop_dir);
4829 if( AOP_TYPE(result) == AOP_ACC) {
4830 emitpcode(POC_MOVLW, popGetLit(0));
4831 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4832 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4833 emitpcode(POC_MOVLW, popGetLit(1));
4837 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4838 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4839 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4840 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4842 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4843 AOP(result)->aopu.aop_dir,
4844 AOP(result)->aopu.aop_dir);
4845 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4846 AOP(right)->aopu.aop_dir,
4847 AOP(right)->aopu.aop_dir);
4848 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4849 AOP(left)->aopu.aop_dir,
4850 AOP(left)->aopu.aop_dir);
4851 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4852 AOP(result)->aopu.aop_dir,
4853 AOP(result)->aopu.aop_dir);
4858 symbol *tlbl = newiTempLabel(NULL);
4859 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4862 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4863 if( AOP_TYPE(right) == AOP_ACC) {
4864 emitpcode(POC_IORLW, popGetLit(0));
4866 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4867 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4872 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4873 pic14_emitcode(";XXX setb","c");
4874 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4875 AOP(left)->aopu.aop_dir,tlbl->key+100);
4876 pic14_toBoolean(right);
4877 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4878 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4879 jmpTrueOrFalse(ifx, tlbl);
4883 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4890 pic14_outBitC(result);
4892 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4893 genIfxJump(ifx, "c");
4897 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4898 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4899 if((AOP_TYPE(right) == AOP_LIT) &&
4900 (AOP_TYPE(result) == AOP_CRY) &&
4901 (AOP_TYPE(left) != AOP_CRY)){
4903 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4906 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4908 continueIfTrue(ifx);
4911 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4912 // lit = 0, result = boolean(left)
4914 pic14_emitcode(";XXX setb","c");
4915 pic14_toBoolean(right);
4917 symbol *tlbl = newiTempLabel(NULL);
4918 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4920 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4922 genIfxJump (ifx,"a");
4926 pic14_outBitC(result);
4930 /* if left is same as result */
4931 if(pic14_sameRegs(AOP(result),AOP(left))){
4933 for(;size--; offset++,lit>>=8) {
4934 if(AOP_TYPE(right) == AOP_LIT){
4935 if((lit & 0xff) == 0)
4936 /* or'ing with 0 has no effect */
4939 int p = my_powof2(lit & 0xff);
4941 /* only one bit is set in the literal, so use a bsf instruction */
4943 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4945 if(know_W != (lit & 0xff))
4946 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4947 know_W = lit & 0xff;
4948 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4953 if (AOP_TYPE(left) == AOP_ACC) {
4954 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
4955 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4957 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
4958 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
4960 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4961 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
4967 // left & result in different registers
4968 if(AOP_TYPE(result) == AOP_CRY){
4970 // if(size), result in bit
4971 // if(!size && ifx), conditional oper: if(left | right)
4972 symbol *tlbl = newiTempLabel(NULL);
4973 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
4974 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4978 pic14_emitcode(";XXX setb","c");
4980 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4981 pic14_emitcode(";XXX orl","a,%s",
4982 aopGet(AOP(left),offset,FALSE,FALSE));
4983 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4988 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4989 pic14_outBitC(result);
4991 jmpTrueOrFalse(ifx, tlbl);
4992 } else for(;(size--);offset++){
4994 // result = left & right
4995 if(AOP_TYPE(right) == AOP_LIT){
4996 int t = (lit >> (offset*8)) & 0x0FFL;
4999 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
5000 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5002 pic14_emitcode("movf","%s,w",
5003 aopGet(AOP(left),offset,FALSE,FALSE));
5004 pic14_emitcode("movwf","%s",
5005 aopGet(AOP(result),offset,FALSE,FALSE));
5008 emitpcode(POC_MOVLW, popGetLit(t));
5009 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5010 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5012 pic14_emitcode("movlw","0x%x",t);
5013 pic14_emitcode("iorwf","%s,w",
5014 aopGet(AOP(left),offset,FALSE,FALSE));
5015 pic14_emitcode("movwf","%s",
5016 aopGet(AOP(result),offset,FALSE,FALSE));
5022 // faster than result <- left, anl result,right
5023 // and better if result is SFR
5024 if (AOP_TYPE(left) == AOP_ACC) {
5025 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
5026 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5028 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5029 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5031 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5032 pic14_emitcode("iorwf","%s,w",
5033 aopGet(AOP(left),offset,FALSE,FALSE));
5035 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5036 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5041 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5043 freeAsmop(result,NULL,ic,TRUE);
5046 /*-----------------------------------------------------------------*/
5047 /* genXor - code for xclusive or */
5048 /*-----------------------------------------------------------------*/
5049 static void genXor (iCode *ic, iCode *ifx)
5051 operand *left, *right, *result;
5053 unsigned long lit = 0L;
5055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5057 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5058 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5059 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5061 /* if left is a literal & right is not ||
5062 if left needs acc & right does not */
5063 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5064 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5065 operand *tmp = right ;
5070 /* if result = right then exchange them */
5071 if(pic14_sameRegs(AOP(result),AOP(right))){
5072 operand *tmp = right ;
5077 /* if right is bit then exchange them */
5078 if (AOP_TYPE(right) == AOP_CRY &&
5079 AOP_TYPE(left) != AOP_CRY){
5080 operand *tmp = right ;
5084 if(AOP_TYPE(right) == AOP_LIT)
5085 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5087 size = AOP_SIZE(result);
5091 if (AOP_TYPE(left) == AOP_CRY){
5092 if(AOP_TYPE(right) == AOP_LIT){
5093 // c = bit & literal;
5095 // lit>>1 != 0 => result = 1
5096 if(AOP_TYPE(result) == AOP_CRY){
5098 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5100 continueIfTrue(ifx);
5103 pic14_emitcode("setb","c");
5107 // lit == 0, result = left
5108 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5110 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5112 // lit == 1, result = not(left)
5113 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5114 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5117 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5118 pic14_emitcode("cpl","c");
5125 symbol *tlbl = newiTempLabel(NULL);
5126 if (AOP_TYPE(right) == AOP_CRY){
5128 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5131 int sizer = AOP_SIZE(right);
5133 // if val>>1 != 0, result = 1
5134 pic14_emitcode("setb","c");
5136 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5138 // test the msb of the lsb
5139 pic14_emitcode("anl","a,#0xfe");
5140 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5144 pic14_emitcode("rrc","a");
5146 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5147 pic14_emitcode("cpl","c");
5148 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5153 pic14_outBitC(result);
5155 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5156 genIfxJump(ifx, "c");
5160 if(pic14_sameRegs(AOP(result),AOP(left))){
5161 /* if left is same as result */
5162 for(;size--; offset++) {
5163 if(AOP_TYPE(right) == AOP_LIT){
5164 int t = (lit >> (offset*8)) & 0x0FFL;
5168 if (IS_AOP_PREG(left)) {
5169 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5170 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5171 aopPut(AOP(result),"a",offset);
5173 emitpcode(POC_MOVLW, popGetLit(t));
5174 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5175 pic14_emitcode("xrl","%s,%s",
5176 aopGet(AOP(left),offset,FALSE,TRUE),
5177 aopGet(AOP(right),offset,FALSE,FALSE));
5180 if (AOP_TYPE(left) == AOP_ACC)
5181 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5183 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5184 if (IS_AOP_PREG(left)) {
5185 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5186 aopPut(AOP(result),"a",offset);
5188 pic14_emitcode("xrl","%s,a",
5189 aopGet(AOP(left),offset,FALSE,TRUE));
5194 // left & result in different registers
5195 if(AOP_TYPE(result) == AOP_CRY){
5197 // if(size), result in bit
5198 // if(!size && ifx), conditional oper: if(left ^ right)
5199 symbol *tlbl = newiTempLabel(NULL);
5200 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5202 pic14_emitcode("setb","c");
5204 if((AOP_TYPE(right) == AOP_LIT) &&
5205 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5206 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5208 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5209 pic14_emitcode("xrl","a,%s",
5210 aopGet(AOP(left),offset,FALSE,FALSE));
5212 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5217 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5218 pic14_outBitC(result);
5220 jmpTrueOrFalse(ifx, tlbl);
5221 } else for(;(size--);offset++){
5223 // result = left & right
5224 if(AOP_TYPE(right) == AOP_LIT){
5225 int t = (lit >> (offset*8)) & 0x0FFL;
5228 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5229 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5230 pic14_emitcode("movf","%s,w",
5231 aopGet(AOP(left),offset,FALSE,FALSE));
5232 pic14_emitcode("movwf","%s",
5233 aopGet(AOP(result),offset,FALSE,FALSE));
5236 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5237 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5238 pic14_emitcode("comf","%s,w",
5239 aopGet(AOP(left),offset,FALSE,FALSE));
5240 pic14_emitcode("movwf","%s",
5241 aopGet(AOP(result),offset,FALSE,FALSE));
5244 emitpcode(POC_MOVLW, popGetLit(t));
5245 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5246 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5247 pic14_emitcode("movlw","0x%x",t);
5248 pic14_emitcode("xorwf","%s,w",
5249 aopGet(AOP(left),offset,FALSE,FALSE));
5250 pic14_emitcode("movwf","%s",
5251 aopGet(AOP(result),offset,FALSE,FALSE));
5257 // faster than result <- left, anl result,right
5258 // and better if result is SFR
5259 if (AOP_TYPE(left) == AOP_ACC) {
5260 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5261 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5263 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5264 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5265 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5266 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5268 if ( AOP_TYPE(result) != AOP_ACC){
5269 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5270 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5276 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5277 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5278 freeAsmop(result,NULL,ic,TRUE);
5281 /*-----------------------------------------------------------------*/
5282 /* genInline - write the inline code out */
5283 /*-----------------------------------------------------------------*/
5284 static void genInline (iCode *ic)
5286 char *buffer, *bp, *bp1;
5288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5290 _G.inLine += (!options.asmpeep);
5292 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5293 strcpy(buffer,IC_INLINE(ic));
5295 /* emit each line as a code */
5299 pic14_emitcode(bp1,"");
5306 pic14_emitcode(bp1,"");
5313 pic14_emitcode(bp1,"");
5314 /* pic14_emitcode("",buffer); */
5315 _G.inLine -= (!options.asmpeep);
5318 /*-----------------------------------------------------------------*/
5319 /* genRRC - rotate right with carry */
5320 /*-----------------------------------------------------------------*/
5321 static void genRRC (iCode *ic)
5323 operand *left , *result ;
5324 int size, offset = 0;
5327 /* rotate right with carry */
5329 result=IC_RESULT(ic);
5330 aopOp (left,ic,FALSE);
5331 aopOp (result,ic,FALSE);
5333 /* move it to the result */
5334 size = AOP_SIZE(result);
5338 l = aopGet(AOP(left),offset,FALSE,FALSE);
5340 pic14_emitcode("rrc","a");
5341 if (AOP_SIZE(result) > 1)
5342 aopPut(AOP(result),"a",offset--);
5344 /* now we need to put the carry into the
5345 highest order byte of the result */
5346 if (AOP_SIZE(result) > 1) {
5347 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5350 pic14_emitcode("mov","acc.7,c");
5351 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5352 freeAsmop(left,NULL,ic,TRUE);
5353 freeAsmop(result,NULL,ic,TRUE);
5356 /*-----------------------------------------------------------------*/
5357 /* genRLC - generate code for rotate left with carry */
5358 /*-----------------------------------------------------------------*/
5359 static void genRLC (iCode *ic)
5361 operand *left , *result ;
5362 int size, offset = 0;
5365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5366 /* rotate right with carry */
5368 result=IC_RESULT(ic);
5369 aopOp (left,ic,FALSE);
5370 aopOp (result,ic,FALSE);
5372 /* move it to the result */
5373 size = AOP_SIZE(result);
5376 l = aopGet(AOP(left),offset,FALSE,FALSE);
5378 pic14_emitcode("add","a,acc");
5379 if (AOP_SIZE(result) > 1)
5380 aopPut(AOP(result),"a",offset++);
5382 l = aopGet(AOP(left),offset,FALSE,FALSE);
5384 pic14_emitcode("rlc","a");
5385 if (AOP_SIZE(result) > 1)
5386 aopPut(AOP(result),"a",offset++);
5389 /* now we need to put the carry into the
5390 highest order byte of the result */
5391 if (AOP_SIZE(result) > 1) {
5392 l = aopGet(AOP(result),0,FALSE,FALSE);
5395 pic14_emitcode("mov","acc.0,c");
5396 aopPut(AOP(result),"a",0);
5397 freeAsmop(left,NULL,ic,TRUE);
5398 freeAsmop(result,NULL,ic,TRUE);
5401 /*-----------------------------------------------------------------*/
5402 /* genGetHbit - generates code get highest order bit */
5403 /*-----------------------------------------------------------------*/
5404 static void genGetHbit (iCode *ic)
5406 operand *left, *result;
5408 result=IC_RESULT(ic);
5409 aopOp (left,ic,FALSE);
5410 aopOp (result,ic,FALSE);
5412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5413 /* get the highest order byte into a */
5414 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5415 if(AOP_TYPE(result) == AOP_CRY){
5416 pic14_emitcode("rlc","a");
5417 pic14_outBitC(result);
5420 pic14_emitcode("rl","a");
5421 pic14_emitcode("anl","a,#0x01");
5422 pic14_outAcc(result);
5426 freeAsmop(left,NULL,ic,TRUE);
5427 freeAsmop(result,NULL,ic,TRUE);
5430 /*-----------------------------------------------------------------*/
5431 /* AccRol - rotate left accumulator by known count */
5432 /*-----------------------------------------------------------------*/
5433 static void AccRol (int shCount)
5435 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5436 shCount &= 0x0007; // shCount : 0..7
5441 pic14_emitcode("rl","a");
5444 pic14_emitcode("rl","a");
5445 pic14_emitcode("rl","a");
5448 pic14_emitcode("swap","a");
5449 pic14_emitcode("rr","a");
5452 pic14_emitcode("swap","a");
5455 pic14_emitcode("swap","a");
5456 pic14_emitcode("rl","a");
5459 pic14_emitcode("rr","a");
5460 pic14_emitcode("rr","a");
5463 pic14_emitcode("rr","a");
5468 /*-----------------------------------------------------------------*/
5469 /* AccLsh - left shift accumulator by known count */
5470 /*-----------------------------------------------------------------*/
5471 static void AccLsh (int shCount)
5473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5476 pic14_emitcode("add","a,acc");
5479 pic14_emitcode("add","a,acc");
5480 pic14_emitcode("add","a,acc");
5482 /* rotate left accumulator */
5484 /* and kill the lower order bits */
5485 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5490 /*-----------------------------------------------------------------*/
5491 /* AccRsh - right shift accumulator by known count */
5492 /*-----------------------------------------------------------------*/
5493 static void AccRsh (int shCount)
5495 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5499 pic14_emitcode("rrc","a");
5501 /* rotate right accumulator */
5502 AccRol(8 - shCount);
5503 /* and kill the higher order bits */
5504 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5510 /*-----------------------------------------------------------------*/
5511 /* AccSRsh - signed right shift accumulator by known count */
5512 /*-----------------------------------------------------------------*/
5513 static void AccSRsh (int shCount)
5516 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5519 pic14_emitcode("mov","c,acc.7");
5520 pic14_emitcode("rrc","a");
5521 } else if(shCount == 2){
5522 pic14_emitcode("mov","c,acc.7");
5523 pic14_emitcode("rrc","a");
5524 pic14_emitcode("mov","c,acc.7");
5525 pic14_emitcode("rrc","a");
5527 tlbl = newiTempLabel(NULL);
5528 /* rotate right accumulator */
5529 AccRol(8 - shCount);
5530 /* and kill the higher order bits */
5531 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5532 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5533 pic14_emitcode("orl","a,#0x%02x",
5534 (unsigned char)~SRMask[shCount]);
5535 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5540 /*-----------------------------------------------------------------*/
5541 /* shiftR1Left2Result - shift right one byte from left to result */
5542 /*-----------------------------------------------------------------*/
5543 static void shiftR1Left2ResultSigned (operand *left, int offl,
5544 operand *result, int offr,
5549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5551 same = (left == result) || (AOP(left) == AOP(result));
5555 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5557 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5559 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5560 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5570 /*-----------------------------------------------------------------*/
5571 /* shiftR1Left2Result - shift right one byte from left to result */
5572 /*-----------------------------------------------------------------*/
5573 static void shiftR1Left2Result (operand *left, int offl,
5574 operand *result, int offr,
5575 int shCount, int sign)
5579 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5581 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5583 /* Copy the msb into the carry if signed. */
5585 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5595 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5597 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5598 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5604 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5606 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5607 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5610 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5615 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5617 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5618 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5621 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5622 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5623 emitpcode(POC_ANDLW, popGetLit(0x1f));
5624 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5628 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5629 emitpcode(POC_ANDLW, popGetLit(0x0f));
5630 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5634 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5635 emitpcode(POC_ANDLW, popGetLit(0x0f));
5636 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5638 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5643 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5644 emitpcode(POC_ANDLW, popGetLit(0x80));
5645 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5646 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5647 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5652 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5653 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5654 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5665 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5667 /* shift right accumulator */
5672 aopPut(AOP(result),"a",offr);
5676 /*-----------------------------------------------------------------*/
5677 /* shiftL1Left2Result - shift left one byte from left to result */
5678 /*-----------------------------------------------------------------*/
5679 static void shiftL1Left2Result (operand *left, int offl,
5680 operand *result, int offr, int shCount)
5685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5687 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5688 DEBUGpic14_emitcode ("; ***","same = %d",same);
5689 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5691 /* shift left accumulator */
5692 //AccLsh(shCount); // don't comment out just yet...
5693 // aopPut(AOP(result),"a",offr);
5697 /* Shift left 1 bit position */
5698 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5700 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5702 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5703 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5707 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5708 emitpcode(POC_ANDLW,popGetLit(0x7e));
5709 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5710 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5713 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5714 emitpcode(POC_ANDLW,popGetLit(0x3e));
5715 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5716 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5717 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5720 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5721 emitpcode(POC_ANDLW, popGetLit(0xf0));
5722 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5725 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5726 emitpcode(POC_ANDLW, popGetLit(0xf0));
5727 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5728 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5731 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5732 emitpcode(POC_ANDLW, popGetLit(0x30));
5733 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5734 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5735 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5738 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5739 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5740 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5744 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5749 /*-----------------------------------------------------------------*/
5750 /* movLeft2Result - move byte from left to result */
5751 /*-----------------------------------------------------------------*/
5752 static void movLeft2Result (operand *left, int offl,
5753 operand *result, int offr, int sign)
5756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5757 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5758 l = aopGet(AOP(left),offl,FALSE,FALSE);
5760 if (*l == '@' && (IS_AOP_PREG(result))) {
5761 pic14_emitcode("mov","a,%s",l);
5762 aopPut(AOP(result),"a",offr);
5765 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5766 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5768 //aopPut(AOP(result),l,offr);
5770 /* MSB sign in acc.7 ! */
5771 if(pic14_getDataSize(left) == offl+1){
5772 pic14_emitcode("mov","a,%s",l);
5773 aopPut(AOP(result),"a",offr);
5780 /*-----------------------------------------------------------------*/
5781 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5782 /*-----------------------------------------------------------------*/
5783 static void AccAXRrl1 (char *x)
5785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5786 pic14_emitcode("rrc","a");
5787 pic14_emitcode("xch","a,%s", x);
5788 pic14_emitcode("rrc","a");
5789 pic14_emitcode("xch","a,%s", x);
5792 /*-----------------------------------------------------------------*/
5793 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5794 /*-----------------------------------------------------------------*/
5795 static void AccAXLrl1 (char *x)
5797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5798 pic14_emitcode("xch","a,%s",x);
5799 pic14_emitcode("rlc","a");
5800 pic14_emitcode("xch","a,%s",x);
5801 pic14_emitcode("rlc","a");
5804 /*-----------------------------------------------------------------*/
5805 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5806 /*-----------------------------------------------------------------*/
5807 static void AccAXLsh1 (char *x)
5809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5810 pic14_emitcode("xch","a,%s",x);
5811 pic14_emitcode("add","a,acc");
5812 pic14_emitcode("xch","a,%s",x);
5813 pic14_emitcode("rlc","a");
5817 /*-----------------------------------------------------------------*/
5818 /* AccAXLsh - left shift a:x by known count (0..7) */
5819 /*-----------------------------------------------------------------*/
5820 static void AccAXLsh (char *x, int shCount)
5822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5835 case 5 : // AAAAABBB:CCCCCDDD
5836 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5837 pic14_emitcode("anl","a,#0x%02x",
5838 SLMask[shCount]); // BBB00000:CCCCCDDD
5839 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5840 AccRol(shCount); // DDDCCCCC:BBB00000
5841 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5842 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5843 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5844 pic14_emitcode("anl","a,#0x%02x",
5845 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5846 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5847 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5849 case 6 : // AAAAAABB:CCCCCCDD
5850 pic14_emitcode("anl","a,#0x%02x",
5851 SRMask[shCount]); // 000000BB:CCCCCCDD
5852 pic14_emitcode("mov","c,acc.0"); // c = B
5853 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5854 AccAXRrl1(x); // BCCCCCCD:D000000B
5855 AccAXRrl1(x); // BBCCCCCC:DD000000
5857 case 7 : // a:x <<= 7
5858 pic14_emitcode("anl","a,#0x%02x",
5859 SRMask[shCount]); // 0000000B:CCCCCCCD
5860 pic14_emitcode("mov","c,acc.0"); // c = B
5861 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5862 AccAXRrl1(x); // BCCCCCCC:D0000000
5870 /*-----------------------------------------------------------------*/
5871 /* AccAXRsh - right shift a:x known count (0..7) */
5872 /*-----------------------------------------------------------------*/
5873 static void AccAXRsh (char *x, int shCount)
5875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5881 AccAXRrl1(x); // 0->a:x
5885 AccAXRrl1(x); // 0->a:x
5887 AccAXRrl1(x); // 0->a:x
5891 case 5 : // AAAAABBB:CCCCCDDD = a:x
5892 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5893 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5894 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5895 pic14_emitcode("anl","a,#0x%02x",
5896 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5897 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5898 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5899 pic14_emitcode("anl","a,#0x%02x",
5900 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5901 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5902 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5903 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5905 case 6 : // AABBBBBB:CCDDDDDD
5906 pic14_emitcode("mov","c,acc.7");
5907 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5908 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5909 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5910 pic14_emitcode("anl","a,#0x%02x",
5911 SRMask[shCount]); // 000000AA:BBBBBBCC
5913 case 7 : // ABBBBBBB:CDDDDDDD
5914 pic14_emitcode("mov","c,acc.7"); // c = A
5915 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5916 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5917 pic14_emitcode("anl","a,#0x%02x",
5918 SRMask[shCount]); // 0000000A:BBBBBBBC
5925 /*-----------------------------------------------------------------*/
5926 /* AccAXRshS - right shift signed a:x known count (0..7) */
5927 /*-----------------------------------------------------------------*/
5928 static void AccAXRshS (char *x, int shCount)
5931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5936 pic14_emitcode("mov","c,acc.7");
5937 AccAXRrl1(x); // s->a:x
5940 pic14_emitcode("mov","c,acc.7");
5941 AccAXRrl1(x); // s->a:x
5942 pic14_emitcode("mov","c,acc.7");
5943 AccAXRrl1(x); // s->a:x
5947 case 5 : // AAAAABBB:CCCCCDDD = a:x
5948 tlbl = newiTempLabel(NULL);
5949 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
5950 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5951 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5952 pic14_emitcode("anl","a,#0x%02x",
5953 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5954 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5955 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5956 pic14_emitcode("anl","a,#0x%02x",
5957 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5958 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5959 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5960 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
5961 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5962 pic14_emitcode("orl","a,#0x%02x",
5963 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
5964 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5965 break; // SSSSAAAA:BBBCCCCC
5966 case 6 : // AABBBBBB:CCDDDDDD
5967 tlbl = newiTempLabel(NULL);
5968 pic14_emitcode("mov","c,acc.7");
5969 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5970 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5971 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5972 pic14_emitcode("anl","a,#0x%02x",
5973 SRMask[shCount]); // 000000AA:BBBBBBCC
5974 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5975 pic14_emitcode("orl","a,#0x%02x",
5976 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
5977 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5979 case 7 : // ABBBBBBB:CDDDDDDD
5980 tlbl = newiTempLabel(NULL);
5981 pic14_emitcode("mov","c,acc.7"); // c = A
5982 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5983 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5984 pic14_emitcode("anl","a,#0x%02x",
5985 SRMask[shCount]); // 0000000A:BBBBBBBC
5986 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5987 pic14_emitcode("orl","a,#0x%02x",
5988 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
5989 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5996 /*-----------------------------------------------------------------*/
5997 /* shiftL2Left2Result - shift left two bytes from left to result */
5998 /*-----------------------------------------------------------------*/
5999 static void shiftL2Left2Result (operand *left, int offl,
6000 operand *result, int offr, int shCount)
6004 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6006 if(pic14_sameRegs(AOP(result), AOP(left))) {
6014 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6015 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6016 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6020 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6021 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6027 emitpcode(POC_MOVLW, popGetLit(0x0f));
6028 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6029 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6030 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6031 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6032 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6033 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6035 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6036 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6040 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6041 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6042 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6043 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6044 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6045 emitpcode(POC_ANDLW,popGetLit(0xc0));
6046 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6047 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6048 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6049 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6052 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6053 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6054 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6055 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6056 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6066 /* note, use a mov/add for the shift since the mov has a
6067 chance of getting optimized out */
6068 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6069 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6070 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6071 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6072 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6076 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6077 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6083 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6084 emitpcode(POC_ANDLW, popGetLit(0xF0));
6085 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6086 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6087 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6088 emitpcode(POC_ANDLW, popGetLit(0xF0));
6089 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6090 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6094 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6095 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6099 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6100 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6101 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6102 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6104 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6105 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6106 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6107 emitpcode(POC_ANDLW,popGetLit(0xc0));
6108 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6109 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6110 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6111 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6114 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6115 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6116 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6117 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6118 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6123 /*-----------------------------------------------------------------*/
6124 /* shiftR2Left2Result - shift right two bytes from left to result */
6125 /*-----------------------------------------------------------------*/
6126 static void shiftR2Left2Result (operand *left, int offl,
6127 operand *result, int offr,
6128 int shCount, int sign)
6132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6133 same = pic14_sameRegs(AOP(result), AOP(left));
6135 if(same && ((offl + MSB16) == offr)){
6137 /* don't crash result[offr] */
6138 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6139 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6141 movLeft2Result(left,offl, result, offr, 0);
6142 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6144 /* a:x >> shCount (x = lsb(result))*/
6146 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6148 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6158 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6159 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6162 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6163 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6164 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6165 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6170 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6171 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6178 emitpcode(POC_MOVLW, popGetLit(0xf0));
6179 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6180 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6182 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6183 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6185 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6187 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6188 emitpcode(POC_ANDLW, popGetLit(0x0f));
6189 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6191 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6192 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6193 emitpcode(POC_ANDLW, popGetLit(0xf0));
6194 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6195 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6199 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6200 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6208 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6209 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6211 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6212 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6213 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6214 emitpcode(POC_ANDLW,popGetLit(0x03));
6215 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6216 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6217 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6218 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6220 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6221 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6222 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6223 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6224 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6225 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6226 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6227 emitpcode(POC_ANDLW,popGetLit(0x03));
6228 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6233 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6234 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6235 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6236 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6237 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6242 /*-----------------------------------------------------------------*/
6243 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6244 /*-----------------------------------------------------------------*/
6245 static void shiftLLeftOrResult (operand *left, int offl,
6246 operand *result, int offr, int shCount)
6248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6249 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6250 /* shift left accumulator */
6252 /* or with result */
6253 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6254 /* back to result */
6255 aopPut(AOP(result),"a",offr);
6258 /*-----------------------------------------------------------------*/
6259 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6260 /*-----------------------------------------------------------------*/
6261 static void shiftRLeftOrResult (operand *left, int offl,
6262 operand *result, int offr, int shCount)
6264 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6265 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6266 /* shift right accumulator */
6268 /* or with result */
6269 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6270 /* back to result */
6271 aopPut(AOP(result),"a",offr);
6274 /*-----------------------------------------------------------------*/
6275 /* genlshOne - left shift a one byte quantity by known count */
6276 /*-----------------------------------------------------------------*/
6277 static void genlshOne (operand *result, operand *left, int shCount)
6279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6283 /*-----------------------------------------------------------------*/
6284 /* genlshTwo - left shift two bytes by known amount != 0 */
6285 /*-----------------------------------------------------------------*/
6286 static void genlshTwo (operand *result,operand *left, int shCount)
6290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6291 size = pic14_getDataSize(result);
6293 /* if shCount >= 8 */
6299 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6301 movLeft2Result(left, LSB, result, MSB16, 0);
6303 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6306 /* 1 <= shCount <= 7 */
6309 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6311 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6315 /*-----------------------------------------------------------------*/
6316 /* shiftLLong - shift left one long from left to result */
6317 /* offl = LSB or MSB16 */
6318 /*-----------------------------------------------------------------*/
6319 static void shiftLLong (operand *left, operand *result, int offr )
6322 int size = AOP_SIZE(result);
6324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6325 if(size >= LSB+offr){
6326 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6328 pic14_emitcode("add","a,acc");
6329 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6330 size >= MSB16+offr && offr != LSB )
6331 pic14_emitcode("xch","a,%s",
6332 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6334 aopPut(AOP(result),"a",LSB+offr);
6337 if(size >= MSB16+offr){
6338 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6339 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6342 pic14_emitcode("rlc","a");
6343 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6344 size >= MSB24+offr && offr != LSB)
6345 pic14_emitcode("xch","a,%s",
6346 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6348 aopPut(AOP(result),"a",MSB16+offr);
6351 if(size >= MSB24+offr){
6352 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6353 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6356 pic14_emitcode("rlc","a");
6357 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6358 size >= MSB32+offr && offr != LSB )
6359 pic14_emitcode("xch","a,%s",
6360 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6362 aopPut(AOP(result),"a",MSB24+offr);
6365 if(size > MSB32+offr){
6366 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6367 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6370 pic14_emitcode("rlc","a");
6371 aopPut(AOP(result),"a",MSB32+offr);
6374 aopPut(AOP(result),zero,LSB);
6377 /*-----------------------------------------------------------------*/
6378 /* genlshFour - shift four byte by a known amount != 0 */
6379 /*-----------------------------------------------------------------*/
6380 static void genlshFour (operand *result, operand *left, int shCount)
6384 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6385 size = AOP_SIZE(result);
6387 /* if shifting more that 3 bytes */
6388 if (shCount >= 24 ) {
6391 /* lowest order of left goes to the highest
6392 order of the destination */
6393 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6395 movLeft2Result(left, LSB, result, MSB32, 0);
6396 aopPut(AOP(result),zero,LSB);
6397 aopPut(AOP(result),zero,MSB16);
6398 aopPut(AOP(result),zero,MSB32);
6402 /* more than two bytes */
6403 else if ( shCount >= 16 ) {
6404 /* lower order two bytes goes to higher order two bytes */
6406 /* if some more remaining */
6408 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6410 movLeft2Result(left, MSB16, result, MSB32, 0);
6411 movLeft2Result(left, LSB, result, MSB24, 0);
6413 aopPut(AOP(result),zero,MSB16);
6414 aopPut(AOP(result),zero,LSB);
6418 /* if more than 1 byte */
6419 else if ( shCount >= 8 ) {
6420 /* lower order three bytes goes to higher order three bytes */
6424 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6426 movLeft2Result(left, LSB, result, MSB16, 0);
6428 else{ /* size = 4 */
6430 movLeft2Result(left, MSB24, result, MSB32, 0);
6431 movLeft2Result(left, MSB16, result, MSB24, 0);
6432 movLeft2Result(left, LSB, result, MSB16, 0);
6433 aopPut(AOP(result),zero,LSB);
6435 else if(shCount == 1)
6436 shiftLLong(left, result, MSB16);
6438 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6439 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6440 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6441 aopPut(AOP(result),zero,LSB);
6446 /* 1 <= shCount <= 7 */
6447 else if(shCount <= 2){
6448 shiftLLong(left, result, LSB);
6450 shiftLLong(result, result, LSB);
6452 /* 3 <= shCount <= 7, optimize */
6454 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6455 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6456 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6460 /*-----------------------------------------------------------------*/
6461 /* genLeftShiftLiteral - left shifting by known count */
6462 /*-----------------------------------------------------------------*/
6463 static void genLeftShiftLiteral (operand *left,
6468 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6472 freeAsmop(right,NULL,ic,TRUE);
6474 aopOp(left,ic,FALSE);
6475 aopOp(result,ic,FALSE);
6477 size = getSize(operandType(result));
6480 pic14_emitcode("; shift left ","result %d, left %d",size,
6484 /* I suppose that the left size >= result size */
6487 movLeft2Result(left, size, result, size, 0);
6491 else if(shCount >= (size * 8))
6493 aopPut(AOP(result),zero,size);
6497 genlshOne (result,left,shCount);
6502 genlshTwo (result,left,shCount);
6506 genlshFour (result,left,shCount);
6510 freeAsmop(left,NULL,ic,TRUE);
6511 freeAsmop(result,NULL,ic,TRUE);
6514 /*-----------------------------------------------------------------*/
6515 /* genLeftShift - generates code for left shifting */
6516 /*-----------------------------------------------------------------*/
6517 static void genLeftShift (iCode *ic)
6519 operand *left,*right, *result;
6522 symbol *tlbl , *tlbl1;
6524 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6526 right = IC_RIGHT(ic);
6528 result = IC_RESULT(ic);
6530 aopOp(right,ic,FALSE);
6532 /* if the shift count is known then do it
6533 as efficiently as possible */
6534 if (AOP_TYPE(right) == AOP_LIT) {
6535 genLeftShiftLiteral (left,right,result,ic);
6539 /* shift count is unknown then we have to form
6540 a loop get the loop count in B : Note: we take
6541 only the lower order byte since shifting
6542 more that 32 bits make no sense anyway, ( the
6543 largest size of an object can be only 32 bits ) */
6546 aopOp(left,ic,FALSE);
6547 aopOp(result,ic,FALSE);
6549 /* now move the left to the result if they are not the
6551 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6552 AOP_SIZE(result) > 1) {
6554 size = AOP_SIZE(result);
6557 l = aopGet(AOP(left),offset,FALSE,TRUE);
6558 if (*l == '@' && (IS_AOP_PREG(result))) {
6560 pic14_emitcode("mov","a,%s",l);
6561 aopPut(AOP(result),"a",offset);
6563 aopPut(AOP(result),l,offset);
6568 size = AOP_SIZE(result);
6570 /* if it is only one byte then */
6572 if(optimized_for_speed) {
6573 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6574 emitpcode(POC_ANDLW, popGetLit(0xf0));
6575 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6576 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6577 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6578 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6579 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6580 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6581 emitpcode(POC_ANDLW, popGetLit(0xfe));
6582 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6583 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6584 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6587 tlbl = newiTempLabel(NULL);
6588 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6589 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6590 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6593 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6594 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6595 emitpLabel(tlbl->key);
6596 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6597 emitpcode(POC_ADDLW, popGetLit(1));
6599 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6605 tlbl = newiTempLabel(NULL);
6607 tlbl1 = newiTempLabel(NULL);
6609 reAdjustPreg(AOP(result));
6611 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6612 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6613 l = aopGet(AOP(result),offset,FALSE,FALSE);
6615 pic14_emitcode("add","a,acc");
6616 aopPut(AOP(result),"a",offset++);
6618 l = aopGet(AOP(result),offset,FALSE,FALSE);
6620 pic14_emitcode("rlc","a");
6621 aopPut(AOP(result),"a",offset++);
6623 reAdjustPreg(AOP(result));
6625 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6626 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6628 freeAsmop (right,NULL,ic,TRUE);
6629 freeAsmop(left,NULL,ic,TRUE);
6630 freeAsmop(result,NULL,ic,TRUE);
6633 /*-----------------------------------------------------------------*/
6634 /* genrshOne - right shift a one byte quantity by known count */
6635 /*-----------------------------------------------------------------*/
6636 static void genrshOne (operand *result, operand *left,
6637 int shCount, int sign)
6639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6640 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6643 /*-----------------------------------------------------------------*/
6644 /* genrshTwo - right shift two bytes by known amount != 0 */
6645 /*-----------------------------------------------------------------*/
6646 static void genrshTwo (operand *result,operand *left,
6647 int shCount, int sign)
6649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6650 /* if shCount >= 8 */
6654 shiftR1Left2Result(left, MSB16, result, LSB,
6657 movLeft2Result(left, MSB16, result, LSB, sign);
6659 addSign(result, MSB16, sign);
6661 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6665 /* 1 <= shCount <= 7 */
6667 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6670 /*-----------------------------------------------------------------*/
6671 /* shiftRLong - shift right one long from left to result */
6672 /* offl = LSB or MSB16 */
6673 /*-----------------------------------------------------------------*/
6674 static void shiftRLong (operand *left, int offl,
6675 operand *result, int sign)
6677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6679 pic14_emitcode("clr","c");
6680 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6682 pic14_emitcode("mov","c,acc.7");
6683 pic14_emitcode("rrc","a");
6684 aopPut(AOP(result),"a",MSB32-offl);
6686 /* add sign of "a" */
6687 addSign(result, MSB32, sign);
6689 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6690 pic14_emitcode("rrc","a");
6691 aopPut(AOP(result),"a",MSB24-offl);
6693 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6694 pic14_emitcode("rrc","a");
6695 aopPut(AOP(result),"a",MSB16-offl);
6698 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6699 pic14_emitcode("rrc","a");
6700 aopPut(AOP(result),"a",LSB);
6704 /*-----------------------------------------------------------------*/
6705 /* genrshFour - shift four byte by a known amount != 0 */
6706 /*-----------------------------------------------------------------*/
6707 static void genrshFour (operand *result, operand *left,
6708 int shCount, int sign)
6710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6711 /* if shifting more that 3 bytes */
6712 if(shCount >= 24 ) {
6715 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6717 movLeft2Result(left, MSB32, result, LSB, sign);
6718 addSign(result, MSB16, sign);
6720 else if(shCount >= 16){
6723 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6725 movLeft2Result(left, MSB24, result, LSB, 0);
6726 movLeft2Result(left, MSB32, result, MSB16, sign);
6728 addSign(result, MSB24, sign);
6730 else if(shCount >= 8){
6733 shiftRLong(left, MSB16, result, sign);
6734 else if(shCount == 0){
6735 movLeft2Result(left, MSB16, result, LSB, 0);
6736 movLeft2Result(left, MSB24, result, MSB16, 0);
6737 movLeft2Result(left, MSB32, result, MSB24, sign);
6738 addSign(result, MSB32, sign);
6741 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6742 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6743 /* the last shift is signed */
6744 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6745 addSign(result, MSB32, sign);
6748 else{ /* 1 <= shCount <= 7 */
6750 shiftRLong(left, LSB, result, sign);
6752 shiftRLong(result, LSB, result, sign);
6755 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6756 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6757 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6762 /*-----------------------------------------------------------------*/
6763 /* genRightShiftLiteral - right shifting by known count */
6764 /*-----------------------------------------------------------------*/
6765 static void genRightShiftLiteral (operand *left,
6771 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6775 freeAsmop(right,NULL,ic,TRUE);
6777 aopOp(left,ic,FALSE);
6778 aopOp(result,ic,FALSE);
6781 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6785 size = pic14_getDataSize(left);
6786 /* test the LEFT size !!! */
6788 /* I suppose that the left size >= result size */
6790 size = pic14_getDataSize(result);
6792 movLeft2Result(left, size, result, size, 0);
6795 else if(shCount >= (size * 8)){
6797 /* get sign in acc.7 */
6798 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6799 addSign(result, LSB, sign);
6803 genrshOne (result,left,shCount,sign);
6807 genrshTwo (result,left,shCount,sign);
6811 genrshFour (result,left,shCount,sign);
6817 freeAsmop(left,NULL,ic,TRUE);
6818 freeAsmop(result,NULL,ic,TRUE);
6822 /*-----------------------------------------------------------------*/
6823 /* genSignedRightShift - right shift of signed number */
6824 /*-----------------------------------------------------------------*/
6825 static void genSignedRightShift (iCode *ic)
6827 operand *right, *left, *result;
6830 symbol *tlbl, *tlbl1 ;
6832 /* we do it the hard way put the shift count in b
6833 and loop thru preserving the sign */
6834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6836 right = IC_RIGHT(ic);
6838 result = IC_RESULT(ic);
6840 aopOp(right,ic,FALSE);
6843 if ( AOP_TYPE(right) == AOP_LIT) {
6844 genRightShiftLiteral (left,right,result,ic,1);
6847 /* shift count is unknown then we have to form
6848 a loop get the loop count in B : Note: we take
6849 only the lower order byte since shifting
6850 more that 32 bits make no sense anyway, ( the
6851 largest size of an object can be only 32 bits ) */
6853 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6854 pic14_emitcode("inc","b");
6855 freeAsmop (right,NULL,ic,TRUE);
6856 aopOp(left,ic,FALSE);
6857 aopOp(result,ic,FALSE);
6859 /* now move the left to the result if they are not the
6861 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6862 AOP_SIZE(result) > 1) {
6864 size = AOP_SIZE(result);
6867 l = aopGet(AOP(left),offset,FALSE,TRUE);
6868 if (*l == '@' && IS_AOP_PREG(result)) {
6870 pic14_emitcode("mov","a,%s",l);
6871 aopPut(AOP(result),"a",offset);
6873 aopPut(AOP(result),l,offset);
6878 /* mov the highest order bit to OVR */
6879 tlbl = newiTempLabel(NULL);
6880 tlbl1= newiTempLabel(NULL);
6882 size = AOP_SIZE(result);
6884 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6885 pic14_emitcode("rlc","a");
6886 pic14_emitcode("mov","ov,c");
6887 /* if it is only one byte then */
6889 l = aopGet(AOP(left),0,FALSE,FALSE);
6891 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6892 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6893 pic14_emitcode("mov","c,ov");
6894 pic14_emitcode("rrc","a");
6895 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6896 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6897 aopPut(AOP(result),"a",0);
6901 reAdjustPreg(AOP(result));
6902 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6903 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6904 pic14_emitcode("mov","c,ov");
6906 l = aopGet(AOP(result),offset,FALSE,FALSE);
6908 pic14_emitcode("rrc","a");
6909 aopPut(AOP(result),"a",offset--);
6911 reAdjustPreg(AOP(result));
6912 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6913 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6916 freeAsmop(left,NULL,ic,TRUE);
6917 freeAsmop(result,NULL,ic,TRUE);
6920 /*-----------------------------------------------------------------*/
6921 /* genRightShift - generate code for right shifting */
6922 /*-----------------------------------------------------------------*/
6923 static void genRightShift (iCode *ic)
6925 operand *right, *left, *result;
6929 symbol *tlbl, *tlbl1 ;
6931 /* if signed then we do it the hard way preserve the
6932 sign bit moving it inwards */
6933 retype = getSpec(operandType(IC_RESULT(ic)));
6934 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6936 if (!SPEC_USIGN(retype)) {
6937 genSignedRightShift (ic);
6941 /* signed & unsigned types are treated the same : i.e. the
6942 signed is NOT propagated inwards : quoting from the
6943 ANSI - standard : "for E1 >> E2, is equivalent to division
6944 by 2**E2 if unsigned or if it has a non-negative value,
6945 otherwise the result is implementation defined ", MY definition
6946 is that the sign does not get propagated */
6948 right = IC_RIGHT(ic);
6950 result = IC_RESULT(ic);
6952 aopOp(right,ic,FALSE);
6954 /* if the shift count is known then do it
6955 as efficiently as possible */
6956 if (AOP_TYPE(right) == AOP_LIT) {
6957 genRightShiftLiteral (left,right,result,ic, 0);
6961 /* shift count is unknown then we have to form
6962 a loop get the loop count in B : Note: we take
6963 only the lower order byte since shifting
6964 more that 32 bits make no sense anyway, ( the
6965 largest size of an object can be only 32 bits ) */
6967 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6968 pic14_emitcode("inc","b");
6969 aopOp(left,ic,FALSE);
6970 aopOp(result,ic,FALSE);
6972 /* now move the left to the result if they are not the
6974 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6975 AOP_SIZE(result) > 1) {
6977 size = AOP_SIZE(result);
6980 l = aopGet(AOP(left),offset,FALSE,TRUE);
6981 if (*l == '@' && IS_AOP_PREG(result)) {
6983 pic14_emitcode("mov","a,%s",l);
6984 aopPut(AOP(result),"a",offset);
6986 aopPut(AOP(result),l,offset);
6991 tlbl = newiTempLabel(NULL);
6992 tlbl1= newiTempLabel(NULL);
6993 size = AOP_SIZE(result);
6996 /* if it is only one byte then */
6999 l = aopGet(AOP(left),0,FALSE,FALSE);
7001 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7002 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7004 pic14_emitcode("rrc","a");
7005 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7006 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7007 aopPut(AOP(result),"a",0);
7009 tlbl = newiTempLabel(NULL);
7010 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7011 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
7012 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
7015 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
7016 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
7017 emitpLabel(tlbl->key);
7018 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
7019 emitpcode(POC_ADDLW, popGetLit(1));
7021 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7026 reAdjustPreg(AOP(result));
7027 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7028 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7031 l = aopGet(AOP(result),offset,FALSE,FALSE);
7033 pic14_emitcode("rrc","a");
7034 aopPut(AOP(result),"a",offset--);
7036 reAdjustPreg(AOP(result));
7038 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7039 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7042 freeAsmop(left,NULL,ic,TRUE);
7043 freeAsmop (right,NULL,ic,TRUE);
7044 freeAsmop(result,NULL,ic,TRUE);
7047 /*-----------------------------------------------------------------*/
7048 /* genUnpackBits - generates code for unpacking bits */
7049 /*-----------------------------------------------------------------*/
7050 static void genUnpackBits (operand *result, char *rname, int ptype)
7057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7058 etype = getSpec(operandType(result));
7060 /* read the first byte */
7065 pic14_emitcode("mov","a,@%s",rname);
7069 pic14_emitcode("movx","a,@%s",rname);
7073 pic14_emitcode("movx","a,@dptr");
7077 pic14_emitcode("clr","a");
7078 pic14_emitcode("movc","a","@a+dptr");
7082 pic14_emitcode("lcall","__gptrget");
7086 /* if we have bitdisplacement then it fits */
7087 /* into this byte completely or if length is */
7088 /* less than a byte */
7089 if ((shCnt = SPEC_BSTR(etype)) ||
7090 (SPEC_BLEN(etype) <= 8)) {
7092 /* shift right acc */
7095 pic14_emitcode("anl","a,#0x%02x",
7096 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7097 aopPut(AOP(result),"a",offset);
7101 /* bit field did not fit in a byte */
7102 rlen = SPEC_BLEN(etype) - 8;
7103 aopPut(AOP(result),"a",offset++);
7110 pic14_emitcode("inc","%s",rname);
7111 pic14_emitcode("mov","a,@%s",rname);
7115 pic14_emitcode("inc","%s",rname);
7116 pic14_emitcode("movx","a,@%s",rname);
7120 pic14_emitcode("inc","dptr");
7121 pic14_emitcode("movx","a,@dptr");
7125 pic14_emitcode("clr","a");
7126 pic14_emitcode("inc","dptr");
7127 pic14_emitcode("movc","a","@a+dptr");
7131 pic14_emitcode("inc","dptr");
7132 pic14_emitcode("lcall","__gptrget");
7137 /* if we are done */
7141 aopPut(AOP(result),"a",offset++);
7146 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7147 aopPut(AOP(result),"a",offset);
7154 /*-----------------------------------------------------------------*/
7155 /* genDataPointerGet - generates code when ptr offset is known */
7156 /*-----------------------------------------------------------------*/
7157 static void genDataPointerGet (operand *left,
7161 int size , offset = 0;
7164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7167 /* optimization - most of the time, left and result are the same
7168 * address, but different types. for the pic code, we could omit
7172 aopOp(result,ic,TRUE);
7174 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7176 size = AOP_SIZE(result);
7179 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7183 freeAsmop(left,NULL,ic,TRUE);
7184 freeAsmop(result,NULL,ic,TRUE);
7187 /*-----------------------------------------------------------------*/
7188 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7189 /*-----------------------------------------------------------------*/
7190 static void genNearPointerGet (operand *left,
7197 sym_link *rtype, *retype;
7198 sym_link *ltype = operandType(left);
7201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7203 rtype = operandType(result);
7204 retype= getSpec(rtype);
7206 aopOp(left,ic,FALSE);
7208 /* if left is rematerialisable and
7209 result is not bit variable type and
7210 the left is pointer to data space i.e
7211 lower 128 bytes of space */
7212 if (AOP_TYPE(left) == AOP_IMMD &&
7213 !IS_BITVAR(retype) &&
7214 DCL_TYPE(ltype) == POINTER) {
7215 genDataPointerGet (left,result,ic);
7219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7221 /* if the value is already in a pointer register
7222 then don't need anything more */
7223 if (!AOP_INPREG(AOP(left))) {
7224 /* otherwise get a free pointer register */
7225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7227 preg = getFreePtr(ic,&aop,FALSE);
7228 pic14_emitcode("mov","%s,%s",
7230 aopGet(AOP(left),0,FALSE,TRUE));
7231 rname = preg->name ;
7233 rname = aopGet(AOP(left),0,FALSE,FALSE);
7235 freeAsmop(left,NULL,ic,TRUE);
7236 aopOp (result,ic,FALSE);
7238 /* if bitfield then unpack the bits */
7239 if (IS_BITVAR(retype))
7240 genUnpackBits (result,rname,POINTER);
7242 /* we have can just get the values */
7243 int size = AOP_SIZE(result);
7246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7248 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7250 pic14_emitcode("mov","a,@%s",rname);
7251 aopPut(AOP(result),"a",offset);
7253 sprintf(buffer,"@%s",rname);
7254 aopPut(AOP(result),buffer,offset);
7258 pic14_emitcode("inc","%s",rname);
7262 /* now some housekeeping stuff */
7264 /* we had to allocate for this iCode */
7265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7266 freeAsmop(NULL,aop,ic,TRUE);
7268 /* we did not allocate which means left
7269 already in a pointer register, then
7270 if size > 0 && this could be used again
7271 we have to point it back to where it
7273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7274 if (AOP_SIZE(result) > 1 &&
7275 !OP_SYMBOL(left)->remat &&
7276 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7278 int size = AOP_SIZE(result) - 1;
7280 pic14_emitcode("dec","%s",rname);
7285 freeAsmop(result,NULL,ic,TRUE);
7289 /*-----------------------------------------------------------------*/
7290 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7291 /*-----------------------------------------------------------------*/
7292 static void genPagedPointerGet (operand *left,
7299 sym_link *rtype, *retype;
7301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7303 rtype = operandType(result);
7304 retype= getSpec(rtype);
7306 aopOp(left,ic,FALSE);
7308 /* if the value is already in a pointer register
7309 then don't need anything more */
7310 if (!AOP_INPREG(AOP(left))) {
7311 /* otherwise get a free pointer register */
7313 preg = getFreePtr(ic,&aop,FALSE);
7314 pic14_emitcode("mov","%s,%s",
7316 aopGet(AOP(left),0,FALSE,TRUE));
7317 rname = preg->name ;
7319 rname = aopGet(AOP(left),0,FALSE,FALSE);
7321 freeAsmop(left,NULL,ic,TRUE);
7322 aopOp (result,ic,FALSE);
7324 /* if bitfield then unpack the bits */
7325 if (IS_BITVAR(retype))
7326 genUnpackBits (result,rname,PPOINTER);
7328 /* we have can just get the values */
7329 int size = AOP_SIZE(result);
7334 pic14_emitcode("movx","a,@%s",rname);
7335 aopPut(AOP(result),"a",offset);
7340 pic14_emitcode("inc","%s",rname);
7344 /* now some housekeeping stuff */
7346 /* we had to allocate for this iCode */
7347 freeAsmop(NULL,aop,ic,TRUE);
7349 /* we did not allocate which means left
7350 already in a pointer register, then
7351 if size > 0 && this could be used again
7352 we have to point it back to where it
7354 if (AOP_SIZE(result) > 1 &&
7355 !OP_SYMBOL(left)->remat &&
7356 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7358 int size = AOP_SIZE(result) - 1;
7360 pic14_emitcode("dec","%s",rname);
7365 freeAsmop(result,NULL,ic,TRUE);
7370 /*-----------------------------------------------------------------*/
7371 /* genFarPointerGet - gget value from far space */
7372 /*-----------------------------------------------------------------*/
7373 static void genFarPointerGet (operand *left,
7374 operand *result, iCode *ic)
7377 sym_link *retype = getSpec(operandType(result));
7379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7381 aopOp(left,ic,FALSE);
7383 /* if the operand is already in dptr
7384 then we do nothing else we move the value to dptr */
7385 if (AOP_TYPE(left) != AOP_STR) {
7386 /* if this is remateriazable */
7387 if (AOP_TYPE(left) == AOP_IMMD)
7388 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7389 else { /* we need to get it byte by byte */
7390 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7391 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7392 if (options.model == MODEL_FLAT24)
7394 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7398 /* so dptr know contains the address */
7399 freeAsmop(left,NULL,ic,TRUE);
7400 aopOp(result,ic,FALSE);
7402 /* if bit then unpack */
7403 if (IS_BITVAR(retype))
7404 genUnpackBits(result,"dptr",FPOINTER);
7406 size = AOP_SIZE(result);
7410 pic14_emitcode("movx","a,@dptr");
7411 aopPut(AOP(result),"a",offset++);
7413 pic14_emitcode("inc","dptr");
7417 freeAsmop(result,NULL,ic,TRUE);
7420 /*-----------------------------------------------------------------*/
7421 /* pic14_emitcodePointerGet - gget value from code space */
7422 /*-----------------------------------------------------------------*/
7423 static void pic14_emitcodePointerGet (operand *left,
7424 operand *result, iCode *ic)
7427 sym_link *retype = getSpec(operandType(result));
7429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7431 aopOp(left,ic,FALSE);
7433 /* if the operand is already in dptr
7434 then we do nothing else we move the value to dptr */
7435 if (AOP_TYPE(left) != AOP_STR) {
7436 /* if this is remateriazable */
7437 if (AOP_TYPE(left) == AOP_IMMD)
7438 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7439 else { /* we need to get it byte by byte */
7440 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7441 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7442 if (options.model == MODEL_FLAT24)
7444 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7448 /* so dptr know contains the address */
7449 freeAsmop(left,NULL,ic,TRUE);
7450 aopOp(result,ic,FALSE);
7452 /* if bit then unpack */
7453 if (IS_BITVAR(retype))
7454 genUnpackBits(result,"dptr",CPOINTER);
7456 size = AOP_SIZE(result);
7460 pic14_emitcode("clr","a");
7461 pic14_emitcode("movc","a,@a+dptr");
7462 aopPut(AOP(result),"a",offset++);
7464 pic14_emitcode("inc","dptr");
7468 freeAsmop(result,NULL,ic,TRUE);
7471 /*-----------------------------------------------------------------*/
7472 /* genGenPointerGet - gget value from generic pointer space */
7473 /*-----------------------------------------------------------------*/
7474 static void genGenPointerGet (operand *left,
7475 operand *result, iCode *ic)
7478 sym_link *retype = getSpec(operandType(result));
7480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7481 aopOp(left,ic,FALSE);
7482 aopOp(result,ic,FALSE);
7485 DEBUGpic14_emitcode ("; ","result %s, left %s",
7486 AopType(AOP_TYPE(result)),
7487 AopType(AOP_TYPE(left)));
7489 /* if the operand is already in dptr
7490 then we do nothing else we move the value to dptr */
7491 if (AOP_TYPE(left) != AOP_STR) {
7492 /* if this is remateriazable */
7493 if (AOP_TYPE(left) == AOP_IMMD) {
7494 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7495 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7497 else { /* we need to get it byte by byte */
7499 size = AOP_SIZE(result);
7503 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7504 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7506 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7511 /* so dptr know contains the address */
7513 /* if bit then unpack */
7514 if (IS_BITVAR(retype))
7515 genUnpackBits(result,"dptr",GPOINTER);
7518 freeAsmop(left,NULL,ic,TRUE);
7519 freeAsmop(result,NULL,ic,TRUE);
7523 /*-----------------------------------------------------------------*/
7524 /* genPointerGet - generate code for pointer get */
7525 /*-----------------------------------------------------------------*/
7526 static void genPointerGet (iCode *ic)
7528 operand *left, *result ;
7529 sym_link *type, *etype;
7532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7535 result = IC_RESULT(ic) ;
7537 /* depending on the type of pointer we need to
7538 move it to the correct pointer register */
7539 type = operandType(left);
7540 etype = getSpec(type);
7541 /* if left is of type of pointer then it is simple */
7542 if (IS_PTR(type) && !IS_FUNC(type->next))
7543 p_type = DCL_TYPE(type);
7545 /* we have to go by the storage class */
7546 p_type = PTR_TYPE(SPEC_OCLS(etype));
7548 /* if (SPEC_OCLS(etype)->codesp ) { */
7549 /* p_type = CPOINTER ; */
7552 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7553 /* p_type = FPOINTER ; */
7555 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7556 /* p_type = PPOINTER; */
7558 /* if (SPEC_OCLS(etype) == idata ) */
7559 /* p_type = IPOINTER; */
7561 /* p_type = POINTER ; */
7564 /* now that we have the pointer type we assign
7565 the pointer values */
7570 genNearPointerGet (left,result,ic);
7574 genPagedPointerGet(left,result,ic);
7578 genFarPointerGet (left,result,ic);
7582 pic14_emitcodePointerGet (left,result,ic);
7586 genGenPointerGet (left,result,ic);
7592 /*-----------------------------------------------------------------*/
7593 /* genPackBits - generates code for packed bit storage */
7594 /*-----------------------------------------------------------------*/
7595 static void genPackBits (sym_link *etype ,
7597 char *rname, int p_type)
7605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7606 blen = SPEC_BLEN(etype);
7607 bstr = SPEC_BSTR(etype);
7609 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7612 /* if the bit lenth is less than or */
7613 /* it exactly fits a byte then */
7614 if (SPEC_BLEN(etype) <= 8 ) {
7615 shCount = SPEC_BSTR(etype) ;
7617 /* shift left acc */
7620 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7625 pic14_emitcode ("mov","b,a");
7626 pic14_emitcode("mov","a,@%s",rname);
7630 pic14_emitcode ("mov","b,a");
7631 pic14_emitcode("movx","a,@dptr");
7635 pic14_emitcode ("push","b");
7636 pic14_emitcode ("push","acc");
7637 pic14_emitcode ("lcall","__gptrget");
7638 pic14_emitcode ("pop","b");
7642 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7643 ((unsigned char)(0xFF << (blen+bstr)) |
7644 (unsigned char)(0xFF >> (8-bstr)) ) );
7645 pic14_emitcode ("orl","a,b");
7646 if (p_type == GPOINTER)
7647 pic14_emitcode("pop","b");
7653 pic14_emitcode("mov","@%s,a",rname);
7657 pic14_emitcode("movx","@dptr,a");
7661 DEBUGpic14_emitcode(";lcall","__gptrput");
7666 if ( SPEC_BLEN(etype) <= 8 )
7669 pic14_emitcode("inc","%s",rname);
7670 rLen = SPEC_BLEN(etype) ;
7672 /* now generate for lengths greater than one byte */
7675 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7685 pic14_emitcode("mov","@%s,a",rname);
7687 pic14_emitcode("mov","@%s,%s",rname,l);
7692 pic14_emitcode("movx","@dptr,a");
7697 DEBUGpic14_emitcode(";lcall","__gptrput");
7700 pic14_emitcode ("inc","%s",rname);
7705 /* last last was not complete */
7707 /* save the byte & read byte */
7710 pic14_emitcode ("mov","b,a");
7711 pic14_emitcode("mov","a,@%s",rname);
7715 pic14_emitcode ("mov","b,a");
7716 pic14_emitcode("movx","a,@dptr");
7720 pic14_emitcode ("push","b");
7721 pic14_emitcode ("push","acc");
7722 pic14_emitcode ("lcall","__gptrget");
7723 pic14_emitcode ("pop","b");
7727 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7728 pic14_emitcode ("orl","a,b");
7731 if (p_type == GPOINTER)
7732 pic14_emitcode("pop","b");
7737 pic14_emitcode("mov","@%s,a",rname);
7741 pic14_emitcode("movx","@dptr,a");
7745 DEBUGpic14_emitcode(";lcall","__gptrput");
7749 /*-----------------------------------------------------------------*/
7750 /* genDataPointerSet - remat pointer to data space */
7751 /*-----------------------------------------------------------------*/
7752 static void genDataPointerSet(operand *right,
7756 int size, offset = 0 ;
7757 char *l, buffer[256];
7759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7760 aopOp(right,ic,FALSE);
7762 l = aopGet(AOP(result),0,FALSE,TRUE);
7763 size = AOP_SIZE(right);
7764 // tsd, was l+1 - the underline `_' prefix was being stripped
7767 sprintf(buffer,"(%s + %d)",l,offset);
7769 sprintf(buffer,"%s",l);
7771 if (AOP_TYPE(right) == AOP_LIT) {
7772 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7773 lit = lit >> (8*offset);
7775 pic14_emitcode("movlw","%d",lit);
7776 pic14_emitcode("movwf","%s",buffer);
7778 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7779 emitpcode(POC_MOVWF, popRegFromString(buffer));
7782 pic14_emitcode("clrf","%s",buffer);
7783 emitpcode(POC_CLRF, popRegFromString(buffer));
7786 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7787 pic14_emitcode("movwf","%s",buffer);
7789 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7790 emitpcode(POC_MOVWF, popRegFromString(buffer));
7797 freeAsmop(right,NULL,ic,TRUE);
7798 freeAsmop(result,NULL,ic,TRUE);
7801 /*-----------------------------------------------------------------*/
7802 /* genNearPointerSet - pic14_emitcode for near pointer put */
7803 /*-----------------------------------------------------------------*/
7804 static void genNearPointerSet (operand *right,
7811 sym_link *ptype = operandType(result);
7814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7815 retype= getSpec(operandType(right));
7817 aopOp(result,ic,FALSE);
7819 /* if the result is rematerializable &
7820 in data space & not a bit variable */
7821 if (AOP_TYPE(result) == AOP_IMMD &&
7822 DCL_TYPE(ptype) == POINTER &&
7823 !IS_BITVAR(retype)) {
7824 genDataPointerSet (right,result,ic);
7828 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7830 /* if the value is already in a pointer register
7831 then don't need anything more */
7832 if (!AOP_INPREG(AOP(result))) {
7833 /* otherwise get a free pointer register */
7834 //aop = newAsmop(0);
7835 //preg = getFreePtr(ic,&aop,FALSE);
7836 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7837 //pic14_emitcode("mov","%s,%s",
7839 // aopGet(AOP(result),0,FALSE,TRUE));
7840 //rname = preg->name ;
7841 pic14_emitcode("movwf","fsr");
7843 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7845 freeAsmop(result,NULL,ic,TRUE);
7846 aopOp (right,ic,FALSE);
7847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7849 /* if bitfield then unpack the bits */
7850 if (IS_BITVAR(retype)) {
7851 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7852 "The programmer is obviously confused");
7853 //genPackBits (retype,right,rname,POINTER);
7857 /* we have can just get the values */
7858 int size = AOP_SIZE(right);
7861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7863 l = aopGet(AOP(right),offset,FALSE,TRUE);
7866 //pic14_emitcode("mov","@%s,a",rname);
7867 pic14_emitcode("movf","indf,w ;1");
7870 if (AOP_TYPE(right) == AOP_LIT) {
7871 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7873 pic14_emitcode("movlw","%s",l);
7874 pic14_emitcode("movwf","indf ;2");
7876 pic14_emitcode("clrf","indf");
7878 pic14_emitcode("movf","%s,w",l);
7879 pic14_emitcode("movwf","indf ;2");
7881 //pic14_emitcode("mov","@%s,%s",rname,l);
7884 pic14_emitcode("incf","fsr,f ;3");
7885 //pic14_emitcode("inc","%s",rname);
7890 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7891 /* now some housekeeping stuff */
7893 /* we had to allocate for this iCode */
7894 freeAsmop(NULL,aop,ic,TRUE);
7896 /* we did not allocate which means left
7897 already in a pointer register, then
7898 if size > 0 && this could be used again
7899 we have to point it back to where it
7901 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7902 if (AOP_SIZE(right) > 1 &&
7903 !OP_SYMBOL(result)->remat &&
7904 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7906 int size = AOP_SIZE(right) - 1;
7908 pic14_emitcode("decf","fsr,f");
7909 //pic14_emitcode("dec","%s",rname);
7913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7915 freeAsmop(right,NULL,ic,TRUE);
7920 /*-----------------------------------------------------------------*/
7921 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7922 /*-----------------------------------------------------------------*/
7923 static void genPagedPointerSet (operand *right,
7932 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7934 retype= getSpec(operandType(right));
7936 aopOp(result,ic,FALSE);
7938 /* if the value is already in a pointer register
7939 then don't need anything more */
7940 if (!AOP_INPREG(AOP(result))) {
7941 /* otherwise get a free pointer register */
7943 preg = getFreePtr(ic,&aop,FALSE);
7944 pic14_emitcode("mov","%s,%s",
7946 aopGet(AOP(result),0,FALSE,TRUE));
7947 rname = preg->name ;
7949 rname = aopGet(AOP(result),0,FALSE,FALSE);
7951 freeAsmop(result,NULL,ic,TRUE);
7952 aopOp (right,ic,FALSE);
7954 /* if bitfield then unpack the bits */
7955 if (IS_BITVAR(retype))
7956 genPackBits (retype,right,rname,PPOINTER);
7958 /* we have can just get the values */
7959 int size = AOP_SIZE(right);
7963 l = aopGet(AOP(right),offset,FALSE,TRUE);
7966 pic14_emitcode("movx","@%s,a",rname);
7969 pic14_emitcode("inc","%s",rname);
7975 /* now some housekeeping stuff */
7977 /* we had to allocate for this iCode */
7978 freeAsmop(NULL,aop,ic,TRUE);
7980 /* we did not allocate which means left
7981 already in a pointer register, then
7982 if size > 0 && this could be used again
7983 we have to point it back to where it
7985 if (AOP_SIZE(right) > 1 &&
7986 !OP_SYMBOL(result)->remat &&
7987 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7989 int size = AOP_SIZE(right) - 1;
7991 pic14_emitcode("dec","%s",rname);
7996 freeAsmop(right,NULL,ic,TRUE);
8001 /*-----------------------------------------------------------------*/
8002 /* genFarPointerSet - set value from far space */
8003 /*-----------------------------------------------------------------*/
8004 static void genFarPointerSet (operand *right,
8005 operand *result, iCode *ic)
8008 sym_link *retype = getSpec(operandType(right));
8010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8011 aopOp(result,ic,FALSE);
8013 /* if the operand is already in dptr
8014 then we do nothing else we move the value to dptr */
8015 if (AOP_TYPE(result) != AOP_STR) {
8016 /* if this is remateriazable */
8017 if (AOP_TYPE(result) == AOP_IMMD)
8018 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8019 else { /* we need to get it byte by byte */
8020 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8021 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8022 if (options.model == MODEL_FLAT24)
8024 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8028 /* so dptr know contains the address */
8029 freeAsmop(result,NULL,ic,TRUE);
8030 aopOp(right,ic,FALSE);
8032 /* if bit then unpack */
8033 if (IS_BITVAR(retype))
8034 genPackBits(retype,right,"dptr",FPOINTER);
8036 size = AOP_SIZE(right);
8040 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8042 pic14_emitcode("movx","@dptr,a");
8044 pic14_emitcode("inc","dptr");
8048 freeAsmop(right,NULL,ic,TRUE);
8051 /*-----------------------------------------------------------------*/
8052 /* genGenPointerSet - set value from generic pointer space */
8053 /*-----------------------------------------------------------------*/
8054 static void genGenPointerSet (operand *right,
8055 operand *result, iCode *ic)
8058 sym_link *retype = getSpec(operandType(right));
8060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8062 aopOp(result,ic,FALSE);
8063 aopOp(right,ic,FALSE);
8064 size = AOP_SIZE(right);
8066 DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8067 AopType(AOP_TYPE(result)),
8068 aopGet(AOP(result),0,TRUE,FALSE),
8069 AopType(AOP_TYPE(right)),
8070 aopGet(AOP(right),0,FALSE,FALSE),
8073 /* if the operand is already in dptr
8074 then we do nothing else we move the value to dptr */
8075 if (AOP_TYPE(result) != AOP_STR) {
8076 /* if this is remateriazable */
8077 if (AOP_TYPE(result) == AOP_IMMD) {
8078 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8079 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8081 else { /* we need to get it byte by byte */
8082 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8083 size = AOP_SIZE(right);
8086 /* hack hack! see if this the FSR. If so don't load W */
8087 if(AOP_TYPE(right) != AOP_ACC) {
8090 emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8093 emitpcode(POC_MOVLW,popGetLit(0xfd));
8094 emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8098 emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8099 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8102 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8109 if(aopIdx(AOP(result),0) != 4) {
8111 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8115 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8120 /* so dptr know contains the address */
8123 /* if bit then unpack */
8124 if (IS_BITVAR(retype))
8125 genPackBits(retype,right,"dptr",GPOINTER);
8127 size = AOP_SIZE(right);
8131 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8133 pic14_emitcode("incf","fsr,f");
8134 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8135 pic14_emitcode("movwf","indf");
8137 //DEBUGpic14_emitcode(";lcall","__gptrput");
8139 // pic14_emitcode("inc","dptr");
8144 freeAsmop(right,NULL,ic,TRUE);
8145 freeAsmop(result,NULL,ic,TRUE);
8148 /*-----------------------------------------------------------------*/
8149 /* genPointerSet - stores the value into a pointer location */
8150 /*-----------------------------------------------------------------*/
8151 static void genPointerSet (iCode *ic)
8153 operand *right, *result ;
8154 sym_link *type, *etype;
8157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 right = IC_RIGHT(ic);
8160 result = IC_RESULT(ic) ;
8162 /* depending on the type of pointer we need to
8163 move it to the correct pointer register */
8164 type = operandType(result);
8165 etype = getSpec(type);
8166 /* if left is of type of pointer then it is simple */
8167 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8168 p_type = DCL_TYPE(type);
8171 /* we have to go by the storage class */
8172 p_type = PTR_TYPE(SPEC_OCLS(etype));
8174 /* if (SPEC_OCLS(etype)->codesp ) { */
8175 /* p_type = CPOINTER ; */
8178 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8179 /* p_type = FPOINTER ; */
8181 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8182 /* p_type = PPOINTER ; */
8184 /* if (SPEC_OCLS(etype) == idata ) */
8185 /* p_type = IPOINTER ; */
8187 /* p_type = POINTER ; */
8190 /* now that we have the pointer type we assign
8191 the pointer values */
8196 genNearPointerSet (right,result,ic);
8200 genPagedPointerSet (right,result,ic);
8204 genFarPointerSet (right,result,ic);
8208 genGenPointerSet (right,result,ic);
8214 /*-----------------------------------------------------------------*/
8215 /* genIfx - generate code for Ifx statement */
8216 /*-----------------------------------------------------------------*/
8217 static void genIfx (iCode *ic, iCode *popIc)
8219 operand *cond = IC_COND(ic);
8222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8224 aopOp(cond,ic,FALSE);
8226 /* get the value into acc */
8227 if (AOP_TYPE(cond) != AOP_CRY)
8228 pic14_toBoolean(cond);
8231 /* the result is now in the accumulator */
8232 freeAsmop(cond,NULL,ic,TRUE);
8234 /* if there was something to be popped then do it */
8238 /* if the condition is a bit variable */
8239 if (isbit && IS_ITEMP(cond) &&
8241 genIfxJump(ic,SPIL_LOC(cond)->rname);
8242 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8245 if (isbit && !IS_ITEMP(cond))
8246 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8254 /*-----------------------------------------------------------------*/
8255 /* genAddrOf - generates code for address of */
8256 /*-----------------------------------------------------------------*/
8257 static void genAddrOf (iCode *ic)
8259 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8260 operand *right, *result, *left;
8261 //int size, offset ;
8263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8266 //aopOp(IC_RESULT(ic),ic,FALSE);
8268 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8269 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8270 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8273 DEBUGpic14_emitcode ("; ","result %s",
8274 AopType(AOP_TYPE(IC_RESULT(ic))));
8277 DEBUGpic14_emitcode ("; ","left %s",
8278 AopType(AOP_TYPE(IC_LEFT(ic))));
8280 DEBUGpic14_emitcode ("; ","right %s",
8281 AopType(AOP_TYPE(IC_RIGHT(ic))));
8283 emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8284 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8287 /* object not on stack then we need the name */
8288 size = AOP_SIZE(IC_RESULT(ic));
8292 char s[SDCC_NAME_MAX];
8294 sprintf(s,"#(%s >> %d)",
8298 sprintf(s,"#%s",sym->rname);
8299 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8304 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8305 freeAsmop(left,NULL,ic,FALSE);
8306 freeAsmop(result,NULL,ic,TRUE);
8311 /*-----------------------------------------------------------------*/
8312 /* genFarFarAssign - assignment when both are in far space */
8313 /*-----------------------------------------------------------------*/
8314 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8316 int size = AOP_SIZE(right);
8319 /* first push the right side on to the stack */
8321 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8323 pic14_emitcode ("push","acc");
8326 freeAsmop(right,NULL,ic,FALSE);
8327 /* now assign DPTR to result */
8328 aopOp(result,ic,FALSE);
8329 size = AOP_SIZE(result);
8331 pic14_emitcode ("pop","acc");
8332 aopPut(AOP(result),"a",--offset);
8334 freeAsmop(result,NULL,ic,FALSE);
8339 /*-----------------------------------------------------------------*/
8340 /* genAssign - generate code for assignment */
8341 /*-----------------------------------------------------------------*/
8342 static void genAssign (iCode *ic)
8344 operand *result, *right;
8345 int size, offset,know_W;
8346 unsigned long lit = 0L;
8348 result = IC_RESULT(ic);
8349 right = IC_RIGHT(ic) ;
8351 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8353 /* if they are the same */
8354 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8357 aopOp(right,ic,FALSE);
8358 aopOp(result,ic,TRUE);
8360 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8361 AopType(AOP_TYPE(IC_RESULT(ic))),
8362 AopType(AOP_TYPE(IC_RIGHT(ic))),
8365 /* if they are the same registers */
8366 if (pic14_sameRegs(AOP(right),AOP(result)))
8369 /* if the result is a bit */
8370 if (AOP_TYPE(result) == AOP_CRY) {
8372 /* if the right size is a literal then
8373 we know what the value is */
8374 if (AOP_TYPE(right) == AOP_LIT) {
8376 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8377 popGet(AOP(result),0,FALSE,FALSE));
8379 if (((int) operandLitValue(right)))
8380 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8381 AOP(result)->aopu.aop_dir,
8382 AOP(result)->aopu.aop_dir);
8384 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8385 AOP(result)->aopu.aop_dir,
8386 AOP(result)->aopu.aop_dir);
8390 /* the right is also a bit variable */
8391 if (AOP_TYPE(right) == AOP_CRY) {
8392 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8393 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8394 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8396 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8397 AOP(result)->aopu.aop_dir,
8398 AOP(result)->aopu.aop_dir);
8399 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8400 AOP(right)->aopu.aop_dir,
8401 AOP(right)->aopu.aop_dir);
8402 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8403 AOP(result)->aopu.aop_dir,
8404 AOP(result)->aopu.aop_dir);
8409 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8410 pic14_toBoolean(right);
8412 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8413 //aopPut(AOP(result),"a",0);
8417 /* bit variables done */
8419 size = AOP_SIZE(result);
8421 if(AOP_TYPE(right) == AOP_LIT)
8422 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8424 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8425 if(aopIdx(AOP(result),0) == 4) {
8426 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8427 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8430 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8435 if(AOP_TYPE(right) == AOP_LIT) {
8437 if(know_W != (lit&0xff))
8438 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8440 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8442 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8446 } else if (AOP_TYPE(right) == AOP_CRY) {
8447 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8449 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8450 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8453 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8454 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8462 freeAsmop (right,NULL,ic,FALSE);
8463 freeAsmop (result,NULL,ic,TRUE);
8466 /*-----------------------------------------------------------------*/
8467 /* genJumpTab - genrates code for jump table */
8468 /*-----------------------------------------------------------------*/
8469 static void genJumpTab (iCode *ic)
8474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8476 aopOp(IC_JTCOND(ic),ic,FALSE);
8477 /* get the condition into accumulator */
8478 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8480 /* multiply by three */
8481 pic14_emitcode("add","a,acc");
8482 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8484 jtab = newiTempLabel(NULL);
8485 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8486 pic14_emitcode("jmp","@a+dptr");
8487 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8489 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8490 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8492 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8493 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8494 emitpLabel(jtab->key);
8496 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8498 /* now generate the jump labels */
8499 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8500 jtab = setNextItem(IC_JTLABELS(ic))) {
8501 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8502 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8508 /*-----------------------------------------------------------------*/
8509 /* genMixedOperation - gen code for operators between mixed types */
8510 /*-----------------------------------------------------------------*/
8512 TSD - Written for the PIC port - but this unfortunately is buggy.
8513 This routine is good in that it is able to efficiently promote
8514 types to different (larger) sizes. Unfortunately, the temporary
8515 variables that are optimized out by this routine are sometimes
8516 used in other places. So until I know how to really parse the
8517 iCode tree, I'm going to not be using this routine :(.
8519 static int genMixedOperation (iCode *ic)
8522 operand *result = IC_RESULT(ic);
8523 sym_link *ctype = operandType(IC_LEFT(ic));
8524 operand *right = IC_RIGHT(ic);
8530 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8532 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8538 nextright = IC_RIGHT(nextic);
8539 nextleft = IC_LEFT(nextic);
8540 nextresult = IC_RESULT(nextic);
8542 aopOp(right,ic,FALSE);
8543 aopOp(result,ic,FALSE);
8544 aopOp(nextright, nextic, FALSE);
8545 aopOp(nextleft, nextic, FALSE);
8546 aopOp(nextresult, nextic, FALSE);
8548 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8554 pic14_emitcode(";remove right +","");
8556 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8562 pic14_emitcode(";remove left +","");
8566 big = AOP_SIZE(nextleft);
8567 small = AOP_SIZE(nextright);
8569 switch(nextic->op) {
8572 pic14_emitcode(";optimize a +","");
8573 /* if unsigned or not an integral type */
8574 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8575 pic14_emitcode(";add a bit to something","");
8578 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8580 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8581 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8582 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8584 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8592 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8593 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8594 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8597 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8599 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8600 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8601 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8602 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8603 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8606 pic14_emitcode("rlf","known_zero,w");
8613 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8614 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8615 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8617 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8627 freeAsmop(right,NULL,ic,TRUE);
8628 freeAsmop(result,NULL,ic,TRUE);
8629 freeAsmop(nextright,NULL,ic,TRUE);
8630 freeAsmop(nextleft,NULL,ic,TRUE);
8632 nextic->generated = 1;
8639 /*-----------------------------------------------------------------*/
8640 /* genCast - gen code for casting */
8641 /*-----------------------------------------------------------------*/
8642 static void genCast (iCode *ic)
8644 operand *result = IC_RESULT(ic);
8645 sym_link *ctype = operandType(IC_LEFT(ic));
8646 operand *right = IC_RIGHT(ic);
8649 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8650 /* if they are equivalent then do nothing */
8651 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8654 aopOp(right,ic,FALSE) ;
8655 aopOp(result,ic,FALSE);
8657 /* if the result is a bit */
8658 if (AOP_TYPE(result) == AOP_CRY) {
8659 /* if the right size is a literal then
8660 we know what the value is */
8661 if (AOP_TYPE(right) == AOP_LIT) {
8663 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8664 popGet(AOP(result),0,FALSE,FALSE));
8666 if (((int) operandLitValue(right)))
8667 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8668 AOP(result)->aopu.aop_dir,
8669 AOP(result)->aopu.aop_dir);
8671 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8672 AOP(result)->aopu.aop_dir,
8673 AOP(result)->aopu.aop_dir);
8678 /* the right is also a bit variable */
8679 if (AOP_TYPE(right) == AOP_CRY) {
8682 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8684 pic14_emitcode("clrc","");
8685 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8686 AOP(right)->aopu.aop_dir,
8687 AOP(right)->aopu.aop_dir);
8688 aopPut(AOP(result),"c",0);
8693 pic14_toBoolean(right);
8694 aopPut(AOP(result),"a",0);
8698 /* if they are the same size : or less */
8699 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8701 /* if they are in the same place */
8702 if (pic14_sameRegs(AOP(right),AOP(result)))
8705 /* if they in different places then copy */
8706 size = AOP_SIZE(result);
8710 aopGet(AOP(right),offset,FALSE,FALSE),
8718 /* if the result is of type pointer */
8719 if (IS_PTR(ctype)) {
8722 sym_link *type = operandType(right);
8723 sym_link *etype = getSpec(type);
8725 /* pointer to generic pointer */
8726 if (IS_GENPTR(ctype)) {
8730 p_type = DCL_TYPE(type);
8732 /* we have to go by the storage class */
8733 p_type = PTR_TYPE(SPEC_OCLS(etype));
8735 /* if (SPEC_OCLS(etype)->codesp ) */
8736 /* p_type = CPOINTER ; */
8738 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8739 /* p_type = FPOINTER ; */
8741 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8742 /* p_type = PPOINTER; */
8744 /* if (SPEC_OCLS(etype) == idata ) */
8745 /* p_type = IPOINTER ; */
8747 /* p_type = POINTER ; */
8750 /* the first two bytes are known */
8751 size = GPTRSIZE - 1;
8755 aopGet(AOP(right),offset,FALSE,FALSE),
8759 /* the last byte depending on type */
8776 /* this should never happen */
8777 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8778 "got unknown pointer type");
8781 aopPut(AOP(result),l, GPTRSIZE - 1);
8785 /* just copy the pointers */
8786 size = AOP_SIZE(result);
8790 aopGet(AOP(right),offset,FALSE,FALSE),
8798 if (AOP_TYPE(right) == AOP_CRY) {
8800 size = AOP_SIZE(right);
8802 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8803 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8804 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8806 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8807 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8808 AOP(right)->aopu.aop_dir,
8809 AOP(right)->aopu.aop_dir);
8810 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8812 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8813 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8818 /* so we now know that the size of destination is greater
8819 than the size of the source.
8820 Now, if the next iCode is an operator then we might be
8821 able to optimize the operation without performing a cast.
8823 if(genMixedOperation(ic))
8827 /* we move to result for the size of source */
8828 size = AOP_SIZE(right);
8831 pic14_emitcode(";","%d",__LINE__);
8832 /* aopPut(AOP(result),
8833 aopGet(AOP(right),offset,FALSE,FALSE),
8835 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8836 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8840 /* now depending on the sign of the destination */
8841 size = AOP_SIZE(result) - AOP_SIZE(right);
8842 /* if unsigned or not an integral type */
8843 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8845 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8846 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8850 /* we need to extend the sign :{ */
8852 emitpcodeNULLop(POC_CLRW);
8855 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8857 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8859 emitpcode(POC_MOVLW, popGetLit(0xff));
8861 pic14_emitcode("clrw","");
8862 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8863 AOP(right)->aopu.aop_dir,
8864 AOP(right)->aopu.aop_dir);
8865 pic14_emitcode("movlw","0xff");
8867 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8868 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8870 // aopPut(AOP(result),"a",offset++);
8875 /* we are done hurray !!!! */
8878 freeAsmop(right,NULL,ic,TRUE);
8879 freeAsmop(result,NULL,ic,TRUE);
8883 /*-----------------------------------------------------------------*/
8884 /* genDjnz - generate decrement & jump if not zero instrucion */
8885 /*-----------------------------------------------------------------*/
8886 static int genDjnz (iCode *ic, iCode *ifx)
8889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8894 /* if the if condition has a false label
8895 then we cannot save */
8899 /* if the minus is not of the form
8901 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8902 !IS_OP_LITERAL(IC_RIGHT(ic)))
8905 if (operandLitValue(IC_RIGHT(ic)) != 1)
8908 /* if the size of this greater than one then no
8910 if (getSize(operandType(IC_RESULT(ic))) > 1)
8913 /* otherwise we can save BIG */
8914 lbl = newiTempLabel(NULL);
8915 lbl1= newiTempLabel(NULL);
8917 aopOp(IC_RESULT(ic),ic,FALSE);
8919 if (IS_AOP_PREG(IC_RESULT(ic))) {
8920 pic14_emitcode("dec","%s",
8921 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8922 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8923 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8927 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8928 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8930 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8931 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8934 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8935 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8936 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8937 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8940 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8945 /*-----------------------------------------------------------------*/
8946 /* genReceive - generate code for a receive iCode */
8947 /*-----------------------------------------------------------------*/
8948 static void genReceive (iCode *ic)
8950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8952 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8953 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8954 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8956 int size = getSize(operandType(IC_RESULT(ic)));
8957 int offset = fReturnSizePic - size;
8959 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8960 fReturn[fReturnSizePic - offset - 1] : "acc"));
8963 aopOp(IC_RESULT(ic),ic,FALSE);
8964 size = AOP_SIZE(IC_RESULT(ic));
8967 pic14_emitcode ("pop","acc");
8968 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8973 aopOp(IC_RESULT(ic),ic,FALSE);
8975 assignResultValue(IC_RESULT(ic));
8978 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8981 /*-----------------------------------------------------------------*/
8982 /* genpic14Code - generate code for pic14 based controllers */
8983 /*-----------------------------------------------------------------*/
8985 * At this point, ralloc.c has gone through the iCode and attempted
8986 * to optimize in a way suitable for a PIC. Now we've got to generate
8987 * PIC instructions that correspond to the iCode.
8989 * Once the instructions are generated, we'll pass through both the
8990 * peep hole optimizer and the pCode optimizer.
8991 *-----------------------------------------------------------------*/
8993 void genpic14Code (iCode *lic)
8998 lineHead = lineCurr = NULL;
9000 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9003 /* if debug information required */
9004 /* if (options.debug && currFunc) { */
9006 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9008 if (IS_STATIC(currFunc->etype)) {
9009 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9010 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9012 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9013 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9019 for (ic = lic ; ic ; ic = ic->next ) {
9021 DEBUGpic14_emitcode(";ic","");
9022 if ( cln != ic->lineno ) {
9023 if ( options.debug ) {
9025 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9026 FileBaseName(ic->filename),ic->lineno,
9027 ic->level,ic->block);
9030 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9033 /* if the result is marked as
9034 spilt and rematerializable or code for
9035 this has already been generated then
9037 if (resultRemat(ic) || ic->generated )
9040 /* depending on the operation */
9059 /* IPOP happens only when trying to restore a
9060 spilt live range, if there is an ifx statement
9061 following this pop then the if statement might
9062 be using some of the registers being popped which
9063 would destory the contents of the register so
9064 we need to check for this condition and handle it */
9066 ic->next->op == IFX &&
9067 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9068 genIfx (ic->next,ic);
9086 genEndFunction (ic);
9106 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9123 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9127 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9134 /* note these two are xlated by algebraic equivalence
9135 during parsing SDCC.y */
9136 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9137 "got '>=' or '<=' shouldn't have come here");
9141 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9153 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9157 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9161 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9188 case GET_VALUE_AT_ADDRESS:
9193 if (POINTER_SET(ic))
9220 addSet(&_G.sendSet,ic);
9229 /* now we are ready to call the
9230 peep hole optimizer */
9231 if (!options.nopeep) {
9232 printf("peep hole optimizing\n");
9233 peepHole (&lineHead);
9235 /* now do the actual printing */
9236 printLine (lineHead,codeOutFile);
9238 printf("printing pBlock\n\n");
9239 printpBlock(stdout,pb);