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 static int labelOffset=0;
64 static int debug_verbose=1;
65 static int optimized_for_speed = 0;
67 /* max_key keeps track of the largest label number used in
68 a function. This is then used to adjust the label offset
69 for the next function.
72 static int GpsuedoStkPtr=0;
74 unsigned int pic14aopLiteral (value *val, int offset);
75 const char *AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic14[] = {"FSR","dph","b","a" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic14;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic14_ptrRegReq ;
119 extern int pic14_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
186 sprintf(lb,"%s\t",inst);
188 sprintf(lb,"%s",inst);
189 vsprintf(lb+(strlen(lb)),fmt,ap);
193 while (isspace(*lbp)) lbp++;
196 lineCurr = (lineCurr ?
197 connectLine(lineCurr,newLineNode(lb)) :
198 (lineHead = newLineNode(lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
202 addpCode2pBlock(pb,newpCodeCharP(lb));
208 static void emitpLabel(int key)
210 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
213 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
229 /*-----------------------------------------------------------------*/
230 /* pic14_emitcode - writes the code into a file : for now it is simple */
231 /*-----------------------------------------------------------------*/
232 void pic14_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
242 sprintf(lb,"%s\t",inst);
244 sprintf(lb,"%s",inst);
245 vsprintf(lb+(strlen(lb)),fmt,ap);
249 while (isspace(*lbp)) lbp++;
252 lineCurr = (lineCurr ?
253 connectLine(lineCurr,newLineNode(lb)) :
254 (lineHead = newLineNode(lb)));
255 lineCurr->isInline = _G.inLine;
256 lineCurr->isDebug = _G.debugLine;
259 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
267 /*-----------------------------------------------------------------*/
268 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
270 bool r0iu = FALSE , r1iu = FALSE;
271 bool r0ou = FALSE , r1ou = FALSE;
273 /* the logic: if r0 & r1 used in the instruction
274 then we are in trouble otherwise */
276 /* first check if r0 & r1 are used by this
277 instruction, in which case we are in trouble */
278 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
279 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
284 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
285 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
287 /* if no usage of r0 then return it */
288 if (!r0iu && !r0ou) {
289 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
290 (*aopp)->type = AOP_R0;
292 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
295 /* if no usage of r1 then return it */
296 if (!r1iu && !r1ou) {
297 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
298 (*aopp)->type = AOP_R1;
300 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
303 /* now we know they both have usage */
304 /* if r0 not used in this instruction */
306 /* push it if not already pushed */
308 pic14_emitcode ("push","%s",
309 pic14_regWithIdx(R0_IDX)->dname);
313 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
314 (*aopp)->type = AOP_R0;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
319 /* if r1 not used then */
322 /* push it if not already pushed */
324 pic14_emitcode ("push","%s",
325 pic14_regWithIdx(R1_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
330 (*aopp)->type = AOP_R1;
331 return pic14_regWithIdx(R1_IDX);
335 /* I said end of world but not quite end of world yet */
336 /* if this is a result then we can push it on the stack*/
338 (*aopp)->type = AOP_STK;
342 /* other wise this is true end of the world */
343 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
344 "getFreePtr should never reach here");
348 /*-----------------------------------------------------------------*/
349 /* newAsmop - creates a new asmOp */
350 /*-----------------------------------------------------------------*/
351 asmop *newAsmop (short type)
355 aop = Safe_calloc(1,sizeof(asmop));
360 static void genSetDPTR(int n)
364 pic14_emitcode(";", "Select standard DPTR");
365 pic14_emitcode("mov", "dps, #0x00");
369 pic14_emitcode(";", "Select alternate DPTR");
370 pic14_emitcode("mov", "dps, #0x01");
374 /*-----------------------------------------------------------------*/
375 /* resolveIfx - converts an iCode ifx into a form more useful for */
376 /* generating code */
377 /*-----------------------------------------------------------------*/
378 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
385 resIfx->condition = 1; /* assume that the ifx is true */
386 resIfx->generated = 0; /* indicate that the ifx has not been used */
389 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
390 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
391 __FUNCTION__,__LINE__,resIfx->lbl->key);
394 resIfx->lbl = IC_TRUE(ifx);
396 resIfx->lbl = IC_FALSE(ifx);
397 resIfx->condition = 0;
400 DEBUGpic14_emitcode("; ***","ifx true is non-null");
402 DEBUGpic14_emitcode("; ***","ifx false is non-null");
405 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
408 /*-----------------------------------------------------------------*/
409 /* pointerCode - returns the code for a pointer type */
410 /*-----------------------------------------------------------------*/
411 static int pointerCode (sym_link *etype)
414 return PTR_TYPE(SPEC_OCLS(etype));
418 /*-----------------------------------------------------------------*/
419 /* aopForSym - for a true symbol */
420 /*-----------------------------------------------------------------*/
421 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
424 memmap *space= SPEC_OCLS(sym->etype);
426 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
427 /* if already has one */
431 /* assign depending on the storage class */
432 /* if it is on the stack or indirectly addressable */
433 /* space we need to assign either r0 or r1 to it */
434 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
435 sym->aop = aop = newAsmop(0);
436 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
437 aop->size = getSize(sym->type);
439 /* now assign the address of the variable to
440 the pointer register */
441 if (aop->type != AOP_STK) {
445 pic14_emitcode("push","acc");
447 pic14_emitcode("mov","a,_bp");
448 pic14_emitcode("add","a,#0x%02x",
450 ((char)(sym->stack - _G.nRegsSaved )) :
451 ((char)sym->stack)) & 0xff);
452 pic14_emitcode("mov","%s,a",
453 aop->aopu.aop_ptr->name);
456 pic14_emitcode("pop","acc");
458 pic14_emitcode("mov","%s,#%s",
459 aop->aopu.aop_ptr->name,
461 aop->paged = space->paged;
463 aop->aopu.aop_stk = sym->stack;
467 if (sym->onStack && options.stack10bit)
469 /* It's on the 10 bit stack, which is located in
473 //DEBUGpic14_emitcode(";","%d",__LINE__);
476 pic14_emitcode("push","acc");
478 pic14_emitcode("mov","a,_bp");
479 pic14_emitcode("add","a,#0x%02x",
481 ((char)(sym->stack - _G.nRegsSaved )) :
482 ((char)sym->stack)) & 0xff);
485 pic14_emitcode ("mov","dpx1,#0x40");
486 pic14_emitcode ("mov","dph1,#0x00");
487 pic14_emitcode ("mov","dpl1, a");
491 pic14_emitcode("pop","acc");
493 sym->aop = aop = newAsmop(AOP_DPTR2);
494 aop->size = getSize(sym->type);
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 /* if in bit space */
500 if (IN_BITSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_CRY);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
507 /* if it is in direct space */
508 if (IN_DIRSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_DIR);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
516 /* special case for a function */
517 if (IS_FUNC(sym->type)) {
518 sym->aop = aop = newAsmop(AOP_IMMD);
519 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
520 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
521 strcpy(aop->aopu.aop_immd,sym->rname);
522 aop->size = FPTRSIZE;
527 /* only remaining is far space */
528 /* in which case DPTR gets the address */
529 sym->aop = aop = newAsmop(AOP_DPTR);
530 pic14_emitcode ("mov","dptr,#%s", sym->rname);
531 aop->size = getSize(sym->type);
533 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
534 /* if it is in code space */
535 if (IN_CODESPACE(space))
541 /*-----------------------------------------------------------------*/
542 /* aopForRemat - rematerialzes an object */
543 /*-----------------------------------------------------------------*/
544 static asmop *aopForRemat (symbol *sym)
546 iCode *ic = sym->rematiCode;
547 asmop *aop = newAsmop(AOP_IMMD);
549 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
552 val += (int) operandLitValue(IC_RIGHT(ic));
553 else if (ic->op == '-')
554 val -= (int) operandLitValue(IC_RIGHT(ic));
558 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
562 sprintf(buffer,"(%s %c 0x%04x)",
563 OP_SYMBOL(IC_LEFT(ic))->rname,
564 val >= 0 ? '+' : '-',
567 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
569 //DEBUGpic14_emitcode(";","%s",buffer);
570 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
571 strcpy(aop->aopu.aop_immd,buffer);
575 int aopIdx (asmop *aop, int offset)
580 if(aop->type != AOP_REG)
583 return aop->aopu.aop_reg[offset]->rIdx;
586 /*-----------------------------------------------------------------*/
587 /* regsInCommon - two operands have some registers in common */
588 /*-----------------------------------------------------------------*/
589 static bool regsInCommon (operand *op1, operand *op2)
594 /* if they have registers in common */
595 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
598 sym1 = OP_SYMBOL(op1);
599 sym2 = OP_SYMBOL(op2);
601 if (sym1->nRegs == 0 || sym2->nRegs == 0)
604 for (i = 0 ; i < sym1->nRegs ; i++) {
609 for (j = 0 ; j < sym2->nRegs ;j++ ) {
613 if (sym2->regs[j] == sym1->regs[i])
621 /*-----------------------------------------------------------------*/
622 /* operandsEqu - equivalent */
623 /*-----------------------------------------------------------------*/
624 static bool operandsEqu ( operand *op1, operand *op2)
628 /* if they not symbols */
629 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
632 sym1 = OP_SYMBOL(op1);
633 sym2 = OP_SYMBOL(op2);
635 /* if both are itemps & one is spilt
636 and the other is not then false */
637 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
638 sym1->isspilt != sym2->isspilt )
641 /* if they are the same */
645 if (strcmp(sym1->rname,sym2->rname) == 0)
649 /* if left is a tmp & right is not */
653 (sym1->usl.spillLoc == sym2))
660 (sym2->usl.spillLoc == sym1))
666 /*-----------------------------------------------------------------*/
667 /* pic14_sameRegs - two asmops have the same registers */
668 /*-----------------------------------------------------------------*/
669 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
676 if (aop1->type != AOP_REG ||
677 aop2->type != AOP_REG )
680 if (aop1->size != aop2->size )
683 for (i = 0 ; i < aop1->size ; i++ )
684 if (aop1->aopu.aop_reg[i] !=
685 aop2->aopu.aop_reg[i] )
691 /*-----------------------------------------------------------------*/
692 /* aopOp - allocates an asmop for an operand : */
693 /*-----------------------------------------------------------------*/
694 void aopOp (operand *op, iCode *ic, bool result)
703 // DEBUGpic14_emitcode(";","%d",__LINE__);
704 /* if this a literal */
705 if (IS_OP_LITERAL(op)) {
706 op->aop = aop = newAsmop(AOP_LIT);
707 aop->aopu.aop_lit = op->operand.valOperand;
708 aop->size = getSize(operandType(op));
712 /* if already has a asmop then continue */
716 /* if the underlying symbol has a aop */
717 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
718 DEBUGpic14_emitcode(";","%d",__LINE__);
719 op->aop = OP_SYMBOL(op)->aop;
723 /* if this is a true symbol */
724 if (IS_TRUE_SYMOP(op)) {
725 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
726 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
730 /* this is a temporary : this has
736 e) can be a return use only */
741 /* if the type is a conditional */
742 if (sym->regType == REG_CND) {
743 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
748 /* if it is spilt then two situations
750 b) has a spill location */
751 if (sym->isspilt || sym->nRegs == 0) {
753 DEBUGpic14_emitcode(";","%d",__LINE__);
754 /* rematerialize it NOW */
756 sym->aop = op->aop = aop =
758 aop->size = getSize(sym->type);
764 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
765 aop->size = getSize(sym->type);
766 for ( i = 0 ; i < 2 ; i++ )
767 aop->aopu.aop_str[i] = accUse[i];
768 DEBUGpic14_emitcode(";","%d",__LINE__);
774 aop = op->aop = sym->aop = newAsmop(AOP_STR);
775 aop->size = getSize(sym->type);
776 for ( i = 0 ; i < fReturnSizePic ; i++ )
777 aop->aopu.aop_str[i] = fReturn[i];
778 DEBUGpic14_emitcode(";","%d",__LINE__);
782 /* else spill location */
783 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
784 /* force a new aop if sizes differ */
785 sym->usl.spillLoc->aop = NULL;
787 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
788 sym->aop = op->aop = aop =
789 aopForSym(ic,sym->usl.spillLoc,result);
790 aop->size = getSize(sym->type);
794 /* must be in a register */
795 sym->aop = op->aop = aop = newAsmop(AOP_REG);
796 aop->size = sym->nRegs;
797 for ( i = 0 ; i < sym->nRegs ;i++)
798 aop->aopu.aop_reg[i] = sym->regs[i];
801 /*-----------------------------------------------------------------*/
802 /* freeAsmop - free up the asmop given to an operand */
803 /*----------------------------------------------------------------*/
804 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
821 /* depending on the asmop type only three cases need work AOP_RO
822 , AOP_R1 && AOP_STK */
828 pic14_emitcode ("pop","ar0");
832 bitVectUnSetBit(ic->rUsed,R0_IDX);
838 pic14_emitcode ("pop","ar1");
842 bitVectUnSetBit(ic->rUsed,R1_IDX);
848 int stk = aop->aopu.aop_stk + aop->size;
849 bitVectUnSetBit(ic->rUsed,R0_IDX);
850 bitVectUnSetBit(ic->rUsed,R1_IDX);
852 getFreePtr(ic,&aop,FALSE);
854 if (options.stack10bit)
856 /* I'm not sure what to do here yet... */
859 "*** Warning: probably generating bad code for "
860 "10 bit stack mode.\n");
864 pic14_emitcode ("mov","a,_bp");
865 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
866 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
868 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
872 pic14_emitcode("pop","acc");
873 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
875 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
878 freeAsmop(op,NULL,ic,TRUE);
880 pic14_emitcode("pop","ar0");
885 pic14_emitcode("pop","ar1");
893 /* all other cases just dealloc */
897 OP_SYMBOL(op)->aop = NULL;
898 /* if the symbol has a spill */
900 SPIL_LOC(op)->aop = NULL;
905 /*-----------------------------------------------------------------*/
906 /* aopGet - for fetching value of the aop */
907 /*-----------------------------------------------------------------*/
908 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
913 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
914 /* offset is greater than
916 if (offset > (aop->size - 1) &&
917 aop->type != AOP_LIT)
920 /* depending on type */
925 DEBUGpic14_emitcode(";","%d",__LINE__);
926 /* if we need to increment it */
927 while (offset > aop->coff) {
928 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
932 while (offset < aop->coff) {
933 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
939 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
940 return (dname ? "acc" : "a");
942 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
943 rs = Safe_calloc(1,strlen(s)+1);
949 DEBUGpic14_emitcode(";","%d",__LINE__);
950 if (aop->type == AOP_DPTR2)
955 while (offset > aop->coff) {
956 pic14_emitcode ("inc","dptr");
960 while (offset < aop->coff) {
961 pic14_emitcode("lcall","__decdptr");
967 pic14_emitcode("clr","a");
968 pic14_emitcode("movc","a,@a+dptr");
971 pic14_emitcode("movx","a,@dptr");
974 if (aop->type == AOP_DPTR2)
979 return (dname ? "acc" : "a");
983 DEBUGpic14_emitcode(";","%d",__LINE__);
985 sprintf (s,"%s",aop->aopu.aop_immd);
988 sprintf(s,"(%s >> %d)",
994 rs = Safe_calloc(1,strlen(s)+1);
1000 sprintf(s,"(%s + %d)",
1004 sprintf(s,"%s",aop->aopu.aop_dir);
1005 rs = Safe_calloc(1,strlen(s)+1);
1011 return aop->aopu.aop_reg[offset]->dname;
1013 return aop->aopu.aop_reg[offset]->name;
1016 //pic14_emitcode(";","%d",__LINE__);
1017 return aop->aopu.aop_dir;
1020 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1021 return "AOP_accumulator_bug";
1024 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1025 rs = Safe_calloc(1,strlen(s)+1);
1030 DEBUGpic14_emitcode(";","%d",__LINE__);
1031 aop->coff = offset ;
1032 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1036 return aop->aopu.aop_str[offset];
1040 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1041 "aopget got unsupported aop->type");
1045 /*-----------------------------------------------------------------*/
1046 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1047 /*-----------------------------------------------------------------*/
1048 pCodeOp *popGetLabel(unsigned int key)
1051 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1056 return newpCodeOpLabel(key+100+labelOffset);
1059 /*-----------------------------------------------------------------*/
1060 /* popCopyReg - copy a pcode operator */
1061 /*-----------------------------------------------------------------*/
1062 pCodeOp *popCopyReg(pCodeOpReg *pc)
1066 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1067 pcor->pcop.type = pc->pcop.type;
1068 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1069 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1071 pcor->rIdx = pc->rIdx;
1073 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1078 /*-----------------------------------------------------------------*/
1079 /* popCopy - copy a pcode operator */
1080 /*-----------------------------------------------------------------*/
1081 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1085 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1086 pcop->type = PO_BIT;
1087 if(!(pcop->name = Safe_strdup(pc->name)))
1088 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1089 ((pCodeOpBit *)pcop)->bit = bitval;
1091 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1096 /*-----------------------------------------------------------------*/
1097 /* popGet - asm operator to pcode operator conversion */
1098 /*-----------------------------------------------------------------*/
1099 pCodeOp *popGetLit(unsigned int lit)
1102 return newpCodeOpLit(lit);
1106 /*-----------------------------------------------------------------*/
1107 /* popGet - asm operator to pcode operator conversion */
1108 /*-----------------------------------------------------------------*/
1109 pCodeOp *popGetWithString(char *str)
1115 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1119 pcop = newpCodeOp(str,PO_STR);
1124 pCodeOp *popRegFromString(char *str)
1127 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1128 pcop->type = PO_GPR_REGISTER;
1130 PCOR(pcop)->rIdx = -1;
1131 PCOR(pcop)->r = NULL;
1133 DEBUGpic14_emitcode(";","%d",__LINE__);
1134 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1139 pCodeOp *popRegFromIdx(int rIdx)
1143 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1144 __FUNCTION__,__LINE__,rIdx);
1146 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1148 PCOR(pcop)->rIdx = rIdx;
1149 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1150 PCOR(pcop)->r->isFree = 0;
1151 PCOR(pcop)->r->wasUsed = 1;
1153 pcop->type = PCOR(pcop)->r->pc_type;
1158 /*-----------------------------------------------------------------*/
1159 /* popGet - asm operator to pcode operator conversion */
1160 /*-----------------------------------------------------------------*/
1161 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1168 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1169 /* offset is greater than
1172 if (offset > (aop->size - 1) &&
1173 aop->type != AOP_LIT)
1174 return NULL; //zero;
1176 /* depending on type */
1177 switch (aop->type) {
1184 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1185 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1186 //pcop->type = PO_SFR_REGISTER;
1188 //PCOR(pcop)->rIdx = -1;
1189 //PCOR(pcop)->r = NULL;
1190 // Really nasty hack to check for temporary registers
1192 //pcop->name = Safe_strdup("BAD_REGISTER");
1197 DEBUGpic14_emitcode(";","%d",__LINE__);
1198 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1199 pcop->type = PO_IMMEDIATE;
1201 // sprintf (s,"%s",aop->aopu.aop_immd);
1204 sprintf(s,"(%s >> %d)",
1209 aop->aopu.aop_immd);
1210 pcop->name = Safe_calloc(1,strlen(s)+1);
1211 strcpy(pcop->name,s);
1215 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1216 pcop->type = PO_DIR;
1218 sprintf(s,"(%s + %d)",
1222 sprintf(s,"%s",aop->aopu.aop_dir);
1223 pcop->name = Safe_calloc(1,strlen(s)+1);
1224 strcpy(pcop->name,s);
1229 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1231 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1232 PCOR(pcop)->rIdx = rIdx;
1233 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1234 pcop->type = PCOR(pcop)->r->pc_type;
1235 rs = aop->aopu.aop_reg[offset]->name;
1236 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1241 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1245 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1248 DEBUGpic14_emitcode(";","%d",__LINE__);
1250 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1251 pcop->type = PO_STR;
1253 //aop->coff = offset ;
1254 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1255 // sprintf(s,"%s","acc");
1257 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1258 pcop->name = Safe_calloc(1,strlen(s)+1);
1259 strcpy(pcop->name,s);
1264 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1265 "popGet got unsupported aop->type");
1268 /*-----------------------------------------------------------------*/
1269 /* aopPut - puts a string for a aop */
1270 /*-----------------------------------------------------------------*/
1271 void aopPut (asmop *aop, char *s, int offset)
1276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1278 if (aop->size && offset > ( aop->size - 1)) {
1279 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280 "aopPut got offset > aop->size");
1284 /* will assign value to value */
1285 /* depending on where it is ofcourse */
1286 switch (aop->type) {
1289 sprintf(d,"(%s + %d)",
1290 aop->aopu.aop_dir,offset);
1292 sprintf(d,"%s",aop->aopu.aop_dir);
1295 DEBUGpic14_emitcode(";","%d",__LINE__);
1297 pic14_emitcode("movf","%s,w",s);
1298 pic14_emitcode("movwf","%s",d);
1301 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1302 emitpcode(POC_MOVWF,popGet(aop,offset));
1309 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1310 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1313 strcmp(s,"r0") == 0 ||
1314 strcmp(s,"r1") == 0 ||
1315 strcmp(s,"r2") == 0 ||
1316 strcmp(s,"r3") == 0 ||
1317 strcmp(s,"r4") == 0 ||
1318 strcmp(s,"r5") == 0 ||
1319 strcmp(s,"r6") == 0 ||
1320 strcmp(s,"r7") == 0 )
1321 pic14_emitcode("mov","%s,%s ; %d",
1322 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1327 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1329 pic14_emitcode("movwf","%s",
1330 aop->aopu.aop_reg[offset]->name);
1333 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1334 pcop->type = PO_GPR_REGISTER;
1336 PCOR(pcop)->rIdx = -1;
1337 PCOR(pcop)->r = NULL;
1339 DEBUGpic14_emitcode(";","%d",__LINE__);
1340 pcop->name = Safe_strdup(s);
1341 emitpcode(POC_MOVFW,pcop);
1343 emitpcode(POC_MOVWF,popGet(aop,offset));
1351 if (aop->type == AOP_DPTR2)
1357 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1358 "aopPut writting to code space");
1362 while (offset > aop->coff) {
1364 pic14_emitcode ("inc","dptr");
1367 while (offset < aop->coff) {
1369 pic14_emitcode("lcall","__decdptr");
1374 /* if not in accumulater */
1377 pic14_emitcode ("movx","@dptr,a");
1379 if (aop->type == AOP_DPTR2)
1387 while (offset > aop->coff) {
1389 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1391 while (offset < aop->coff) {
1393 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1399 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1404 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1406 if (strcmp(s,"r0") == 0 ||
1407 strcmp(s,"r1") == 0 ||
1408 strcmp(s,"r2") == 0 ||
1409 strcmp(s,"r3") == 0 ||
1410 strcmp(s,"r4") == 0 ||
1411 strcmp(s,"r5") == 0 ||
1412 strcmp(s,"r6") == 0 ||
1413 strcmp(s,"r7") == 0 ) {
1415 sprintf(buffer,"a%s",s);
1416 pic14_emitcode("mov","@%s,%s",
1417 aop->aopu.aop_ptr->name,buffer);
1419 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1424 if (strcmp(s,"a") == 0)
1425 pic14_emitcode("push","acc");
1427 pic14_emitcode("push","%s",s);
1432 /* if bit variable */
1433 if (!aop->aopu.aop_dir) {
1434 pic14_emitcode("clr","a");
1435 pic14_emitcode("rlc","a");
1438 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1441 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1444 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1446 lbl = newiTempLabel(NULL);
1448 if (strcmp(s,"a")) {
1451 pic14_emitcode("clr","c");
1452 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1453 pic14_emitcode("cpl","c");
1454 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1455 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1462 if (strcmp(aop->aopu.aop_str[offset],s))
1463 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1468 if (!offset && (strcmp(s,"acc") == 0))
1471 if (strcmp(aop->aopu.aop_str[offset],s))
1472 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1476 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1477 "aopPut got unsupported aop->type");
1483 /*-----------------------------------------------------------------*/
1484 /* reAdjustPreg - points a register back to where it should */
1485 /*-----------------------------------------------------------------*/
1486 static void reAdjustPreg (asmop *aop)
1490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1492 if ((size = aop->size) <= 1)
1495 switch (aop->type) {
1499 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1503 if (aop->type == AOP_DPTR2)
1509 pic14_emitcode("lcall","__decdptr");
1512 if (aop->type == AOP_DPTR2)
1522 /*-----------------------------------------------------------------*/
1523 /* genNotFloat - generates not for float operations */
1524 /*-----------------------------------------------------------------*/
1525 static void genNotFloat (operand *op, operand *res)
1531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1532 /* we will put 127 in the first byte of
1534 aopPut(AOP(res),"#127",0);
1535 size = AOP_SIZE(op) - 1;
1538 l = aopGet(op->aop,offset++,FALSE,FALSE);
1542 pic14_emitcode("orl","a,%s",
1544 offset++,FALSE,FALSE));
1546 tlbl = newiTempLabel(NULL);
1548 tlbl = newiTempLabel(NULL);
1549 aopPut(res->aop,one,1);
1550 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1551 aopPut(res->aop,zero,1);
1552 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1554 size = res->aop->size - 2;
1556 /* put zeros in the rest */
1558 aopPut(res->aop,zero,offset++);
1562 /*-----------------------------------------------------------------*/
1563 /* opIsGptr: returns non-zero if the passed operand is */
1564 /* a generic pointer type. */
1565 /*-----------------------------------------------------------------*/
1566 static int opIsGptr(operand *op)
1568 sym_link *type = operandType(op);
1570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1571 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1579 /*-----------------------------------------------------------------*/
1580 /* pic14_getDataSize - get the operand data size */
1581 /*-----------------------------------------------------------------*/
1582 int pic14_getDataSize(operand *op)
1584 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1587 return AOP_SIZE(op);
1589 // tsd- in the pic port, the genptr size is 1, so this code here
1590 // fails. ( in the 8051 port, the size was 4).
1593 size = AOP_SIZE(op);
1594 if (size == GPTRSIZE)
1596 sym_link *type = operandType(op);
1597 if (IS_GENPTR(type))
1599 /* generic pointer; arithmetic operations
1600 * should ignore the high byte (pointer type).
1603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1610 /*-----------------------------------------------------------------*/
1611 /* pic14_outAcc - output Acc */
1612 /*-----------------------------------------------------------------*/
1613 void pic14_outAcc(operand *result)
1616 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1617 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1620 size = pic14_getDataSize(result);
1622 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1625 /* unsigned or positive */
1627 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1632 /*-----------------------------------------------------------------*/
1633 /* pic14_outBitC - output a bit C */
1634 /*-----------------------------------------------------------------*/
1635 void pic14_outBitC(operand *result)
1638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1639 /* if the result is bit */
1640 if (AOP_TYPE(result) == AOP_CRY)
1641 aopPut(AOP(result),"c",0);
1643 pic14_emitcode("clr","a ; %d", __LINE__);
1644 pic14_emitcode("rlc","a");
1645 pic14_outAcc(result);
1649 /*-----------------------------------------------------------------*/
1650 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1651 /*-----------------------------------------------------------------*/
1652 void pic14_toBoolean(operand *oper)
1654 int size = AOP_SIZE(oper) - 1;
1657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if ( AOP_TYPE(oper) != AOP_ACC) {
1660 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1663 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1668 /*-----------------------------------------------------------------*/
1669 /* genNot - generate code for ! operation */
1670 /*-----------------------------------------------------------------*/
1671 static void genNot (iCode *ic)
1674 sym_link *optype = operandType(IC_LEFT(ic));
1677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1678 /* assign asmOps to operand & result */
1679 aopOp (IC_LEFT(ic),ic,FALSE);
1680 aopOp (IC_RESULT(ic),ic,TRUE);
1682 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1683 /* if in bit space then a special case */
1684 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1685 pic14_emitcode("movlw","1<<%s");
1686 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1687 //pic14_emitcode("cpl","c");
1688 //pic14_outBitC(IC_RESULT(ic));
1692 /* if type float then do float */
1693 if (IS_FLOAT(optype)) {
1694 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1698 size = AOP_SIZE(IC_RESULT(ic));
1700 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1701 emitpcode(POC_ANDLW,popGetLit(1));
1702 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1705 pic14_toBoolean(IC_LEFT(ic));
1707 tlbl = newiTempLabel(NULL);
1708 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1710 pic14_outBitC(IC_RESULT(ic));
1713 /* release the aops */
1714 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1715 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1719 /*-----------------------------------------------------------------*/
1720 /* genCpl - generate code for complement */
1721 /*-----------------------------------------------------------------*/
1722 static void genCpl (iCode *ic)
1728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 /* assign asmOps to operand & result */
1730 aopOp (IC_LEFT(ic),ic,FALSE);
1731 aopOp (IC_RESULT(ic),ic,TRUE);
1733 /* if both are in bit space then
1735 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1736 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1738 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1739 pic14_emitcode("cpl","c");
1740 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1744 size = AOP_SIZE(IC_RESULT(ic));
1746 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1748 pic14_emitcode("cpl","a");
1749 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1754 /* release the aops */
1755 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1756 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1759 /*-----------------------------------------------------------------*/
1760 /* genUminusFloat - unary minus for floating points */
1761 /*-----------------------------------------------------------------*/
1762 static void genUminusFloat(operand *op,operand *result)
1764 int size ,offset =0 ;
1767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1768 /* for this we just need to flip the
1769 first it then copy the rest in place */
1770 size = AOP_SIZE(op) - 1;
1771 l = aopGet(AOP(op),3,FALSE,FALSE);
1775 pic14_emitcode("cpl","acc.7");
1776 aopPut(AOP(result),"a",3);
1780 aopGet(AOP(op),offset,FALSE,FALSE),
1786 /*-----------------------------------------------------------------*/
1787 /* genUminus - unary minus code generation */
1788 /*-----------------------------------------------------------------*/
1789 static void genUminus (iCode *ic)
1792 sym_link *optype, *rtype;
1795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 aopOp(IC_LEFT(ic),ic,FALSE);
1798 aopOp(IC_RESULT(ic),ic,TRUE);
1800 /* if both in bit space then special
1802 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1803 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1805 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1806 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1807 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1812 optype = operandType(IC_LEFT(ic));
1813 rtype = operandType(IC_RESULT(ic));
1815 /* if float then do float stuff */
1816 if (IS_FLOAT(optype)) {
1817 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1821 /* otherwise subtract from zero by taking the 2's complement */
1822 size = AOP_SIZE(IC_LEFT(ic));
1824 for(i=0; i<size; i++) {
1825 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1826 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1828 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1829 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1833 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1834 for(i=1; i<size; i++) {
1836 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1840 /* release the aops */
1841 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1842 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1845 /*-----------------------------------------------------------------*/
1846 /* saveRegisters - will look for a call and save the registers */
1847 /*-----------------------------------------------------------------*/
1848 static void saveRegisters(iCode *lic)
1855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1857 for (ic = lic ; ic ; ic = ic->next)
1858 if (ic->op == CALL || ic->op == PCALL)
1862 fprintf(stderr,"found parameter push with no function call\n");
1866 /* if the registers have been saved already then
1868 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1871 /* find the registers in use at this time
1872 and push them away to safety */
1873 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1877 if (options.useXstack) {
1878 if (bitVectBitValue(rsave,R0_IDX))
1879 pic14_emitcode("mov","b,r0");
1880 pic14_emitcode("mov","r0,%s",spname);
1881 for (i = 0 ; i < pic14_nRegs ; i++) {
1882 if (bitVectBitValue(rsave,i)) {
1884 pic14_emitcode("mov","a,b");
1886 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1887 pic14_emitcode("movx","@r0,a");
1888 pic14_emitcode("inc","r0");
1891 pic14_emitcode("mov","%s,r0",spname);
1892 if (bitVectBitValue(rsave,R0_IDX))
1893 pic14_emitcode("mov","r0,b");
1895 for (i = 0 ; i < pic14_nRegs ; i++) {
1896 if (bitVectBitValue(rsave,i))
1897 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1900 dtype = operandType(IC_LEFT(ic));
1901 if (currFunc && dtype &&
1902 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1903 IFFUNC_ISISR(currFunc->type) &&
1906 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1909 /*-----------------------------------------------------------------*/
1910 /* unsaveRegisters - pop the pushed registers */
1911 /*-----------------------------------------------------------------*/
1912 static void unsaveRegisters (iCode *ic)
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 /* find the registers in use at this time
1919 and push them away to safety */
1920 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1923 if (options.useXstack) {
1924 pic14_emitcode("mov","r0,%s",spname);
1925 for (i = pic14_nRegs ; i >= 0 ; i--) {
1926 if (bitVectBitValue(rsave,i)) {
1927 pic14_emitcode("dec","r0");
1928 pic14_emitcode("movx","a,@r0");
1930 pic14_emitcode("mov","b,a");
1932 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1936 pic14_emitcode("mov","%s,r0",spname);
1937 if (bitVectBitValue(rsave,R0_IDX))
1938 pic14_emitcode("mov","r0,b");
1940 for (i = pic14_nRegs ; i >= 0 ; i--) {
1941 if (bitVectBitValue(rsave,i))
1942 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1948 /*-----------------------------------------------------------------*/
1950 /*-----------------------------------------------------------------*/
1951 static void pushSide(operand * oper, int size)
1955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1957 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1958 if (AOP_TYPE(oper) != AOP_REG &&
1959 AOP_TYPE(oper) != AOP_DIR &&
1961 pic14_emitcode("mov","a,%s",l);
1962 pic14_emitcode("push","acc");
1964 pic14_emitcode("push","%s",l);
1969 /*-----------------------------------------------------------------*/
1970 /* assignResultValue - */
1971 /*-----------------------------------------------------------------*/
1972 static void assignResultValue(operand * oper)
1974 int size = AOP_SIZE(oper);
1976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1978 if(!GpsuedoStkPtr) {
1979 /* The last byte in the assignment is in W */
1981 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1986 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1988 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1993 /*-----------------------------------------------------------------*/
1994 /* genIpush - genrate code for pushing this gets a little complex */
1995 /*-----------------------------------------------------------------*/
1996 static void genIpush (iCode *ic)
1999 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2001 int size, offset = 0 ;
2005 /* if this is not a parm push : ie. it is spill push
2006 and spill push is always done on the local stack */
2007 if (!ic->parmPush) {
2009 /* and the item is spilt then do nothing */
2010 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2013 aopOp(IC_LEFT(ic),ic,FALSE);
2014 size = AOP_SIZE(IC_LEFT(ic));
2015 /* push it on the stack */
2017 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2022 pic14_emitcode("push","%s",l);
2027 /* this is a paramter push: in this case we call
2028 the routine to find the call and save those
2029 registers that need to be saved */
2032 /* then do the push */
2033 aopOp(IC_LEFT(ic),ic,FALSE);
2036 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2037 size = AOP_SIZE(IC_LEFT(ic));
2040 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2041 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2042 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2044 pic14_emitcode("mov","a,%s",l);
2045 pic14_emitcode("push","acc");
2047 pic14_emitcode("push","%s",l);
2050 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2054 /*-----------------------------------------------------------------*/
2055 /* genIpop - recover the registers: can happen only for spilling */
2056 /*-----------------------------------------------------------------*/
2057 static void genIpop (iCode *ic)
2059 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2064 /* if the temp was not pushed then */
2065 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2068 aopOp(IC_LEFT(ic),ic,FALSE);
2069 size = AOP_SIZE(IC_LEFT(ic));
2072 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2075 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2079 /*-----------------------------------------------------------------*/
2080 /* unsaverbank - restores the resgister bank from stack */
2081 /*-----------------------------------------------------------------*/
2082 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2084 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 if (options.useXstack) {
2094 r = getFreePtr(ic,&aop,FALSE);
2097 pic14_emitcode("mov","%s,_spx",r->name);
2098 pic14_emitcode("movx","a,@%s",r->name);
2099 pic14_emitcode("mov","psw,a");
2100 pic14_emitcode("dec","%s",r->name);
2103 pic14_emitcode ("pop","psw");
2106 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2107 if (options.useXstack) {
2108 pic14_emitcode("movx","a,@%s",r->name);
2109 //pic14_emitcode("mov","(%s+%d),a",
2110 // regspic14[i].base,8*bank+regspic14[i].offset);
2111 pic14_emitcode("dec","%s",r->name);
2114 pic14_emitcode("pop",""); //"(%s+%d)",
2115 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2118 if (options.useXstack) {
2120 pic14_emitcode("mov","_spx,%s",r->name);
2121 freeAsmop(NULL,aop,ic,TRUE);
2127 /*-----------------------------------------------------------------*/
2128 /* saverbank - saves an entire register bank on the stack */
2129 /*-----------------------------------------------------------------*/
2130 static void saverbank (int bank, iCode *ic, bool pushPsw)
2132 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2139 if (options.useXstack) {
2142 r = getFreePtr(ic,&aop,FALSE);
2143 pic14_emitcode("mov","%s,_spx",r->name);
2147 for (i = 0 ; i < pic14_nRegs ;i++) {
2148 if (options.useXstack) {
2149 pic14_emitcode("inc","%s",r->name);
2150 //pic14_emitcode("mov","a,(%s+%d)",
2151 // regspic14[i].base,8*bank+regspic14[i].offset);
2152 pic14_emitcode("movx","@%s,a",r->name);
2154 pic14_emitcode("push","");// "(%s+%d)",
2155 //regspic14[i].base,8*bank+regspic14[i].offset);
2159 if (options.useXstack) {
2160 pic14_emitcode("mov","a,psw");
2161 pic14_emitcode("movx","@%s,a",r->name);
2162 pic14_emitcode("inc","%s",r->name);
2163 pic14_emitcode("mov","_spx,%s",r->name);
2164 freeAsmop (NULL,aop,ic,TRUE);
2167 pic14_emitcode("push","psw");
2169 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2175 /*-----------------------------------------------------------------*/
2176 /* genCall - generates a call statement */
2177 /*-----------------------------------------------------------------*/
2178 static void genCall (iCode *ic)
2182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2184 /* if caller saves & we have not saved then */
2188 /* if we are calling a function that is not using
2189 the same register bank then we need to save the
2190 destination registers on the stack */
2191 dtype = operandType(IC_LEFT(ic));
2192 if (currFunc && dtype &&
2193 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2194 IFFUNC_ISISR(currFunc->type) &&
2197 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2199 /* if send set is not empty the assign */
2202 /* For the Pic port, there is no data stack.
2203 * So parameters passed to functions are stored
2204 * in registers. (The pCode optimizer will get
2205 * rid of most of these :).
2207 int psuedoStkPtr=-1;
2208 int firstTimeThruLoop = 1;
2210 _G.sendSet = reverseSet(_G.sendSet);
2212 /* First figure how many parameters are getting passed */
2213 for (sic = setFirstItem(_G.sendSet) ; sic ;
2214 sic = setNextItem(_G.sendSet)) {
2216 aopOp(IC_LEFT(sic),sic,FALSE);
2217 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2218 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2221 for (sic = setFirstItem(_G.sendSet) ; sic ;
2222 sic = setNextItem(_G.sendSet)) {
2223 int size, offset = 0;
2225 aopOp(IC_LEFT(sic),sic,FALSE);
2226 size = AOP_SIZE(IC_LEFT(sic));
2230 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2231 AopType(AOP_TYPE(IC_LEFT(sic))));
2233 if(!firstTimeThruLoop) {
2234 /* If this is not the first time we've been through the loop
2235 * then we need to save the parameter in a temporary
2236 * register. The last byte of the last parameter is
2238 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2241 firstTimeThruLoop=0;
2243 //if (strcmp(l,fReturn[offset])) {
2245 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2246 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2247 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2249 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2254 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2259 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2260 OP_SYMBOL(IC_LEFT(ic))->rname :
2261 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 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2277 AopType(AOP_TYPE(IC_RESULT(ic))));
2279 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2282 /* adjust the stack for parameters if
2284 if (ic->parmBytes) {
2286 if (ic->parmBytes > 3) {
2287 pic14_emitcode("mov","a,%s",spname);
2288 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2289 pic14_emitcode("mov","%s,a",spname);
2291 for ( i = 0 ; i < ic->parmBytes ;i++)
2292 pic14_emitcode("dec","%s",spname);
2296 /* if register bank was saved then pop them */
2298 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2300 /* if we hade saved some registers then unsave them */
2301 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2302 unsaveRegisters (ic);
2307 /*-----------------------------------------------------------------*/
2308 /* genPcall - generates a call by pointer statement */
2309 /*-----------------------------------------------------------------*/
2310 static void genPcall (iCode *ic)
2313 symbol *rlbl = newiTempLabel(NULL);
2316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 /* if caller saves & we have not saved then */
2321 /* if we are calling a function that is not using
2322 the same register bank then we need to save the
2323 destination registers on the stack */
2324 dtype = operandType(IC_LEFT(ic));
2325 if (currFunc && dtype &&
2326 IFFUNC_ISISR(currFunc->type) &&
2327 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2328 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2331 /* push the return address on to the stack */
2332 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2333 pic14_emitcode("push","acc");
2334 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2335 pic14_emitcode("push","acc");
2337 if (options.model == MODEL_FLAT24)
2339 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2340 pic14_emitcode("push","acc");
2343 /* now push the calling address */
2344 aopOp(IC_LEFT(ic),ic,FALSE);
2346 pushSide(IC_LEFT(ic), FPTRSIZE);
2348 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2350 /* if send set is not empty the assign */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2356 int size, offset = 0;
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 size = AOP_SIZE(IC_LEFT(sic));
2360 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2362 if (strcmp(l,fReturn[offset]))
2363 pic14_emitcode("mov","%s,%s",
2368 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2373 pic14_emitcode("ret","");
2374 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2377 /* if we need assign a result value */
2378 if ((IS_ITEMP(IC_RESULT(ic)) &&
2379 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2380 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2381 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2384 aopOp(IC_RESULT(ic),ic,FALSE);
2387 assignResultValue(IC_RESULT(ic));
2389 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2392 /* adjust the stack for parameters if
2394 if (ic->parmBytes) {
2396 if (ic->parmBytes > 3) {
2397 pic14_emitcode("mov","a,%s",spname);
2398 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2399 pic14_emitcode("mov","%s,a",spname);
2401 for ( i = 0 ; i < ic->parmBytes ;i++)
2402 pic14_emitcode("dec","%s",spname);
2406 /* if register bank was saved then unsave them */
2407 if (currFunc && dtype &&
2408 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2409 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2411 /* if we hade saved some registers then
2414 unsaveRegisters (ic);
2418 /*-----------------------------------------------------------------*/
2419 /* resultRemat - result is rematerializable */
2420 /*-----------------------------------------------------------------*/
2421 static int resultRemat (iCode *ic)
2423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2424 if (SKIP_IC(ic) || ic->op == IFX)
2427 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2428 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2429 if (sym->remat && !POINTER_SET(ic))
2436 #if defined(__BORLANDC__) || defined(_MSC_VER)
2437 #define STRCASECMP stricmp
2439 #define STRCASECMP strcasecmp
2442 /*-----------------------------------------------------------------*/
2443 /* inExcludeList - return 1 if the string is in exclude Reg list */
2444 /*-----------------------------------------------------------------*/
2445 static bool inExcludeList(char *s)
2447 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2452 if (options.excludeRegs[i] &&
2453 STRCASECMP(options.excludeRegs[i],"none") == 0)
2456 for ( i = 0 ; options.excludeRegs[i]; i++) {
2457 if (options.excludeRegs[i] &&
2458 STRCASECMP(s,options.excludeRegs[i]) == 0)
2465 /*-----------------------------------------------------------------*/
2466 /* genFunction - generated code for function entry */
2467 /*-----------------------------------------------------------------*/
2468 static void genFunction (iCode *ic)
2473 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2475 labelOffset += (max_key+4);
2479 /* create the function header */
2480 pic14_emitcode(";","-----------------------------------------");
2481 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2482 pic14_emitcode(";","-----------------------------------------");
2484 pic14_emitcode("","%s:",sym->rname);
2485 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2487 ftype = operandType(IC_LEFT(ic));
2489 /* if critical function then turn interrupts off */
2490 if (IFFUNC_ISCRITICAL(ftype))
2491 pic14_emitcode("clr","ea");
2493 /* here we need to generate the equates for the
2494 register bank if required */
2496 if (FUNC_REGBANK(ftype) != rbank) {
2499 rbank = FUNC_REGBANK(ftype);
2500 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2501 if (strcmp(regspic14[i].base,"0") == 0)
2502 pic14_emitcode("","%s = 0x%02x",
2504 8*rbank+regspic14[i].offset);
2506 pic14_emitcode ("","%s = %s + 0x%02x",
2509 8*rbank+regspic14[i].offset);
2514 /* if this is an interrupt service routine then
2515 save acc, b, dpl, dph */
2516 if (IFFUNC_ISISR(sym->type)) {
2518 if (!inExcludeList("acc"))
2519 pic14_emitcode ("push","acc");
2520 if (!inExcludeList("b"))
2521 pic14_emitcode ("push","b");
2522 if (!inExcludeList("dpl"))
2523 pic14_emitcode ("push","dpl");
2524 if (!inExcludeList("dph"))
2525 pic14_emitcode ("push","dph");
2526 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2528 pic14_emitcode ("push", "dpx");
2529 /* Make sure we're using standard DPTR */
2530 pic14_emitcode ("push", "dps");
2531 pic14_emitcode ("mov", "dps, #0x00");
2532 if (options.stack10bit)
2534 /* This ISR could conceivably use DPTR2. Better save it. */
2535 pic14_emitcode ("push", "dpl1");
2536 pic14_emitcode ("push", "dph1");
2537 pic14_emitcode ("push", "dpx1");
2540 /* if this isr has no bank i.e. is going to
2541 run with bank 0 , then we need to save more
2543 if (!FUNC_REGBANK(sym->type)) {
2545 /* if this function does not call any other
2546 function then we can be economical and
2547 save only those registers that are used */
2548 if (! IFFUNC_HASFCALL(sym->type)) {
2551 /* if any registers used */
2552 if (sym->regsUsed) {
2553 /* save the registers used */
2554 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2555 if (bitVectBitValue(sym->regsUsed,i) ||
2556 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2557 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2562 /* this function has a function call cannot
2563 determines register usage so we will have the
2565 saverbank(0,ic,FALSE);
2569 /* if callee-save to be used for this function
2570 then save the registers being used in this function */
2571 if (IFFUNC_CALLEESAVES(sym->type)) {
2574 /* if any registers used */
2575 if (sym->regsUsed) {
2576 /* save the registers used */
2577 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2578 if (bitVectBitValue(sym->regsUsed,i) ||
2579 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2580 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2588 /* set the register bank to the desired value */
2589 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2590 pic14_emitcode("push","psw");
2591 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2594 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2596 if (options.useXstack) {
2597 pic14_emitcode("mov","r0,%s",spname);
2598 pic14_emitcode("mov","a,_bp");
2599 pic14_emitcode("movx","@r0,a");
2600 pic14_emitcode("inc","%s",spname);
2604 /* set up the stack */
2605 pic14_emitcode ("push","_bp"); /* save the callers stack */
2607 pic14_emitcode ("mov","_bp,%s",spname);
2610 /* adjust the stack for the function */
2615 werror(W_STACK_OVERFLOW,sym->name);
2617 if (i > 3 && sym->recvSize < 4) {
2619 pic14_emitcode ("mov","a,sp");
2620 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2621 pic14_emitcode ("mov","sp,a");
2626 pic14_emitcode("inc","sp");
2631 pic14_emitcode ("mov","a,_spx");
2632 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2633 pic14_emitcode ("mov","_spx,a");
2638 /*-----------------------------------------------------------------*/
2639 /* genEndFunction - generates epilogue for functions */
2640 /*-----------------------------------------------------------------*/
2641 static void genEndFunction (iCode *ic)
2643 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2649 pic14_emitcode ("mov","%s,_bp",spname);
2652 /* if use external stack but some variables were
2653 added to the local stack then decrement the
2655 if (options.useXstack && sym->stack) {
2656 pic14_emitcode("mov","a,sp");
2657 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2658 pic14_emitcode("mov","sp,a");
2662 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2663 if (options.useXstack) {
2664 pic14_emitcode("mov","r0,%s",spname);
2665 pic14_emitcode("movx","a,@r0");
2666 pic14_emitcode("mov","_bp,a");
2667 pic14_emitcode("dec","%s",spname);
2671 pic14_emitcode ("pop","_bp");
2675 /* restore the register bank */
2676 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2677 pic14_emitcode ("pop","psw");
2679 if (IFFUNC_ISISR(sym->type)) {
2681 /* now we need to restore the registers */
2682 /* if this isr has no bank i.e. is going to
2683 run with bank 0 , then we need to save more
2685 if (!FUNC_REGBANK(sym->type)) {
2687 /* if this function does not call any other
2688 function then we can be economical and
2689 save only those registers that are used */
2690 if (! IFFUNC_HASFCALL(sym->type)) {
2693 /* if any registers used */
2694 if (sym->regsUsed) {
2695 /* save the registers used */
2696 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2697 if (bitVectBitValue(sym->regsUsed,i) ||
2698 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2699 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2704 /* this function has a function call cannot
2705 determines register usage so we will have the
2707 unsaverbank(0,ic,FALSE);
2711 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2713 if (options.stack10bit)
2715 pic14_emitcode ("pop", "dpx1");
2716 pic14_emitcode ("pop", "dph1");
2717 pic14_emitcode ("pop", "dpl1");
2719 pic14_emitcode ("pop", "dps");
2720 pic14_emitcode ("pop", "dpx");
2722 if (!inExcludeList("dph"))
2723 pic14_emitcode ("pop","dph");
2724 if (!inExcludeList("dpl"))
2725 pic14_emitcode ("pop","dpl");
2726 if (!inExcludeList("b"))
2727 pic14_emitcode ("pop","b");
2728 if (!inExcludeList("acc"))
2729 pic14_emitcode ("pop","acc");
2731 if (IFFUNC_ISCRITICAL(sym->type))
2732 pic14_emitcode("setb","ea");
2734 /* if debug then send end of function */
2735 /* if (options.debug && currFunc) { */
2738 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2739 FileBaseName(ic->filename),currFunc->lastLine,
2740 ic->level,ic->block);
2741 if (IS_STATIC(currFunc->etype))
2742 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2744 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2748 pic14_emitcode ("reti","");
2751 if (IFFUNC_ISCRITICAL(sym->type))
2752 pic14_emitcode("setb","ea");
2754 if (IFFUNC_CALLEESAVES(sym->type)) {
2757 /* if any registers used */
2758 if (sym->regsUsed) {
2759 /* save the registers used */
2760 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2761 if (bitVectBitValue(sym->regsUsed,i) ||
2762 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2763 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2769 /* if debug then send end of function */
2772 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2773 FileBaseName(ic->filename),currFunc->lastLine,
2774 ic->level,ic->block);
2775 if (IS_STATIC(currFunc->etype))
2776 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2778 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2782 pic14_emitcode ("return","");
2783 emitpcodeNULLop(POC_RETURN);
2785 /* Mark the end of a function */
2786 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2791 /*-----------------------------------------------------------------*/
2792 /* genRet - generate code for return statement */
2793 /*-----------------------------------------------------------------*/
2794 static void genRet (iCode *ic)
2796 int size,offset = 0 , pushed = 0;
2798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2799 /* if we have no return value then
2800 just generate the "ret" */
2804 /* we have something to return then
2805 move the return value into place */
2806 aopOp(IC_LEFT(ic),ic,FALSE);
2807 size = AOP_SIZE(IC_LEFT(ic));
2811 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2813 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2815 pic14_emitcode("push","%s",l);
2818 l = aopGet(AOP(IC_LEFT(ic)),offset,
2820 if (strcmp(fReturn[offset],l)) {
2821 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2822 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2823 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2825 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2828 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2829 pic14_emitcode("movwf","%s",fReturn[offset]);
2839 if (strcmp(fReturn[pushed],"a"))
2840 pic14_emitcode("pop",fReturn[pushed]);
2842 pic14_emitcode("pop","acc");
2845 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2848 /* generate a jump to the return label
2849 if the next is not the return statement */
2850 if (!(ic->next && ic->next->op == LABEL &&
2851 IC_LABEL(ic->next) == returnLabel)) {
2853 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2854 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2859 /*-----------------------------------------------------------------*/
2860 /* genLabel - generates a label */
2861 /*-----------------------------------------------------------------*/
2862 static void genLabel (iCode *ic)
2864 /* special case never generate */
2865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2866 if (IC_LABEL(ic) == entryLabel)
2869 emitpLabel(IC_LABEL(ic)->key);
2870 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2873 /*-----------------------------------------------------------------*/
2874 /* genGoto - generates a goto */
2875 /*-----------------------------------------------------------------*/
2877 static void genGoto (iCode *ic)
2879 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2880 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2884 /*-----------------------------------------------------------------*/
2885 /* genMultbits :- multiplication of bits */
2886 /*-----------------------------------------------------------------*/
2887 static void genMultbits (operand *left,
2891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2893 if(!pic14_sameRegs(AOP(result),AOP(right)))
2894 emitpcode(POC_BSF, popGet(AOP(result),0));
2896 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2897 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2898 emitpcode(POC_BCF, popGet(AOP(result),0));
2903 /*-----------------------------------------------------------------*/
2904 /* genMultOneByte : 8 bit multiplication & division */
2905 /*-----------------------------------------------------------------*/
2906 static void genMultOneByte (operand *left,
2910 sym_link *opetype = operandType(result);
2915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2916 DEBUGpic14_AopType(__LINE__,left,right,result);
2918 /* (if two literals, the value is computed before) */
2919 /* if one literal, literal on the right */
2920 if (AOP_TYPE(left) == AOP_LIT){
2926 size = AOP_SIZE(result);
2927 /* signed or unsigned */
2928 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2929 l = aopGet(AOP(left),0,FALSE,FALSE);
2931 pic14_emitcode("mul","ab");
2932 /* if result size = 1, mul signed = mul unsigned */
2933 aopPut(AOP(result),"a",0);
2935 if (SPEC_USIGN(opetype)){
2936 aopPut(AOP(result),"b",1);
2938 /* for filling the MSBs */
2939 pic14_emitcode("clr","a");
2942 pic14_emitcode("mov","a,b");
2944 /* adjust the MSB if left or right neg */
2946 /* if one literal */
2947 if (AOP_TYPE(right) == AOP_LIT){
2948 /* AND literal negative */
2949 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2950 /* adjust MSB (c==0 after mul) */
2951 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2955 lbl = newiTempLabel(NULL);
2956 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2957 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2958 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2959 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2960 lbl = newiTempLabel(NULL);
2961 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2962 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2963 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2966 lbl = newiTempLabel(NULL);
2967 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2968 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2969 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2970 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2971 lbl = newiTempLabel(NULL);
2972 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2973 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2974 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2976 aopPut(AOP(result),"a",1);
2979 pic14_emitcode("rlc","a");
2980 pic14_emitcode("subb","a,acc");
2987 aopPut(AOP(result),"a",offset++);
2991 /*-----------------------------------------------------------------*/
2992 /* genMult - generates code for multiplication */
2993 /*-----------------------------------------------------------------*/
2994 static void genMult (iCode *ic)
2996 operand *left = IC_LEFT(ic);
2997 operand *right = IC_RIGHT(ic);
2998 operand *result= IC_RESULT(ic);
3000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3001 /* assign the amsops */
3002 aopOp (left,ic,FALSE);
3003 aopOp (right,ic,FALSE);
3004 aopOp (result,ic,TRUE);
3006 DEBUGpic14_AopType(__LINE__,left,right,result);
3008 /* special cases first */
3010 if (AOP_TYPE(left) == AOP_CRY &&
3011 AOP_TYPE(right)== AOP_CRY) {
3012 genMultbits(left,right,result);
3016 /* if both are of size == 1 */
3017 if (AOP_SIZE(left) == 1 &&
3018 AOP_SIZE(right) == 1 ) {
3019 genMultOneByte(left,right,result);
3023 /* should have been converted to function call */
3027 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3028 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3029 freeAsmop(result,NULL,ic,TRUE);
3032 /*-----------------------------------------------------------------*/
3033 /* genDivbits :- division of bits */
3034 /*-----------------------------------------------------------------*/
3035 static void genDivbits (operand *left,
3042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3043 /* the result must be bit */
3044 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3045 l = aopGet(AOP(left),0,FALSE,FALSE);
3049 pic14_emitcode("div","ab");
3050 pic14_emitcode("rrc","a");
3051 aopPut(AOP(result),"c",0);
3054 /*-----------------------------------------------------------------*/
3055 /* genDivOneByte : 8 bit division */
3056 /*-----------------------------------------------------------------*/
3057 static void genDivOneByte (operand *left,
3061 sym_link *opetype = operandType(result);
3066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3067 size = AOP_SIZE(result) - 1;
3069 /* signed or unsigned */
3070 if (SPEC_USIGN(opetype)) {
3071 /* unsigned is easy */
3072 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3073 l = aopGet(AOP(left),0,FALSE,FALSE);
3075 pic14_emitcode("div","ab");
3076 aopPut(AOP(result),"a",0);
3078 aopPut(AOP(result),zero,offset++);
3082 /* signed is a little bit more difficult */
3084 /* save the signs of the operands */
3085 l = aopGet(AOP(left),0,FALSE,FALSE);
3087 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3088 pic14_emitcode("push","acc"); /* save it on the stack */
3090 /* now sign adjust for both left & right */
3091 l = aopGet(AOP(right),0,FALSE,FALSE);
3093 lbl = newiTempLabel(NULL);
3094 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3095 pic14_emitcode("cpl","a");
3096 pic14_emitcode("inc","a");
3097 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3098 pic14_emitcode("mov","b,a");
3100 /* sign adjust left side */
3101 l = aopGet(AOP(left),0,FALSE,FALSE);
3104 lbl = newiTempLabel(NULL);
3105 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3106 pic14_emitcode("cpl","a");
3107 pic14_emitcode("inc","a");
3108 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3110 /* now the division */
3111 pic14_emitcode("div","ab");
3112 /* we are interested in the lower order
3114 pic14_emitcode("mov","b,a");
3115 lbl = newiTempLabel(NULL);
3116 pic14_emitcode("pop","acc");
3117 /* if there was an over flow we don't
3118 adjust the sign of the result */
3119 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3120 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3122 pic14_emitcode("clr","a");
3123 pic14_emitcode("subb","a,b");
3124 pic14_emitcode("mov","b,a");
3125 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3127 /* now we are done */
3128 aopPut(AOP(result),"b",0);
3130 pic14_emitcode("mov","c,b.7");
3131 pic14_emitcode("subb","a,acc");
3134 aopPut(AOP(result),"a",offset++);
3138 /*-----------------------------------------------------------------*/
3139 /* genDiv - generates code for division */
3140 /*-----------------------------------------------------------------*/
3141 static void genDiv (iCode *ic)
3143 operand *left = IC_LEFT(ic);
3144 operand *right = IC_RIGHT(ic);
3145 operand *result= IC_RESULT(ic);
3147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3148 /* assign the amsops */
3149 aopOp (left,ic,FALSE);
3150 aopOp (right,ic,FALSE);
3151 aopOp (result,ic,TRUE);
3153 /* special cases first */
3155 if (AOP_TYPE(left) == AOP_CRY &&
3156 AOP_TYPE(right)== AOP_CRY) {
3157 genDivbits(left,right,result);
3161 /* if both are of size == 1 */
3162 if (AOP_SIZE(left) == 1 &&
3163 AOP_SIZE(right) == 1 ) {
3164 genDivOneByte(left,right,result);
3168 /* should have been converted to function call */
3171 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3172 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3173 freeAsmop(result,NULL,ic,TRUE);
3176 /*-----------------------------------------------------------------*/
3177 /* genModbits :- modulus of bits */
3178 /*-----------------------------------------------------------------*/
3179 static void genModbits (operand *left,
3186 /* the result must be bit */
3187 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3188 l = aopGet(AOP(left),0,FALSE,FALSE);
3192 pic14_emitcode("div","ab");
3193 pic14_emitcode("mov","a,b");
3194 pic14_emitcode("rrc","a");
3195 aopPut(AOP(result),"c",0);
3198 /*-----------------------------------------------------------------*/
3199 /* genModOneByte : 8 bit modulus */
3200 /*-----------------------------------------------------------------*/
3201 static void genModOneByte (operand *left,
3205 sym_link *opetype = operandType(result);
3209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3210 /* signed or unsigned */
3211 if (SPEC_USIGN(opetype)) {
3212 /* unsigned is easy */
3213 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3214 l = aopGet(AOP(left),0,FALSE,FALSE);
3216 pic14_emitcode("div","ab");
3217 aopPut(AOP(result),"b",0);
3221 /* signed is a little bit more difficult */
3223 /* save the signs of the operands */
3224 l = aopGet(AOP(left),0,FALSE,FALSE);
3227 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3228 pic14_emitcode("push","acc"); /* save it on the stack */
3230 /* now sign adjust for both left & right */
3231 l = aopGet(AOP(right),0,FALSE,FALSE);
3234 lbl = newiTempLabel(NULL);
3235 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3236 pic14_emitcode("cpl","a");
3237 pic14_emitcode("inc","a");
3238 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3239 pic14_emitcode("mov","b,a");
3241 /* sign adjust left side */
3242 l = aopGet(AOP(left),0,FALSE,FALSE);
3245 lbl = newiTempLabel(NULL);
3246 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3247 pic14_emitcode("cpl","a");
3248 pic14_emitcode("inc","a");
3249 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251 /* now the multiplication */
3252 pic14_emitcode("div","ab");
3253 /* we are interested in the lower order
3255 lbl = newiTempLabel(NULL);
3256 pic14_emitcode("pop","acc");
3257 /* if there was an over flow we don't
3258 adjust the sign of the result */
3259 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3262 pic14_emitcode("clr","a");
3263 pic14_emitcode("subb","a,b");
3264 pic14_emitcode("mov","b,a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3267 /* now we are done */
3268 aopPut(AOP(result),"b",0);
3272 /*-----------------------------------------------------------------*/
3273 /* genMod - generates code for division */
3274 /*-----------------------------------------------------------------*/
3275 static void genMod (iCode *ic)
3277 operand *left = IC_LEFT(ic);
3278 operand *right = IC_RIGHT(ic);
3279 operand *result= IC_RESULT(ic);
3281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3282 /* assign the amsops */
3283 aopOp (left,ic,FALSE);
3284 aopOp (right,ic,FALSE);
3285 aopOp (result,ic,TRUE);
3287 /* special cases first */
3289 if (AOP_TYPE(left) == AOP_CRY &&
3290 AOP_TYPE(right)== AOP_CRY) {
3291 genModbits(left,right,result);
3295 /* if both are of size == 1 */
3296 if (AOP_SIZE(left) == 1 &&
3297 AOP_SIZE(right) == 1 ) {
3298 genModOneByte(left,right,result);
3302 /* should have been converted to function call */
3306 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3307 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3308 freeAsmop(result,NULL,ic,TRUE);
3311 /*-----------------------------------------------------------------*/
3312 /* genIfxJump :- will create a jump depending on the ifx */
3313 /*-----------------------------------------------------------------*/
3315 note: May need to add parameter to indicate when a variable is in bit space.
3317 static void genIfxJump (iCode *ic, char *jval)
3320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3321 /* if true label then we jump if condition
3323 if ( IC_TRUE(ic) ) {
3325 if(strcmp(jval,"a") == 0)
3327 else if (strcmp(jval,"c") == 0)
3330 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3331 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3334 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3335 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3339 /* false label is present */
3340 if(strcmp(jval,"a") == 0)
3342 else if (strcmp(jval,"c") == 0)
3345 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3346 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3349 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3350 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3355 /* mark the icode as generated */
3359 /*-----------------------------------------------------------------*/
3361 /*-----------------------------------------------------------------*/
3362 static void genSkip(iCode *ifx,int status_bit)
3367 if ( IC_TRUE(ifx) ) {
3368 switch(status_bit) {
3383 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3384 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3388 switch(status_bit) {
3402 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3403 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3409 /*-----------------------------------------------------------------*/
3411 /*-----------------------------------------------------------------*/
3412 static void genSkipc(resolvedIfx *rifx)
3422 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3423 rifx->generated = 1;
3426 /*-----------------------------------------------------------------*/
3428 /*-----------------------------------------------------------------*/
3429 static void genSkipz2(resolvedIfx *rifx)
3439 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3440 rifx->generated = 1;
3443 /*-----------------------------------------------------------------*/
3445 /*-----------------------------------------------------------------*/
3446 static void genSkipz(iCode *ifx, int condition)
3457 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3459 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3462 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3464 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3467 /*-----------------------------------------------------------------*/
3469 /*-----------------------------------------------------------------*/
3470 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3476 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3478 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3481 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3482 rifx->generated = 1;
3486 /*-----------------------------------------------------------------*/
3487 /* genChkZeroes :- greater or less than comparison */
3488 /* For each byte in a literal that is zero, inclusive or the */
3489 /* the corresponding byte in the operand with W */
3490 /* returns true if any of the bytes are zero */
3491 /*-----------------------------------------------------------------*/
3492 static int genChkZeroes(operand *op, int lit, int size)
3499 i = (lit >> (size*8)) & 0xff;
3503 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3505 emitpcode(POC_IORFW, popGet(AOP(op),size));
3514 /*-----------------------------------------------------------------*/
3515 /* genCmp :- greater or less than comparison */
3516 /*-----------------------------------------------------------------*/
3517 static void genCmp (operand *left,operand *right,
3518 operand *result, iCode *ifx, int sign)
3520 int size, offset = 0 ;
3521 unsigned long lit = 0L,i = 0;
3522 resolvedIfx rFalseIfx;
3523 // resolvedIfx rTrueIfx;
3525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3527 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3528 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3532 resolveIfx(&rFalseIfx,ifx);
3533 truelbl = newiTempLabel(NULL);
3535 //if(IC_TRUE(ifx) == NULL)
3536 /* if left & right are bit variables */
3537 if (AOP_TYPE(left) == AOP_CRY &&
3538 AOP_TYPE(right) == AOP_CRY ) {
3539 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3540 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3542 /* subtract right from left if at the
3543 end the carry flag is set then we know that
3544 left is greater than right */
3545 size = max(AOP_SIZE(left),AOP_SIZE(right));
3547 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3548 if((size == 1) && !sign &&
3549 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3550 symbol *lbl = newiTempLabel(NULL);
3551 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3552 aopGet(AOP(left),offset,FALSE,FALSE),
3553 aopGet(AOP(right),offset,FALSE,FALSE),
3555 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3558 symbol *lbl = newiTempLabel(NULL);
3560 if(AOP_TYPE(right) == AOP_LIT) {
3562 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3564 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3571 genSkipCond(&rFalseIfx,left,size-1,7);
3573 /* no need to compare to 0...*/
3574 /* NOTE: this is a de-generate compare that most certainly
3575 * creates some dead code. */
3576 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3578 if(ifx) ifx->generated = 1;
3585 //i = (lit >> (size*8)) & 0xff;
3586 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3588 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3590 i = ((0-lit) & 0xff);
3593 /* lit is 0x7f, all signed chars are less than
3594 * this except for 0x7f itself */
3595 emitpcode(POC_XORLW, popGetLit(0x7f));
3596 genSkipz2(&rFalseIfx);
3598 emitpcode(POC_ADDLW, popGetLit(0x80));
3599 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3600 genSkipc(&rFalseIfx);
3604 emitpcode(POC_ADDLW, popGetLit(i));
3605 genSkipc(&rFalseIfx);
3609 if(ifx) ifx->generated = 1;
3613 /* chars are out of the way. now do ints and longs */
3616 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3623 genSkipCond(&rFalseIfx,left,size,7);
3624 if(ifx) ifx->generated = 1;
3629 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3631 //rFalseIfx.condition ^= 1;
3632 //genSkipCond(&rFalseIfx,left,size,7);
3633 //rFalseIfx.condition ^= 1;
3635 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3636 if(rFalseIfx.condition)
3637 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3639 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3641 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3642 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3643 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3646 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3648 if(rFalseIfx.condition) {
3650 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3656 genSkipc(&rFalseIfx);
3657 emitpLabel(truelbl->key);
3658 if(ifx) ifx->generated = 1;
3665 if( (lit & 0xff) == 0) {
3666 /* lower byte is zero */
3667 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3668 i = ((lit >> 8) & 0xff) ^0x80;
3669 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3670 emitpcode(POC_ADDLW, popGetLit( 0x80));
3671 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3672 genSkipc(&rFalseIfx);
3675 if(ifx) ifx->generated = 1;
3680 /* Special cases for signed longs */
3681 if( (lit & 0xffffff) == 0) {
3682 /* lower byte is zero */
3683 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3684 i = ((lit >> 8*3) & 0xff) ^0x80;
3685 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3686 emitpcode(POC_ADDLW, popGetLit( 0x80));
3687 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3688 genSkipc(&rFalseIfx);
3691 if(ifx) ifx->generated = 1;
3699 if(lit & (0x80 << (size*8))) {
3700 /* lit is negative */
3701 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3703 //genSkipCond(&rFalseIfx,left,size,7);
3705 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3707 if(rFalseIfx.condition)
3708 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3710 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3714 /* lit is positive */
3715 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3716 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3717 if(rFalseIfx.condition)
3718 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3720 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3722 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3723 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3724 //rFalseIfx.condition ^= 1;
3725 //genSkipCond(&rFalseIfx,left,size,7);
3726 //rFalseIfx.condition ^= 1;
3730 This works, but is only good for ints.
3731 It also requires a "known zero" register.
3732 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3733 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3734 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3735 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3736 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3737 genSkipc(&rFalseIfx);
3739 emitpLabel(truelbl->key);
3740 if(ifx) ifx->generated = 1;
3744 /* There are no more special cases, so perform a general compare */
3746 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3747 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3751 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3753 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3755 //rFalseIfx.condition ^= 1;
3756 genSkipc(&rFalseIfx);
3758 emitpLabel(truelbl->key);
3760 if(ifx) ifx->generated = 1;
3767 /* sign is out of the way. So now do an unsigned compare */
3768 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3771 //genChkZeroes(left)
3773 /* General case - compare to an unsigned literal on the right.*/
3775 i = (lit >> (size*8)) & 0xff;
3776 emitpcode(POC_MOVLW, popGetLit(i));
3777 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3779 i = (lit >> (size*8)) & 0xff;
3782 emitpcode(POC_MOVLW, popGetLit(i));
3784 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3786 /* this byte of the lit is zero,
3787 *if it's not the last then OR in the variable */
3789 emitpcode(POC_IORFW, popGet(AOP(left),size));
3794 emitpLabel(lbl->key);
3795 //if(emitFinalCheck)
3796 genSkipc(&rFalseIfx);
3798 emitpLabel(truelbl->key);
3800 if(ifx) ifx->generated = 1;
3806 if(AOP_TYPE(left) == AOP_LIT) {
3807 //symbol *lbl = newiTempLabel(NULL);
3809 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3812 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3815 if((lit == 0) && (sign == 0)){
3818 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3820 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3822 //rFalseIfx.condition ^= 1;
3823 genSkipz2(&rFalseIfx);
3824 if(ifx) ifx->generated = 1;
3831 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3832 /* degenerate compare can never be true */
3833 if(rFalseIfx.condition == 0)
3834 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3836 if(ifx) ifx->generated = 1;
3842 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3843 emitpcode(POC_ADDLW, popGetLit(0x80));
3844 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3845 rFalseIfx.condition ^= 1;
3846 genSkipc(&rFalseIfx);
3848 rFalseIfx.condition ^= 1;
3849 genSkipCond(&rFalseIfx,right,0,7);
3854 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3855 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3856 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3857 rFalseIfx.condition ^= 1;
3858 genSkipc(&rFalseIfx);
3860 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3861 genSkipz2(&rFalseIfx);
3865 if(ifx) ifx->generated = 1;
3870 /* Size is greater than 1 */
3880 /* this means lit = 0xffffffff, or -1 */
3883 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
3884 rFalseIfx.condition ^= 1;
3885 genSkipCond(&rFalseIfx,right,size,7);
3886 if(ifx) ifx->generated = 1;
3893 if(rFalseIfx.condition) {
3894 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3895 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3898 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3900 emitpcode(POC_IORFW, popGet(AOP(right),size));
3904 if(rFalseIfx.condition) {
3905 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3906 emitpLabel(truelbl->key);
3908 rFalseIfx.condition ^= 1;
3909 genSkipCond(&rFalseIfx,right,s,7);
3912 if(ifx) ifx->generated = 1;
3917 if(lit & (0x80 << (size*8))) {
3918 /* Lit is less than zero */
3919 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
3920 //rFalseIfx.condition ^= 1;
3921 //genSkipCond(&rFalseIfx,left,size,7);
3922 //rFalseIfx.condition ^= 1;
3923 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3924 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3926 if(rFalseIfx.condition)
3927 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3929 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3933 /* Lit is greater than or equal to zero */
3934 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
3935 //rFalseIfx.condition ^= 1;
3936 //genSkipCond(&rFalseIfx,right,size,7);
3937 //rFalseIfx.condition ^= 1;
3939 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3940 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3942 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3943 if(rFalseIfx.condition)
3944 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3946 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3949 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3950 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3954 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3956 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3958 rFalseIfx.condition ^= 1;
3959 //rFalseIfx.condition = 1;
3960 genSkipc(&rFalseIfx);
3962 emitpLabel(truelbl->key);
3964 if(ifx) ifx->generated = 1;
3968 /* Unsigned compare for sizes greater than 1 */
3971 i = (lit >> (size*8)) & 0xff;
3975 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3976 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3977 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3979 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3981 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3982 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3983 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3990 emitpLabel(lbl->key);
3992 rFalseIfx.condition ^= 1;
3993 genSkipc(&rFalseIfx);
3997 emitpLabel(truelbl->key);
3998 if(ifx) ifx->generated = 1;
4002 /* Compare two variables */
4004 DEBUGpic14_emitcode(";sign","%d",sign);
4008 /* Sigh. thus sucks... */
4010 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4011 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4012 emitpcode(POC_MOVLW, popGetLit(0x80));
4013 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4014 emitpcode(POC_XORFW, popGet(AOP(right),size));
4015 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4017 /* Signed char comparison */
4018 /* Special thanks to Nikolai Golovchenko for this snippet */
4019 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4020 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4021 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4022 emitpcode(POC_XORFW, popGet(AOP(left),0));
4023 emitpcode(POC_XORFW, popGet(AOP(right),0));
4024 emitpcode(POC_ADDLW, popGetLit(0x80));
4026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4027 genSkipc(&rFalseIfx);
4029 if(ifx) ifx->generated = 1;
4035 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4036 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4040 /* The rest of the bytes of a multi-byte compare */
4044 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4047 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4048 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4053 emitpLabel(lbl->key);
4055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4056 genSkipc(&rFalseIfx);
4057 if(ifx) ifx->generated = 1;
4064 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4065 pic14_outBitC(result);
4067 /* if the result is used in the next
4068 ifx conditional branch then generate
4069 code a little differently */
4071 genIfxJump (ifx,"c");
4073 pic14_outBitC(result);
4074 /* leave the result in acc */
4079 /*-----------------------------------------------------------------*/
4080 /* genCmpGt :- greater than comparison */
4081 /*-----------------------------------------------------------------*/
4082 static void genCmpGt (iCode *ic, iCode *ifx)
4084 operand *left, *right, *result;
4085 sym_link *letype , *retype;
4088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4090 right= IC_RIGHT(ic);
4091 result = IC_RESULT(ic);
4093 letype = getSpec(operandType(left));
4094 retype =getSpec(operandType(right));
4095 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4096 /* assign the amsops */
4097 aopOp (left,ic,FALSE);
4098 aopOp (right,ic,FALSE);
4099 aopOp (result,ic,TRUE);
4101 genCmp(right, left, result, ifx, sign);
4103 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4104 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4105 freeAsmop(result,NULL,ic,TRUE);
4108 /*-----------------------------------------------------------------*/
4109 /* genCmpLt - less than comparisons */
4110 /*-----------------------------------------------------------------*/
4111 static void genCmpLt (iCode *ic, iCode *ifx)
4113 operand *left, *right, *result;
4114 sym_link *letype , *retype;
4117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4119 right= IC_RIGHT(ic);
4120 result = IC_RESULT(ic);
4122 letype = getSpec(operandType(left));
4123 retype =getSpec(operandType(right));
4124 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4126 /* assign the amsops */
4127 aopOp (left,ic,FALSE);
4128 aopOp (right,ic,FALSE);
4129 aopOp (result,ic,TRUE);
4131 genCmp(left, right, result, ifx, sign);
4133 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4134 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4135 freeAsmop(result,NULL,ic,TRUE);
4138 /*-----------------------------------------------------------------*/
4139 /* genc16bit2lit - compare a 16 bit value to a literal */
4140 /*-----------------------------------------------------------------*/
4141 static void genc16bit2lit(operand *op, int lit, int offset)
4145 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4146 if( (lit&0xff) == 0)
4151 switch( BYTEofLONG(lit,i)) {
4153 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4156 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4159 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4162 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4163 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4168 switch( BYTEofLONG(lit,i)) {
4170 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4174 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4178 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4181 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4183 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4189 /*-----------------------------------------------------------------*/
4190 /* gencjneshort - compare and jump if not equal */
4191 /*-----------------------------------------------------------------*/
4192 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4194 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4199 unsigned long lit = 0L;
4200 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4201 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4203 resolveIfx(&rIfx,ifx);
4204 lbl = newiTempLabel(NULL);
4207 /* if the left side is a literal or
4208 if the right is in a pointer register and left
4210 if ((AOP_TYPE(left) == AOP_LIT) ||
4211 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4216 if(AOP_TYPE(right) == AOP_LIT)
4217 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4219 /* if the right side is a literal then anything goes */
4220 if (AOP_TYPE(right) == AOP_LIT &&
4221 AOP_TYPE(left) != AOP_DIR ) {
4224 genc16bit2lit(left, lit, 0);
4226 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4231 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4232 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4234 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4238 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4246 /* if the right side is in a register or in direct space or
4247 if the left is a pointer register & right is not */
4248 else if (AOP_TYPE(right) == AOP_REG ||
4249 AOP_TYPE(right) == AOP_DIR ||
4250 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4251 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4254 genc16bit2lit(left, lit, 0);
4256 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4261 if((AOP_TYPE(left) == AOP_DIR) &&
4262 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4264 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4265 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4267 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4269 switch (lit & 0xff) {
4271 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4274 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4275 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4279 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4280 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4284 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4285 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4290 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4293 if(AOP_TYPE(result) == AOP_CRY) {
4294 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4299 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4301 /* fix me. probably need to check result size too */
4302 emitpcode(POC_CLRF,popGet(AOP(result),0));
4307 emitpcode(POC_INCF,popGet(AOP(result),0));
4317 } else if(AOP_TYPE(right) == AOP_REG &&
4318 AOP_TYPE(left) != AOP_DIR){
4321 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4322 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4323 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4328 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4333 /* right is a pointer reg need both a & b */
4335 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4337 pic14_emitcode("mov","b,%s",l);
4338 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4339 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4343 emitpLabel(lbl->key);
4350 /*-----------------------------------------------------------------*/
4351 /* gencjne - compare and jump if not equal */
4352 /*-----------------------------------------------------------------*/
4353 static void gencjne(operand *left, operand *right, iCode *ifx)
4355 symbol *tlbl = newiTempLabel(NULL);
4357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4358 gencjneshort(left, right, lbl);
4360 pic14_emitcode("mov","a,%s",one);
4361 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4362 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4363 pic14_emitcode("clr","a");
4364 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4366 emitpLabel(lbl->key);
4367 emitpLabel(tlbl->key);
4372 /*-----------------------------------------------------------------*/
4373 /* genCmpEq - generates code for equal to */
4374 /*-----------------------------------------------------------------*/
4375 static void genCmpEq (iCode *ic, iCode *ifx)
4377 operand *left, *right, *result;
4378 unsigned long lit = 0L;
4381 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4384 DEBUGpic14_emitcode ("; ifx is non-null","");
4386 DEBUGpic14_emitcode ("; ifx is null","");
4388 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4389 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4390 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4392 size = max(AOP_SIZE(left),AOP_SIZE(right));
4394 DEBUGpic14_AopType(__LINE__,left,right,result);
4396 /* if literal, literal on the right or
4397 if the right is in a pointer register and left
4399 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4400 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4401 operand *tmp = right ;
4407 if(ifx && !AOP_SIZE(result)){
4409 /* if they are both bit variables */
4410 if (AOP_TYPE(left) == AOP_CRY &&
4411 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4412 if(AOP_TYPE(right) == AOP_LIT){
4413 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4415 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4416 pic14_emitcode("cpl","c");
4417 } else if(lit == 1L) {
4418 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4420 pic14_emitcode("clr","c");
4422 /* AOP_TYPE(right) == AOP_CRY */
4424 symbol *lbl = newiTempLabel(NULL);
4425 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4426 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4427 pic14_emitcode("cpl","c");
4428 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4430 /* if true label then we jump if condition
4432 tlbl = newiTempLabel(NULL);
4433 if ( IC_TRUE(ifx) ) {
4434 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4435 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4437 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4438 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4440 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4443 /* They're not both bit variables. Is the right a literal? */
4444 if(AOP_TYPE(right) == AOP_LIT) {
4445 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4450 switch(lit & 0xff) {
4452 if ( IC_TRUE(ifx) ) {
4453 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4455 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4457 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4458 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4462 if ( IC_TRUE(ifx) ) {
4463 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4465 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4467 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4468 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4472 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4474 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4479 /* end of size == 1 */
4483 genc16bit2lit(left,lit,offset);
4486 /* end of size == 2 */
4491 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4492 emitpcode(POC_IORFW,popGet(AOP(left),1));
4493 emitpcode(POC_IORFW,popGet(AOP(left),2));
4494 emitpcode(POC_IORFW,popGet(AOP(left),3));
4498 /* search for patterns that can be optimized */
4500 genc16bit2lit(left,lit,0);
4503 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4505 genc16bit2lit(left,lit,2);
4507 emitpcode(POC_IORFW,popGet(AOP(left),2));
4508 emitpcode(POC_IORFW,popGet(AOP(left),3));
4521 } else if(AOP_TYPE(right) == AOP_CRY ) {
4522 /* we know the left is not a bit, but that the right is */
4523 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4524 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4525 popGet(AOP(right),offset));
4526 emitpcode(POC_XORLW,popGetLit(1));
4528 /* if the two are equal, then W will be 0 and the Z bit is set
4529 * we could test Z now, or go ahead and check the high order bytes if
4530 * the variable we're comparing is larger than a byte. */
4533 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4535 if ( IC_TRUE(ifx) ) {
4537 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4538 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4541 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4542 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4546 /* They're both variables that are larger than bits */
4549 tlbl = newiTempLabel(NULL);
4552 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4553 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4555 if ( IC_TRUE(ifx) ) {
4558 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4559 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4562 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4563 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4567 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4568 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4572 if(s>1 && IC_TRUE(ifx)) {
4573 emitpLabel(tlbl->key);
4574 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4578 /* mark the icode as generated */
4583 /* if they are both bit variables */
4584 if (AOP_TYPE(left) == AOP_CRY &&
4585 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4586 if(AOP_TYPE(right) == AOP_LIT){
4587 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4589 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4590 pic14_emitcode("cpl","c");
4591 } else if(lit == 1L) {
4592 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4594 pic14_emitcode("clr","c");
4596 /* AOP_TYPE(right) == AOP_CRY */
4598 symbol *lbl = newiTempLabel(NULL);
4599 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4600 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4601 pic14_emitcode("cpl","c");
4602 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4605 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4606 pic14_outBitC(result);
4610 genIfxJump (ifx,"c");
4613 /* if the result is used in an arithmetic operation
4614 then put the result in place */
4615 pic14_outBitC(result);
4618 gencjne(left,right,result,ifx);
4621 gencjne(left,right,newiTempLabel(NULL));
4623 if(IC_TRUE(ifx)->key)
4624 gencjne(left,right,IC_TRUE(ifx)->key);
4626 gencjne(left,right,IC_FALSE(ifx)->key);
4630 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4631 aopPut(AOP(result),"a",0);
4636 genIfxJump (ifx,"a");
4640 /* if the result is used in an arithmetic operation
4641 then put the result in place */
4643 if (AOP_TYPE(result) != AOP_CRY)
4644 pic14_outAcc(result);
4646 /* leave the result in acc */
4650 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4651 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4652 freeAsmop(result,NULL,ic,TRUE);
4655 /*-----------------------------------------------------------------*/
4656 /* ifxForOp - returns the icode containing the ifx for operand */
4657 /*-----------------------------------------------------------------*/
4658 static iCode *ifxForOp ( operand *op, iCode *ic )
4660 /* if true symbol then needs to be assigned */
4661 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4662 if (IS_TRUE_SYMOP(op))
4665 /* if this has register type condition and
4666 the next instruction is ifx with the same operand
4667 and live to of the operand is upto the ifx only then */
4669 ic->next->op == IFX &&
4670 IC_COND(ic->next)->key == op->key &&
4671 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4675 ic->next->op == IFX &&
4676 IC_COND(ic->next)->key == op->key) {
4677 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4681 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4683 ic->next->op == IFX)
4684 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4687 ic->next->op == IFX &&
4688 IC_COND(ic->next)->key == op->key) {
4689 DEBUGpic14_emitcode ("; "," key is okay");
4690 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4691 OP_SYMBOL(op)->liveTo,
4698 /*-----------------------------------------------------------------*/
4699 /* genAndOp - for && operation */
4700 /*-----------------------------------------------------------------*/
4701 static void genAndOp (iCode *ic)
4703 operand *left,*right, *result;
4706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4707 /* note here that && operations that are in an
4708 if statement are taken away by backPatchLabels
4709 only those used in arthmetic operations remain */
4710 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4711 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4712 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4714 /* if both are bit variables */
4715 if (AOP_TYPE(left) == AOP_CRY &&
4716 AOP_TYPE(right) == AOP_CRY ) {
4717 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4718 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4719 pic14_outBitC(result);
4721 tlbl = newiTempLabel(NULL);
4722 pic14_toBoolean(left);
4723 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4724 pic14_toBoolean(right);
4725 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4726 pic14_outBitAcc(result);
4729 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4730 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4731 freeAsmop(result,NULL,ic,TRUE);
4735 /*-----------------------------------------------------------------*/
4736 /* genOrOp - for || operation */
4737 /*-----------------------------------------------------------------*/
4740 modified this code, but it doesn't appear to ever get called
4743 static void genOrOp (iCode *ic)
4745 operand *left,*right, *result;
4748 /* note here that || operations that are in an
4749 if statement are taken away by backPatchLabels
4750 only those used in arthmetic operations remain */
4751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4752 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4753 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4754 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4756 DEBUGpic14_AopType(__LINE__,left,right,result);
4758 /* if both are bit variables */
4759 if (AOP_TYPE(left) == AOP_CRY &&
4760 AOP_TYPE(right) == AOP_CRY ) {
4761 pic14_emitcode("clrc","");
4762 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4763 AOP(left)->aopu.aop_dir,
4764 AOP(left)->aopu.aop_dir);
4765 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4766 AOP(right)->aopu.aop_dir,
4767 AOP(right)->aopu.aop_dir);
4768 pic14_emitcode("setc","");
4771 tlbl = newiTempLabel(NULL);
4772 pic14_toBoolean(left);
4774 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4775 pic14_toBoolean(right);
4776 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4778 pic14_outBitAcc(result);
4781 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4782 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4783 freeAsmop(result,NULL,ic,TRUE);
4786 /*-----------------------------------------------------------------*/
4787 /* isLiteralBit - test if lit == 2^n */
4788 /*-----------------------------------------------------------------*/
4789 static int isLiteralBit(unsigned long lit)
4791 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4792 0x100L,0x200L,0x400L,0x800L,
4793 0x1000L,0x2000L,0x4000L,0x8000L,
4794 0x10000L,0x20000L,0x40000L,0x80000L,
4795 0x100000L,0x200000L,0x400000L,0x800000L,
4796 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4797 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4801 for(idx = 0; idx < 32; idx++)
4807 /*-----------------------------------------------------------------*/
4808 /* continueIfTrue - */
4809 /*-----------------------------------------------------------------*/
4810 static void continueIfTrue (iCode *ic)
4812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4814 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4818 /*-----------------------------------------------------------------*/
4820 /*-----------------------------------------------------------------*/
4821 static void jumpIfTrue (iCode *ic)
4823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4825 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4829 /*-----------------------------------------------------------------*/
4830 /* jmpTrueOrFalse - */
4831 /*-----------------------------------------------------------------*/
4832 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4834 // ugly but optimized by peephole
4835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4837 symbol *nlbl = newiTempLabel(NULL);
4838 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4839 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4840 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4841 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4844 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4845 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4850 /*-----------------------------------------------------------------*/
4851 /* genAnd - code for and */
4852 /*-----------------------------------------------------------------*/
4853 static void genAnd (iCode *ic, iCode *ifx)
4855 operand *left, *right, *result;
4857 unsigned long lit = 0L;
4862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4863 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4864 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4865 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4867 resolveIfx(&rIfx,ifx);
4869 /* if left is a literal & right is not then exchange them */
4870 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4871 AOP_NEEDSACC(left)) {
4872 operand *tmp = right ;
4877 /* if result = right then exchange them */
4878 if(pic14_sameRegs(AOP(result),AOP(right))){
4879 operand *tmp = right ;
4884 /* if right is bit then exchange them */
4885 if (AOP_TYPE(right) == AOP_CRY &&
4886 AOP_TYPE(left) != AOP_CRY){
4887 operand *tmp = right ;
4891 if(AOP_TYPE(right) == AOP_LIT)
4892 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4894 size = AOP_SIZE(result);
4896 DEBUGpic14_AopType(__LINE__,left,right,result);
4899 // result = bit & yy;
4900 if (AOP_TYPE(left) == AOP_CRY){
4901 // c = bit & literal;
4902 if(AOP_TYPE(right) == AOP_LIT){
4904 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4907 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4910 if(size && (AOP_TYPE(result) == AOP_CRY)){
4911 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4914 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4918 pic14_emitcode("clr","c");
4921 if (AOP_TYPE(right) == AOP_CRY){
4923 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4924 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4927 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4929 pic14_emitcode("rrc","a");
4930 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4936 pic14_outBitC(result);
4938 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4939 genIfxJump(ifx, "c");
4943 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4944 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4945 if((AOP_TYPE(right) == AOP_LIT) &&
4946 (AOP_TYPE(result) == AOP_CRY) &&
4947 (AOP_TYPE(left) != AOP_CRY)){
4948 int posbit = isLiteralBit(lit);
4952 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4955 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4961 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4962 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4964 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4965 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4968 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4969 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4970 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4977 symbol *tlbl = newiTempLabel(NULL);
4978 int sizel = AOP_SIZE(left);
4980 pic14_emitcode("setb","c");
4982 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4983 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4985 if((posbit = isLiteralBit(bytelit)) != 0)
4986 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4988 if(bytelit != 0x0FFL)
4989 pic14_emitcode("anl","a,%s",
4990 aopGet(AOP(right),offset,FALSE,TRUE));
4991 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4996 // bit = left & literal
4998 pic14_emitcode("clr","c");
4999 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5001 // if(left & literal)
5004 jmpTrueOrFalse(ifx, tlbl);
5008 pic14_outBitC(result);
5012 /* if left is same as result */
5013 if(pic14_sameRegs(AOP(result),AOP(left))){
5015 for(;size--; offset++,lit>>=8) {
5016 if(AOP_TYPE(right) == AOP_LIT){
5017 switch(lit & 0xff) {
5019 /* and'ing with 0 has clears the result */
5020 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5021 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5024 /* and'ing with 0xff is a nop when the result and left are the same */
5029 int p = my_powof2( (~lit) & 0xff );
5031 /* only one bit is set in the literal, so use a bcf instruction */
5032 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5033 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5036 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5037 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5038 if(know_W != (lit&0xff))
5039 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5041 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5046 if (AOP_TYPE(left) == AOP_ACC) {
5047 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5049 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5050 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5057 // left & result in different registers
5058 if(AOP_TYPE(result) == AOP_CRY){
5060 // if(size), result in bit
5061 // if(!size && ifx), conditional oper: if(left & right)
5062 symbol *tlbl = newiTempLabel(NULL);
5063 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5065 pic14_emitcode("setb","c");
5067 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5068 pic14_emitcode("anl","a,%s",
5069 aopGet(AOP(left),offset,FALSE,FALSE));
5070 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5075 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5076 pic14_outBitC(result);
5078 jmpTrueOrFalse(ifx, tlbl);
5080 for(;(size--);offset++) {
5082 // result = left & right
5083 if(AOP_TYPE(right) == AOP_LIT){
5084 int t = (lit >> (offset*8)) & 0x0FFL;
5087 pic14_emitcode("clrf","%s",
5088 aopGet(AOP(result),offset,FALSE,FALSE));
5089 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5092 pic14_emitcode("movf","%s,w",
5093 aopGet(AOP(left),offset,FALSE,FALSE));
5094 pic14_emitcode("movwf","%s",
5095 aopGet(AOP(result),offset,FALSE,FALSE));
5096 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5097 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5100 pic14_emitcode("movlw","0x%x",t);
5101 pic14_emitcode("andwf","%s,w",
5102 aopGet(AOP(left),offset,FALSE,FALSE));
5103 pic14_emitcode("movwf","%s",
5104 aopGet(AOP(result),offset,FALSE,FALSE));
5106 emitpcode(POC_MOVLW, popGetLit(t));
5107 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5108 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5113 if (AOP_TYPE(left) == AOP_ACC) {
5114 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5115 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5117 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5118 pic14_emitcode("andwf","%s,w",
5119 aopGet(AOP(left),offset,FALSE,FALSE));
5120 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5121 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5123 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5124 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5130 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5131 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5132 freeAsmop(result,NULL,ic,TRUE);
5135 /*-----------------------------------------------------------------*/
5136 /* genOr - code for or */
5137 /*-----------------------------------------------------------------*/
5138 static void genOr (iCode *ic, iCode *ifx)
5140 operand *left, *right, *result;
5142 unsigned long lit = 0L;
5144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5146 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5147 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5148 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5150 DEBUGpic14_AopType(__LINE__,left,right,result);
5152 /* if left is a literal & right is not then exchange them */
5153 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5154 AOP_NEEDSACC(left)) {
5155 operand *tmp = right ;
5160 /* if result = right then exchange them */
5161 if(pic14_sameRegs(AOP(result),AOP(right))){
5162 operand *tmp = right ;
5167 /* if right is bit then exchange them */
5168 if (AOP_TYPE(right) == AOP_CRY &&
5169 AOP_TYPE(left) != AOP_CRY){
5170 operand *tmp = right ;
5175 DEBUGpic14_AopType(__LINE__,left,right,result);
5177 if(AOP_TYPE(right) == AOP_LIT)
5178 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5180 size = AOP_SIZE(result);
5184 if (AOP_TYPE(left) == AOP_CRY){
5185 if(AOP_TYPE(right) == AOP_LIT){
5186 // c = bit & literal;
5188 // lit != 0 => result = 1
5189 if(AOP_TYPE(result) == AOP_CRY){
5191 emitpcode(POC_BSF, popGet(AOP(result),0));
5192 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5193 // AOP(result)->aopu.aop_dir,
5194 // AOP(result)->aopu.aop_dir);
5196 continueIfTrue(ifx);
5200 // lit == 0 => result = left
5201 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5203 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5206 if (AOP_TYPE(right) == AOP_CRY){
5207 if(pic14_sameRegs(AOP(result),AOP(left))){
5209 emitpcode(POC_BCF, popGet(AOP(result),0));
5210 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5211 emitpcode(POC_BSF, popGet(AOP(result),0));
5213 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5214 AOP(result)->aopu.aop_dir,
5215 AOP(result)->aopu.aop_dir);
5216 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5217 AOP(right)->aopu.aop_dir,
5218 AOP(right)->aopu.aop_dir);
5219 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5220 AOP(result)->aopu.aop_dir,
5221 AOP(result)->aopu.aop_dir);
5223 if( AOP_TYPE(result) == AOP_ACC) {
5224 emitpcode(POC_MOVLW, popGetLit(0));
5225 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5226 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5227 emitpcode(POC_MOVLW, popGetLit(1));
5231 emitpcode(POC_BCF, popGet(AOP(result),0));
5232 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5233 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5234 emitpcode(POC_BSF, popGet(AOP(result),0));
5236 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5237 AOP(result)->aopu.aop_dir,
5238 AOP(result)->aopu.aop_dir);
5239 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5240 AOP(right)->aopu.aop_dir,
5241 AOP(right)->aopu.aop_dir);
5242 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5243 AOP(left)->aopu.aop_dir,
5244 AOP(left)->aopu.aop_dir);
5245 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5246 AOP(result)->aopu.aop_dir,
5247 AOP(result)->aopu.aop_dir);
5252 symbol *tlbl = newiTempLabel(NULL);
5253 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5256 emitpcode(POC_BCF, popGet(AOP(result),0));
5257 if( AOP_TYPE(right) == AOP_ACC) {
5258 emitpcode(POC_IORLW, popGetLit(0));
5260 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5261 emitpcode(POC_BSF, popGet(AOP(result),0));
5266 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5267 pic14_emitcode(";XXX setb","c");
5268 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5269 AOP(left)->aopu.aop_dir,tlbl->key+100);
5270 pic14_toBoolean(right);
5271 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5272 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5273 jmpTrueOrFalse(ifx, tlbl);
5277 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5284 pic14_outBitC(result);
5286 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5287 genIfxJump(ifx, "c");
5291 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5292 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5293 if((AOP_TYPE(right) == AOP_LIT) &&
5294 (AOP_TYPE(result) == AOP_CRY) &&
5295 (AOP_TYPE(left) != AOP_CRY)){
5297 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5300 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5302 continueIfTrue(ifx);
5305 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5306 // lit = 0, result = boolean(left)
5308 pic14_emitcode(";XXX setb","c");
5309 pic14_toBoolean(right);
5311 symbol *tlbl = newiTempLabel(NULL);
5312 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5314 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5316 genIfxJump (ifx,"a");
5320 pic14_outBitC(result);
5324 /* if left is same as result */
5325 if(pic14_sameRegs(AOP(result),AOP(left))){
5327 for(;size--; offset++,lit>>=8) {
5328 if(AOP_TYPE(right) == AOP_LIT){
5329 if((lit & 0xff) == 0)
5330 /* or'ing with 0 has no effect */
5333 int p = my_powof2(lit & 0xff);
5335 /* only one bit is set in the literal, so use a bsf instruction */
5337 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5339 if(know_W != (lit & 0xff))
5340 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5341 know_W = lit & 0xff;
5342 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5347 if (AOP_TYPE(left) == AOP_ACC) {
5348 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5349 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5351 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5352 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5354 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5355 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5361 // left & result in different registers
5362 if(AOP_TYPE(result) == AOP_CRY){
5364 // if(size), result in bit
5365 // if(!size && ifx), conditional oper: if(left | right)
5366 symbol *tlbl = newiTempLabel(NULL);
5367 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5368 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5372 pic14_emitcode(";XXX setb","c");
5374 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5375 pic14_emitcode(";XXX orl","a,%s",
5376 aopGet(AOP(left),offset,FALSE,FALSE));
5377 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5382 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5383 pic14_outBitC(result);
5385 jmpTrueOrFalse(ifx, tlbl);
5386 } else for(;(size--);offset++){
5388 // result = left & right
5389 if(AOP_TYPE(right) == AOP_LIT){
5390 int t = (lit >> (offset*8)) & 0x0FFL;
5393 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5394 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5396 pic14_emitcode("movf","%s,w",
5397 aopGet(AOP(left),offset,FALSE,FALSE));
5398 pic14_emitcode("movwf","%s",
5399 aopGet(AOP(result),offset,FALSE,FALSE));
5402 emitpcode(POC_MOVLW, popGetLit(t));
5403 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5404 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5406 pic14_emitcode("movlw","0x%x",t);
5407 pic14_emitcode("iorwf","%s,w",
5408 aopGet(AOP(left),offset,FALSE,FALSE));
5409 pic14_emitcode("movwf","%s",
5410 aopGet(AOP(result),offset,FALSE,FALSE));
5416 // faster than result <- left, anl result,right
5417 // and better if result is SFR
5418 if (AOP_TYPE(left) == AOP_ACC) {
5419 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5420 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5422 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5423 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5425 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5426 pic14_emitcode("iorwf","%s,w",
5427 aopGet(AOP(left),offset,FALSE,FALSE));
5429 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5430 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5435 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5436 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5437 freeAsmop(result,NULL,ic,TRUE);
5440 /*-----------------------------------------------------------------*/
5441 /* genXor - code for xclusive or */
5442 /*-----------------------------------------------------------------*/
5443 static void genXor (iCode *ic, iCode *ifx)
5445 operand *left, *right, *result;
5447 unsigned long lit = 0L;
5449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5451 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5452 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5453 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5455 /* if left is a literal & right is not ||
5456 if left needs acc & right does not */
5457 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5458 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5459 operand *tmp = right ;
5464 /* if result = right then exchange them */
5465 if(pic14_sameRegs(AOP(result),AOP(right))){
5466 operand *tmp = right ;
5471 /* if right is bit then exchange them */
5472 if (AOP_TYPE(right) == AOP_CRY &&
5473 AOP_TYPE(left) != AOP_CRY){
5474 operand *tmp = right ;
5478 if(AOP_TYPE(right) == AOP_LIT)
5479 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5481 size = AOP_SIZE(result);
5485 if (AOP_TYPE(left) == AOP_CRY){
5486 if(AOP_TYPE(right) == AOP_LIT){
5487 // c = bit & literal;
5489 // lit>>1 != 0 => result = 1
5490 if(AOP_TYPE(result) == AOP_CRY){
5492 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5494 continueIfTrue(ifx);
5497 pic14_emitcode("setb","c");
5501 // lit == 0, result = left
5502 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5504 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5506 // lit == 1, result = not(left)
5507 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5508 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5511 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5512 pic14_emitcode("cpl","c");
5519 symbol *tlbl = newiTempLabel(NULL);
5520 if (AOP_TYPE(right) == AOP_CRY){
5522 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5525 int sizer = AOP_SIZE(right);
5527 // if val>>1 != 0, result = 1
5528 pic14_emitcode("setb","c");
5530 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5532 // test the msb of the lsb
5533 pic14_emitcode("anl","a,#0xfe");
5534 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5538 pic14_emitcode("rrc","a");
5540 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5541 pic14_emitcode("cpl","c");
5542 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5547 pic14_outBitC(result);
5549 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5550 genIfxJump(ifx, "c");
5554 if(pic14_sameRegs(AOP(result),AOP(left))){
5555 /* if left is same as result */
5556 for(;size--; offset++) {
5557 if(AOP_TYPE(right) == AOP_LIT){
5558 int t = (lit >> (offset*8)) & 0x0FFL;
5562 if (IS_AOP_PREG(left)) {
5563 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5564 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5565 aopPut(AOP(result),"a",offset);
5567 emitpcode(POC_MOVLW, popGetLit(t));
5568 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5569 pic14_emitcode("xrl","%s,%s",
5570 aopGet(AOP(left),offset,FALSE,TRUE),
5571 aopGet(AOP(right),offset,FALSE,FALSE));
5574 if (AOP_TYPE(left) == AOP_ACC)
5575 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5577 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5578 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5580 if (IS_AOP_PREG(left)) {
5581 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5582 aopPut(AOP(result),"a",offset);
5584 pic14_emitcode("xrl","%s,a",
5585 aopGet(AOP(left),offset,FALSE,TRUE));
5591 // left & result in different registers
5592 if(AOP_TYPE(result) == AOP_CRY){
5594 // if(size), result in bit
5595 // if(!size && ifx), conditional oper: if(left ^ right)
5596 symbol *tlbl = newiTempLabel(NULL);
5597 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5599 pic14_emitcode("setb","c");
5601 if((AOP_TYPE(right) == AOP_LIT) &&
5602 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5603 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5605 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5606 pic14_emitcode("xrl","a,%s",
5607 aopGet(AOP(left),offset,FALSE,FALSE));
5609 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5614 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5615 pic14_outBitC(result);
5617 jmpTrueOrFalse(ifx, tlbl);
5618 } else for(;(size--);offset++){
5620 // result = left & right
5621 if(AOP_TYPE(right) == AOP_LIT){
5622 int t = (lit >> (offset*8)) & 0x0FFL;
5625 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5626 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5627 pic14_emitcode("movf","%s,w",
5628 aopGet(AOP(left),offset,FALSE,FALSE));
5629 pic14_emitcode("movwf","%s",
5630 aopGet(AOP(result),offset,FALSE,FALSE));
5633 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5634 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5635 pic14_emitcode("comf","%s,w",
5636 aopGet(AOP(left),offset,FALSE,FALSE));
5637 pic14_emitcode("movwf","%s",
5638 aopGet(AOP(result),offset,FALSE,FALSE));
5641 emitpcode(POC_MOVLW, popGetLit(t));
5642 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5643 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5644 pic14_emitcode("movlw","0x%x",t);
5645 pic14_emitcode("xorwf","%s,w",
5646 aopGet(AOP(left),offset,FALSE,FALSE));
5647 pic14_emitcode("movwf","%s",
5648 aopGet(AOP(result),offset,FALSE,FALSE));
5654 // faster than result <- left, anl result,right
5655 // and better if result is SFR
5656 if (AOP_TYPE(left) == AOP_ACC) {
5657 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5658 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5660 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5661 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5662 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5663 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5665 if ( AOP_TYPE(result) != AOP_ACC){
5666 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5667 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5673 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5674 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5675 freeAsmop(result,NULL,ic,TRUE);
5678 /*-----------------------------------------------------------------*/
5679 /* genInline - write the inline code out */
5680 /*-----------------------------------------------------------------*/
5681 static void genInline (iCode *ic)
5683 char *buffer, *bp, *bp1;
5685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5687 _G.inLine += (!options.asmpeep);
5689 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5690 strcpy(buffer,IC_INLINE(ic));
5692 /* emit each line as a code */
5696 pic14_emitcode(bp1,"");
5703 pic14_emitcode(bp1,"");
5710 pic14_emitcode(bp1,"");
5711 /* pic14_emitcode("",buffer); */
5712 _G.inLine -= (!options.asmpeep);
5715 /*-----------------------------------------------------------------*/
5716 /* genRRC - rotate right with carry */
5717 /*-----------------------------------------------------------------*/
5718 static void genRRC (iCode *ic)
5720 operand *left , *result ;
5721 int size, offset = 0, same;
5723 /* rotate right with carry */
5725 result=IC_RESULT(ic);
5726 aopOp (left,ic,FALSE);
5727 aopOp (result,ic,FALSE);
5729 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5731 same = pic14_sameRegs(AOP(result),AOP(left));
5733 size = AOP_SIZE(result);
5735 /* get the lsb and put it into the carry */
5736 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5743 emitpcode(POC_RRF, popGet(AOP(left),offset));
5745 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5746 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5752 freeAsmop(left,NULL,ic,TRUE);
5753 freeAsmop(result,NULL,ic,TRUE);
5756 /*-----------------------------------------------------------------*/
5757 /* genRLC - generate code for rotate left with carry */
5758 /*-----------------------------------------------------------------*/
5759 static void genRLC (iCode *ic)
5761 operand *left , *result ;
5762 int size, offset = 0;
5765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5766 /* rotate right with carry */
5768 result=IC_RESULT(ic);
5769 aopOp (left,ic,FALSE);
5770 aopOp (result,ic,FALSE);
5772 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5774 same = pic14_sameRegs(AOP(result),AOP(left));
5776 /* move it to the result */
5777 size = AOP_SIZE(result);
5779 /* get the msb and put it into the carry */
5780 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5787 emitpcode(POC_RLF, popGet(AOP(left),offset));
5789 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5790 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5797 freeAsmop(left,NULL,ic,TRUE);
5798 freeAsmop(result,NULL,ic,TRUE);
5801 /*-----------------------------------------------------------------*/
5802 /* genGetHbit - generates code get highest order bit */
5803 /*-----------------------------------------------------------------*/
5804 static void genGetHbit (iCode *ic)
5806 operand *left, *result;
5808 result=IC_RESULT(ic);
5809 aopOp (left,ic,FALSE);
5810 aopOp (result,ic,FALSE);
5812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5813 /* get the highest order byte into a */
5814 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5815 if(AOP_TYPE(result) == AOP_CRY){
5816 pic14_emitcode("rlc","a");
5817 pic14_outBitC(result);
5820 pic14_emitcode("rl","a");
5821 pic14_emitcode("anl","a,#0x01");
5822 pic14_outAcc(result);
5826 freeAsmop(left,NULL,ic,TRUE);
5827 freeAsmop(result,NULL,ic,TRUE);
5830 /*-----------------------------------------------------------------*/
5831 /* AccRol - rotate left accumulator by known count */
5832 /*-----------------------------------------------------------------*/
5833 static void AccRol (int shCount)
5835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5836 shCount &= 0x0007; // shCount : 0..7
5841 pic14_emitcode("rl","a");
5844 pic14_emitcode("rl","a");
5845 pic14_emitcode("rl","a");
5848 pic14_emitcode("swap","a");
5849 pic14_emitcode("rr","a");
5852 pic14_emitcode("swap","a");
5855 pic14_emitcode("swap","a");
5856 pic14_emitcode("rl","a");
5859 pic14_emitcode("rr","a");
5860 pic14_emitcode("rr","a");
5863 pic14_emitcode("rr","a");
5868 /*-----------------------------------------------------------------*/
5869 /* AccLsh - left shift accumulator by known count */
5870 /*-----------------------------------------------------------------*/
5871 static void AccLsh (int shCount)
5873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5876 pic14_emitcode("add","a,acc");
5879 pic14_emitcode("add","a,acc");
5880 pic14_emitcode("add","a,acc");
5882 /* rotate left accumulator */
5884 /* and kill the lower order bits */
5885 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5890 /*-----------------------------------------------------------------*/
5891 /* AccRsh - right shift accumulator by known count */
5892 /*-----------------------------------------------------------------*/
5893 static void AccRsh (int shCount)
5895 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5899 pic14_emitcode("rrc","a");
5901 /* rotate right accumulator */
5902 AccRol(8 - shCount);
5903 /* and kill the higher order bits */
5904 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5910 /*-----------------------------------------------------------------*/
5911 /* AccSRsh - signed right shift accumulator by known count */
5912 /*-----------------------------------------------------------------*/
5913 static void AccSRsh (int shCount)
5916 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5919 pic14_emitcode("mov","c,acc.7");
5920 pic14_emitcode("rrc","a");
5921 } else if(shCount == 2){
5922 pic14_emitcode("mov","c,acc.7");
5923 pic14_emitcode("rrc","a");
5924 pic14_emitcode("mov","c,acc.7");
5925 pic14_emitcode("rrc","a");
5927 tlbl = newiTempLabel(NULL);
5928 /* rotate right accumulator */
5929 AccRol(8 - shCount);
5930 /* and kill the higher order bits */
5931 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5932 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5933 pic14_emitcode("orl","a,#0x%02x",
5934 (unsigned char)~SRMask[shCount]);
5935 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5940 /*-----------------------------------------------------------------*/
5941 /* shiftR1Left2Result - shift right one byte from left to result */
5942 /*-----------------------------------------------------------------*/
5943 static void shiftR1Left2ResultSigned (operand *left, int offl,
5944 operand *result, int offr,
5949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5951 same = (left == result) || (AOP(left) == AOP(result));
5955 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5957 emitpcode(POC_RRF, popGet(AOP(result),offr));
5959 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5960 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5970 /*-----------------------------------------------------------------*/
5971 /* shiftR1Left2Result - shift right one byte from left to result */
5972 /*-----------------------------------------------------------------*/
5973 static void shiftR1Left2Result (operand *left, int offl,
5974 operand *result, int offr,
5975 int shCount, int sign)
5979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5981 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5983 /* Copy the msb into the carry if signed. */
5985 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5995 emitpcode(POC_RRF, popGet(AOP(result),offr));
5997 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5998 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6004 emitpcode(POC_RRF, popGet(AOP(result),offr));
6006 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6007 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6010 emitpcode(POC_RRF, popGet(AOP(result),offr));
6015 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6017 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6018 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6021 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6022 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6023 emitpcode(POC_ANDLW, popGetLit(0x1f));
6024 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6028 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6029 emitpcode(POC_ANDLW, popGetLit(0x0f));
6030 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6034 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6035 emitpcode(POC_ANDLW, popGetLit(0x0f));
6036 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6038 emitpcode(POC_RRF, popGet(AOP(result),offr));
6043 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6044 emitpcode(POC_ANDLW, popGetLit(0x80));
6045 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6046 emitpcode(POC_RLF, popGet(AOP(result),offr));
6047 emitpcode(POC_RLF, popGet(AOP(result),offr));
6052 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6053 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6054 emitpcode(POC_RLF, popGet(AOP(result),offr));
6065 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6067 /* shift right accumulator */
6072 aopPut(AOP(result),"a",offr);
6076 /*-----------------------------------------------------------------*/
6077 /* shiftL1Left2Result - shift left one byte from left to result */
6078 /*-----------------------------------------------------------------*/
6079 static void shiftL1Left2Result (operand *left, int offl,
6080 operand *result, int offr, int shCount)
6085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6087 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6088 DEBUGpic14_emitcode ("; ***","same = %d",same);
6089 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6091 /* shift left accumulator */
6092 //AccLsh(shCount); // don't comment out just yet...
6093 // aopPut(AOP(result),"a",offr);
6097 /* Shift left 1 bit position */
6098 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6100 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6102 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6103 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6107 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6108 emitpcode(POC_ANDLW,popGetLit(0x7e));
6109 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6110 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6113 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6114 emitpcode(POC_ANDLW,popGetLit(0x3e));
6115 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6116 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6117 emitpcode(POC_RLF, popGet(AOP(result),offr));
6120 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6121 emitpcode(POC_ANDLW, popGetLit(0xf0));
6122 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6125 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6126 emitpcode(POC_ANDLW, popGetLit(0xf0));
6127 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6128 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6131 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6132 emitpcode(POC_ANDLW, popGetLit(0x30));
6133 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6134 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6135 emitpcode(POC_RLF, popGet(AOP(result),offr));
6138 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6139 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6140 emitpcode(POC_RRF, popGet(AOP(result),offr));
6144 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6149 /*-----------------------------------------------------------------*/
6150 /* movLeft2Result - move byte from left to result */
6151 /*-----------------------------------------------------------------*/
6152 static void movLeft2Result (operand *left, int offl,
6153 operand *result, int offr, int sign)
6156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6157 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6158 l = aopGet(AOP(left),offl,FALSE,FALSE);
6160 if (*l == '@' && (IS_AOP_PREG(result))) {
6161 pic14_emitcode("mov","a,%s",l);
6162 aopPut(AOP(result),"a",offr);
6165 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6166 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6168 //aopPut(AOP(result),l,offr);
6170 /* MSB sign in acc.7 ! */
6171 if(pic14_getDataSize(left) == offl+1){
6172 pic14_emitcode("mov","a,%s",l);
6173 aopPut(AOP(result),"a",offr);
6180 /*-----------------------------------------------------------------*/
6181 /* shiftL2Left2Result - shift left two bytes from left to result */
6182 /*-----------------------------------------------------------------*/
6183 static void shiftL2Left2Result (operand *left, int offl,
6184 operand *result, int offr, int shCount)
6188 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6190 if(pic14_sameRegs(AOP(result), AOP(left))) {
6198 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6199 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6200 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6204 emitpcode(POC_RLF, popGet(AOP(result),offr));
6205 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6211 emitpcode(POC_MOVLW, popGetLit(0x0f));
6212 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6213 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6214 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6215 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6216 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6217 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6219 emitpcode(POC_RLF, popGet(AOP(result),offr));
6220 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6224 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6225 emitpcode(POC_RRF, popGet(AOP(result),offr));
6226 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6227 emitpcode(POC_RRF, popGet(AOP(result),offr));
6228 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6229 emitpcode(POC_ANDLW,popGetLit(0xc0));
6230 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6231 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6232 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6233 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6236 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6237 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6238 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6239 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6240 emitpcode(POC_RRF, popGet(AOP(result),offr));
6250 /* note, use a mov/add for the shift since the mov has a
6251 chance of getting optimized out */
6252 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6253 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6254 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6255 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6256 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6260 emitpcode(POC_RLF, popGet(AOP(result),offr));
6261 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6267 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6268 emitpcode(POC_ANDLW, popGetLit(0xF0));
6269 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6270 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6271 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6272 emitpcode(POC_ANDLW, popGetLit(0xF0));
6273 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6274 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6278 emitpcode(POC_RLF, popGet(AOP(result),offr));
6279 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6283 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6284 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6285 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6286 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6288 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6289 emitpcode(POC_RRF, popGet(AOP(result),offr));
6290 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6291 emitpcode(POC_ANDLW,popGetLit(0xc0));
6292 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6293 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6294 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6295 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6298 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6299 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6300 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6301 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6302 emitpcode(POC_RRF, popGet(AOP(result),offr));
6307 /*-----------------------------------------------------------------*/
6308 /* shiftR2Left2Result - shift right two bytes from left to result */
6309 /*-----------------------------------------------------------------*/
6310 static void shiftR2Left2Result (operand *left, int offl,
6311 operand *result, int offr,
6312 int shCount, int sign)
6316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6317 same = pic14_sameRegs(AOP(result), AOP(left));
6319 if(same && ((offl + MSB16) == offr)){
6321 /* don't crash result[offr] */
6322 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6323 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6325 movLeft2Result(left,offl, result, offr, 0);
6326 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6328 /* a:x >> shCount (x = lsb(result))*/
6331 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6333 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6343 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6344 emitpcode(POC_RRF,popGet(AOP(result),offr));
6347 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6348 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6349 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6350 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6355 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6356 emitpcode(POC_RRF,popGet(AOP(result),offr));
6363 emitpcode(POC_MOVLW, popGetLit(0xf0));
6364 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6365 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6367 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6368 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6369 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6370 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6372 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6373 emitpcode(POC_ANDLW, popGetLit(0x0f));
6374 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6376 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6377 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6378 emitpcode(POC_ANDLW, popGetLit(0xf0));
6379 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6380 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6384 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6385 emitpcode(POC_RRF, popGet(AOP(result),offr));
6393 emitpcode(POC_RLF, popGet(AOP(result),offr));
6394 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6396 emitpcode(POC_RLF, popGet(AOP(result),offr));
6397 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6398 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6399 emitpcode(POC_ANDLW,popGetLit(0x03));
6400 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6401 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6402 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6403 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6405 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6406 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6407 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6408 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6409 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6410 emitpcode(POC_RLF, popGet(AOP(result),offr));
6411 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6412 emitpcode(POC_ANDLW,popGetLit(0x03));
6413 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6418 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6419 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6420 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6421 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6422 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6427 /*-----------------------------------------------------------------*/
6428 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6429 /*-----------------------------------------------------------------*/
6430 static void shiftLLeftOrResult (operand *left, int offl,
6431 operand *result, int offr, int shCount)
6433 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6434 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6435 /* shift left accumulator */
6437 /* or with result */
6438 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6439 /* back to result */
6440 aopPut(AOP(result),"a",offr);
6443 /*-----------------------------------------------------------------*/
6444 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6445 /*-----------------------------------------------------------------*/
6446 static void shiftRLeftOrResult (operand *left, int offl,
6447 operand *result, int offr, int shCount)
6449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6450 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6451 /* shift right accumulator */
6453 /* or with result */
6454 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6455 /* back to result */
6456 aopPut(AOP(result),"a",offr);
6459 /*-----------------------------------------------------------------*/
6460 /* genlshOne - left shift a one byte quantity by known count */
6461 /*-----------------------------------------------------------------*/
6462 static void genlshOne (operand *result, operand *left, int shCount)
6464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6465 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6468 /*-----------------------------------------------------------------*/
6469 /* genlshTwo - left shift two bytes by known amount != 0 */
6470 /*-----------------------------------------------------------------*/
6471 static void genlshTwo (operand *result,operand *left, int shCount)
6475 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6476 size = pic14_getDataSize(result);
6478 /* if shCount >= 8 */
6484 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6486 movLeft2Result(left, LSB, result, MSB16, 0);
6488 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6491 /* 1 <= shCount <= 7 */
6494 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6496 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6500 /*-----------------------------------------------------------------*/
6501 /* shiftLLong - shift left one long from left to result */
6502 /* offl = LSB or MSB16 */
6503 /*-----------------------------------------------------------------*/
6504 static void shiftLLong (operand *left, operand *result, int offr )
6507 int size = AOP_SIZE(result);
6509 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6510 if(size >= LSB+offr){
6511 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6513 pic14_emitcode("add","a,acc");
6514 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6515 size >= MSB16+offr && offr != LSB )
6516 pic14_emitcode("xch","a,%s",
6517 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6519 aopPut(AOP(result),"a",LSB+offr);
6522 if(size >= MSB16+offr){
6523 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6524 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6527 pic14_emitcode("rlc","a");
6528 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6529 size >= MSB24+offr && offr != LSB)
6530 pic14_emitcode("xch","a,%s",
6531 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6533 aopPut(AOP(result),"a",MSB16+offr);
6536 if(size >= MSB24+offr){
6537 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6538 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6541 pic14_emitcode("rlc","a");
6542 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6543 size >= MSB32+offr && offr != LSB )
6544 pic14_emitcode("xch","a,%s",
6545 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6547 aopPut(AOP(result),"a",MSB24+offr);
6550 if(size > MSB32+offr){
6551 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6552 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6555 pic14_emitcode("rlc","a");
6556 aopPut(AOP(result),"a",MSB32+offr);
6559 aopPut(AOP(result),zero,LSB);
6562 /*-----------------------------------------------------------------*/
6563 /* genlshFour - shift four byte by a known amount != 0 */
6564 /*-----------------------------------------------------------------*/
6565 static void genlshFour (operand *result, operand *left, int shCount)
6569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6570 size = AOP_SIZE(result);
6572 /* if shifting more that 3 bytes */
6573 if (shCount >= 24 ) {
6576 /* lowest order of left goes to the highest
6577 order of the destination */
6578 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6580 movLeft2Result(left, LSB, result, MSB32, 0);
6581 aopPut(AOP(result),zero,LSB);
6582 aopPut(AOP(result),zero,MSB16);
6583 aopPut(AOP(result),zero,MSB32);
6587 /* more than two bytes */
6588 else if ( shCount >= 16 ) {
6589 /* lower order two bytes goes to higher order two bytes */
6591 /* if some more remaining */
6593 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6595 movLeft2Result(left, MSB16, result, MSB32, 0);
6596 movLeft2Result(left, LSB, result, MSB24, 0);
6598 aopPut(AOP(result),zero,MSB16);
6599 aopPut(AOP(result),zero,LSB);
6603 /* if more than 1 byte */
6604 else if ( shCount >= 8 ) {
6605 /* lower order three bytes goes to higher order three bytes */
6609 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6611 movLeft2Result(left, LSB, result, MSB16, 0);
6613 else{ /* size = 4 */
6615 movLeft2Result(left, MSB24, result, MSB32, 0);
6616 movLeft2Result(left, MSB16, result, MSB24, 0);
6617 movLeft2Result(left, LSB, result, MSB16, 0);
6618 aopPut(AOP(result),zero,LSB);
6620 else if(shCount == 1)
6621 shiftLLong(left, result, MSB16);
6623 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6624 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6625 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6626 aopPut(AOP(result),zero,LSB);
6631 /* 1 <= shCount <= 7 */
6632 else if(shCount <= 2){
6633 shiftLLong(left, result, LSB);
6635 shiftLLong(result, result, LSB);
6637 /* 3 <= shCount <= 7, optimize */
6639 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6640 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6641 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6645 /*-----------------------------------------------------------------*/
6646 /* genLeftShiftLiteral - left shifting by known count */
6647 /*-----------------------------------------------------------------*/
6648 static void genLeftShiftLiteral (operand *left,
6653 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6657 freeAsmop(right,NULL,ic,TRUE);
6659 aopOp(left,ic,FALSE);
6660 aopOp(result,ic,FALSE);
6662 size = getSize(operandType(result));
6665 pic14_emitcode("; shift left ","result %d, left %d",size,
6669 /* I suppose that the left size >= result size */
6672 movLeft2Result(left, size, result, size, 0);
6676 else if(shCount >= (size * 8))
6678 aopPut(AOP(result),zero,size);
6682 genlshOne (result,left,shCount);
6687 genlshTwo (result,left,shCount);
6691 genlshFour (result,left,shCount);
6695 freeAsmop(left,NULL,ic,TRUE);
6696 freeAsmop(result,NULL,ic,TRUE);
6699 /*-----------------------------------------------------------------*/
6700 /* genLeftShift - generates code for left shifting */
6701 /*-----------------------------------------------------------------*/
6702 static void genLeftShift (iCode *ic)
6704 operand *left,*right, *result;
6707 symbol *tlbl , *tlbl1;
6709 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6711 right = IC_RIGHT(ic);
6713 result = IC_RESULT(ic);
6715 aopOp(right,ic,FALSE);
6717 /* if the shift count is known then do it
6718 as efficiently as possible */
6719 if (AOP_TYPE(right) == AOP_LIT) {
6720 genLeftShiftLiteral (left,right,result,ic);
6724 /* shift count is unknown then we have to form
6725 a loop get the loop count in B : Note: we take
6726 only the lower order byte since shifting
6727 more that 32 bits make no sense anyway, ( the
6728 largest size of an object can be only 32 bits ) */
6731 aopOp(left,ic,FALSE);
6732 aopOp(result,ic,FALSE);
6734 /* now move the left to the result if they are not the
6736 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6737 AOP_SIZE(result) > 1) {
6739 size = AOP_SIZE(result);
6742 l = aopGet(AOP(left),offset,FALSE,TRUE);
6743 if (*l == '@' && (IS_AOP_PREG(result))) {
6745 pic14_emitcode("mov","a,%s",l);
6746 aopPut(AOP(result),"a",offset);
6748 aopPut(AOP(result),l,offset);
6753 size = AOP_SIZE(result);
6755 /* if it is only one byte then */
6757 if(optimized_for_speed) {
6758 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6759 emitpcode(POC_ANDLW, popGetLit(0xf0));
6760 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6761 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6762 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6763 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6764 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6765 emitpcode(POC_RLFW, popGet(AOP(result),0));
6766 emitpcode(POC_ANDLW, popGetLit(0xfe));
6767 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6768 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6769 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6772 tlbl = newiTempLabel(NULL);
6773 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6774 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6775 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6778 emitpcode(POC_COMFW, popGet(AOP(right),0));
6779 emitpcode(POC_RRF, popGet(AOP(result),0));
6780 emitpLabel(tlbl->key);
6781 emitpcode(POC_RLF, popGet(AOP(result),0));
6782 emitpcode(POC_ADDLW, popGetLit(1));
6784 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6790 tlbl = newiTempLabel(NULL);
6792 tlbl1 = newiTempLabel(NULL);
6794 reAdjustPreg(AOP(result));
6796 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6797 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6798 l = aopGet(AOP(result),offset,FALSE,FALSE);
6800 pic14_emitcode("add","a,acc");
6801 aopPut(AOP(result),"a",offset++);
6803 l = aopGet(AOP(result),offset,FALSE,FALSE);
6805 pic14_emitcode("rlc","a");
6806 aopPut(AOP(result),"a",offset++);
6808 reAdjustPreg(AOP(result));
6810 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6811 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6813 freeAsmop (right,NULL,ic,TRUE);
6814 freeAsmop(left,NULL,ic,TRUE);
6815 freeAsmop(result,NULL,ic,TRUE);
6818 /*-----------------------------------------------------------------*/
6819 /* genrshOne - right shift a one byte quantity by known count */
6820 /*-----------------------------------------------------------------*/
6821 static void genrshOne (operand *result, operand *left,
6822 int shCount, int sign)
6824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6825 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6828 /*-----------------------------------------------------------------*/
6829 /* genrshTwo - right shift two bytes by known amount != 0 */
6830 /*-----------------------------------------------------------------*/
6831 static void genrshTwo (operand *result,operand *left,
6832 int shCount, int sign)
6834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6835 /* if shCount >= 8 */
6839 shiftR1Left2Result(left, MSB16, result, LSB,
6842 movLeft2Result(left, MSB16, result, LSB, sign);
6844 addSign(result, MSB16, sign);
6846 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6850 /* 1 <= shCount <= 7 */
6852 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6855 /*-----------------------------------------------------------------*/
6856 /* shiftRLong - shift right one long from left to result */
6857 /* offl = LSB or MSB16 */
6858 /*-----------------------------------------------------------------*/
6859 static void shiftRLong (operand *left, int offl,
6860 operand *result, int sign)
6862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6864 pic14_emitcode("clr","c");
6865 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6867 pic14_emitcode("mov","c,acc.7");
6868 pic14_emitcode("rrc","a");
6869 aopPut(AOP(result),"a",MSB32-offl);
6871 /* add sign of "a" */
6872 addSign(result, MSB32, sign);
6874 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6875 pic14_emitcode("rrc","a");
6876 aopPut(AOP(result),"a",MSB24-offl);
6878 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6879 pic14_emitcode("rrc","a");
6880 aopPut(AOP(result),"a",MSB16-offl);
6883 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6884 pic14_emitcode("rrc","a");
6885 aopPut(AOP(result),"a",LSB);
6889 /*-----------------------------------------------------------------*/
6890 /* genrshFour - shift four byte by a known amount != 0 */
6891 /*-----------------------------------------------------------------*/
6892 static void genrshFour (operand *result, operand *left,
6893 int shCount, int sign)
6895 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6896 /* if shifting more that 3 bytes */
6897 if(shCount >= 24 ) {
6900 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6902 movLeft2Result(left, MSB32, result, LSB, sign);
6903 addSign(result, MSB16, sign);
6905 else if(shCount >= 16){
6908 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6910 movLeft2Result(left, MSB24, result, LSB, 0);
6911 movLeft2Result(left, MSB32, result, MSB16, sign);
6913 addSign(result, MSB24, sign);
6915 else if(shCount >= 8){
6918 shiftRLong(left, MSB16, result, sign);
6919 else if(shCount == 0){
6920 movLeft2Result(left, MSB16, result, LSB, 0);
6921 movLeft2Result(left, MSB24, result, MSB16, 0);
6922 movLeft2Result(left, MSB32, result, MSB24, sign);
6923 addSign(result, MSB32, sign);
6926 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6927 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6928 /* the last shift is signed */
6929 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6930 addSign(result, MSB32, sign);
6933 else{ /* 1 <= shCount <= 7 */
6935 shiftRLong(left, LSB, result, sign);
6937 shiftRLong(result, LSB, result, sign);
6940 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6941 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6942 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6947 /*-----------------------------------------------------------------*/
6948 /* genRightShiftLiteral - right shifting by known count */
6949 /*-----------------------------------------------------------------*/
6950 static void genRightShiftLiteral (operand *left,
6956 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6960 freeAsmop(right,NULL,ic,TRUE);
6962 aopOp(left,ic,FALSE);
6963 aopOp(result,ic,FALSE);
6966 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6970 size = pic14_getDataSize(left);
6971 /* test the LEFT size !!! */
6973 /* I suppose that the left size >= result size */
6975 size = pic14_getDataSize(result);
6977 movLeft2Result(left, size, result, size, 0);
6980 else if(shCount >= (size * 8)){
6982 /* get sign in acc.7 */
6983 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6984 addSign(result, LSB, sign);
6988 genrshOne (result,left,shCount,sign);
6992 genrshTwo (result,left,shCount,sign);
6996 genrshFour (result,left,shCount,sign);
7002 freeAsmop(left,NULL,ic,TRUE);
7003 freeAsmop(result,NULL,ic,TRUE);
7007 /*-----------------------------------------------------------------*/
7008 /* genSignedRightShift - right shift of signed number */
7009 /*-----------------------------------------------------------------*/
7010 static void genSignedRightShift (iCode *ic)
7012 operand *right, *left, *result;
7015 symbol *tlbl, *tlbl1 ;
7017 /* we do it the hard way put the shift count in b
7018 and loop thru preserving the sign */
7019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7021 right = IC_RIGHT(ic);
7023 result = IC_RESULT(ic);
7025 aopOp(right,ic,FALSE);
7028 if ( AOP_TYPE(right) == AOP_LIT) {
7029 genRightShiftLiteral (left,right,result,ic,1);
7032 /* shift count is unknown then we have to form
7033 a loop get the loop count in B : Note: we take
7034 only the lower order byte since shifting
7035 more that 32 bits make no sense anyway, ( the
7036 largest size of an object can be only 32 bits ) */
7038 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7039 pic14_emitcode("inc","b");
7040 freeAsmop (right,NULL,ic,TRUE);
7041 aopOp(left,ic,FALSE);
7042 aopOp(result,ic,FALSE);
7044 /* now move the left to the result if they are not the
7046 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7047 AOP_SIZE(result) > 1) {
7049 size = AOP_SIZE(result);
7052 l = aopGet(AOP(left),offset,FALSE,TRUE);
7053 if (*l == '@' && IS_AOP_PREG(result)) {
7055 pic14_emitcode("mov","a,%s",l);
7056 aopPut(AOP(result),"a",offset);
7058 aopPut(AOP(result),l,offset);
7063 /* mov the highest order bit to OVR */
7064 tlbl = newiTempLabel(NULL);
7065 tlbl1= newiTempLabel(NULL);
7067 size = AOP_SIZE(result);
7069 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7070 pic14_emitcode("rlc","a");
7071 pic14_emitcode("mov","ov,c");
7072 /* if it is only one byte then */
7074 l = aopGet(AOP(left),0,FALSE,FALSE);
7076 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7077 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7078 pic14_emitcode("mov","c,ov");
7079 pic14_emitcode("rrc","a");
7080 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7081 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7082 aopPut(AOP(result),"a",0);
7086 reAdjustPreg(AOP(result));
7087 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7088 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7089 pic14_emitcode("mov","c,ov");
7091 l = aopGet(AOP(result),offset,FALSE,FALSE);
7093 pic14_emitcode("rrc","a");
7094 aopPut(AOP(result),"a",offset--);
7096 reAdjustPreg(AOP(result));
7097 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7098 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7101 freeAsmop(left,NULL,ic,TRUE);
7102 freeAsmop(result,NULL,ic,TRUE);
7105 /*-----------------------------------------------------------------*/
7106 /* genRightShift - generate code for right shifting */
7107 /*-----------------------------------------------------------------*/
7108 static void genRightShift (iCode *ic)
7110 operand *right, *left, *result;
7114 symbol *tlbl, *tlbl1 ;
7116 /* if signed then we do it the hard way preserve the
7117 sign bit moving it inwards */
7118 retype = getSpec(operandType(IC_RESULT(ic)));
7119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7121 if (!SPEC_USIGN(retype)) {
7122 genSignedRightShift (ic);
7126 /* signed & unsigned types are treated the same : i.e. the
7127 signed is NOT propagated inwards : quoting from the
7128 ANSI - standard : "for E1 >> E2, is equivalent to division
7129 by 2**E2 if unsigned or if it has a non-negative value,
7130 otherwise the result is implementation defined ", MY definition
7131 is that the sign does not get propagated */
7133 right = IC_RIGHT(ic);
7135 result = IC_RESULT(ic);
7137 aopOp(right,ic,FALSE);
7139 /* if the shift count is known then do it
7140 as efficiently as possible */
7141 if (AOP_TYPE(right) == AOP_LIT) {
7142 genRightShiftLiteral (left,right,result,ic, 0);
7146 /* shift count is unknown then we have to form
7147 a loop get the loop count in B : Note: we take
7148 only the lower order byte since shifting
7149 more that 32 bits make no sense anyway, ( the
7150 largest size of an object can be only 32 bits ) */
7152 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7153 pic14_emitcode("inc","b");
7154 aopOp(left,ic,FALSE);
7155 aopOp(result,ic,FALSE);
7157 /* now move the left to the result if they are not the
7159 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7160 AOP_SIZE(result) > 1) {
7162 size = AOP_SIZE(result);
7165 l = aopGet(AOP(left),offset,FALSE,TRUE);
7166 if (*l == '@' && IS_AOP_PREG(result)) {
7168 pic14_emitcode("mov","a,%s",l);
7169 aopPut(AOP(result),"a",offset);
7171 aopPut(AOP(result),l,offset);
7176 tlbl = newiTempLabel(NULL);
7177 tlbl1= newiTempLabel(NULL);
7178 size = AOP_SIZE(result);
7181 /* if it is only one byte then */
7184 l = aopGet(AOP(left),0,FALSE,FALSE);
7186 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7187 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7189 pic14_emitcode("rrc","a");
7190 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7191 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7192 aopPut(AOP(result),"a",0);
7194 tlbl = newiTempLabel(NULL);
7195 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7196 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7197 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7200 emitpcode(POC_COMFW, popGet(AOP(right),0));
7201 emitpcode(POC_RLF, popGet(AOP(result),0));
7202 emitpLabel(tlbl->key);
7203 emitpcode(POC_RRF, popGet(AOP(result),0));
7204 emitpcode(POC_ADDLW, popGetLit(1));
7206 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7211 reAdjustPreg(AOP(result));
7212 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7213 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7216 l = aopGet(AOP(result),offset,FALSE,FALSE);
7218 pic14_emitcode("rrc","a");
7219 aopPut(AOP(result),"a",offset--);
7221 reAdjustPreg(AOP(result));
7223 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7224 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7227 freeAsmop(left,NULL,ic,TRUE);
7228 freeAsmop (right,NULL,ic,TRUE);
7229 freeAsmop(result,NULL,ic,TRUE);
7232 /*-----------------------------------------------------------------*/
7233 /* genUnpackBits - generates code for unpacking bits */
7234 /*-----------------------------------------------------------------*/
7235 static void genUnpackBits (operand *result, char *rname, int ptype)
7242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7243 etype = getSpec(operandType(result));
7245 /* read the first byte */
7250 pic14_emitcode("mov","a,@%s",rname);
7254 pic14_emitcode("movx","a,@%s",rname);
7258 pic14_emitcode("movx","a,@dptr");
7262 pic14_emitcode("clr","a");
7263 pic14_emitcode("movc","a","@a+dptr");
7267 pic14_emitcode("lcall","__gptrget");
7271 /* if we have bitdisplacement then it fits */
7272 /* into this byte completely or if length is */
7273 /* less than a byte */
7274 if ((shCnt = SPEC_BSTR(etype)) ||
7275 (SPEC_BLEN(etype) <= 8)) {
7277 /* shift right acc */
7280 pic14_emitcode("anl","a,#0x%02x",
7281 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7282 aopPut(AOP(result),"a",offset);
7286 /* bit field did not fit in a byte */
7287 rlen = SPEC_BLEN(etype) - 8;
7288 aopPut(AOP(result),"a",offset++);
7295 pic14_emitcode("inc","%s",rname);
7296 pic14_emitcode("mov","a,@%s",rname);
7300 pic14_emitcode("inc","%s",rname);
7301 pic14_emitcode("movx","a,@%s",rname);
7305 pic14_emitcode("inc","dptr");
7306 pic14_emitcode("movx","a,@dptr");
7310 pic14_emitcode("clr","a");
7311 pic14_emitcode("inc","dptr");
7312 pic14_emitcode("movc","a","@a+dptr");
7316 pic14_emitcode("inc","dptr");
7317 pic14_emitcode("lcall","__gptrget");
7322 /* if we are done */
7326 aopPut(AOP(result),"a",offset++);
7331 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7332 aopPut(AOP(result),"a",offset);
7339 /*-----------------------------------------------------------------*/
7340 /* genDataPointerGet - generates code when ptr offset is known */
7341 /*-----------------------------------------------------------------*/
7342 static void genDataPointerGet (operand *left,
7346 int size , offset = 0;
7349 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7352 /* optimization - most of the time, left and result are the same
7353 * address, but different types. for the pic code, we could omit
7357 aopOp(result,ic,TRUE);
7359 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7361 size = AOP_SIZE(result);
7364 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7368 freeAsmop(left,NULL,ic,TRUE);
7369 freeAsmop(result,NULL,ic,TRUE);
7372 /*-----------------------------------------------------------------*/
7373 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7374 /*-----------------------------------------------------------------*/
7375 static void genNearPointerGet (operand *left,
7382 sym_link *rtype, *retype;
7383 sym_link *ltype = operandType(left);
7386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7388 rtype = operandType(result);
7389 retype= getSpec(rtype);
7391 aopOp(left,ic,FALSE);
7393 /* if left is rematerialisable and
7394 result is not bit variable type and
7395 the left is pointer to data space i.e
7396 lower 128 bytes of space */
7397 if (AOP_TYPE(left) == AOP_IMMD &&
7398 !IS_BITVAR(retype) &&
7399 DCL_TYPE(ltype) == POINTER) {
7400 genDataPointerGet (left,result,ic);
7404 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7406 /* if the value is already in a pointer register
7407 then don't need anything more */
7408 if (!AOP_INPREG(AOP(left))) {
7409 /* otherwise get a free pointer register */
7410 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7412 preg = getFreePtr(ic,&aop,FALSE);
7413 pic14_emitcode("mov","%s,%s",
7415 aopGet(AOP(left),0,FALSE,TRUE));
7416 rname = preg->name ;
7418 rname = aopGet(AOP(left),0,FALSE,FALSE);
7420 freeAsmop(left,NULL,ic,TRUE);
7421 aopOp (result,ic,FALSE);
7423 /* if bitfield then unpack the bits */
7424 if (IS_BITVAR(retype))
7425 genUnpackBits (result,rname,POINTER);
7427 /* we have can just get the values */
7428 int size = AOP_SIZE(result);
7431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7433 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7435 pic14_emitcode("mov","a,@%s",rname);
7436 aopPut(AOP(result),"a",offset);
7438 sprintf(buffer,"@%s",rname);
7439 aopPut(AOP(result),buffer,offset);
7443 pic14_emitcode("inc","%s",rname);
7447 /* now some housekeeping stuff */
7449 /* we had to allocate for this iCode */
7450 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7451 freeAsmop(NULL,aop,ic,TRUE);
7453 /* we did not allocate which means left
7454 already in a pointer register, then
7455 if size > 0 && this could be used again
7456 we have to point it back to where it
7458 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7459 if (AOP_SIZE(result) > 1 &&
7460 !OP_SYMBOL(left)->remat &&
7461 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7463 int size = AOP_SIZE(result) - 1;
7465 pic14_emitcode("dec","%s",rname);
7470 freeAsmop(result,NULL,ic,TRUE);
7474 /*-----------------------------------------------------------------*/
7475 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7476 /*-----------------------------------------------------------------*/
7477 static void genPagedPointerGet (operand *left,
7484 sym_link *rtype, *retype;
7486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7488 rtype = operandType(result);
7489 retype= getSpec(rtype);
7491 aopOp(left,ic,FALSE);
7493 /* if the value is already in a pointer register
7494 then don't need anything more */
7495 if (!AOP_INPREG(AOP(left))) {
7496 /* otherwise get a free pointer register */
7498 preg = getFreePtr(ic,&aop,FALSE);
7499 pic14_emitcode("mov","%s,%s",
7501 aopGet(AOP(left),0,FALSE,TRUE));
7502 rname = preg->name ;
7504 rname = aopGet(AOP(left),0,FALSE,FALSE);
7506 freeAsmop(left,NULL,ic,TRUE);
7507 aopOp (result,ic,FALSE);
7509 /* if bitfield then unpack the bits */
7510 if (IS_BITVAR(retype))
7511 genUnpackBits (result,rname,PPOINTER);
7513 /* we have can just get the values */
7514 int size = AOP_SIZE(result);
7519 pic14_emitcode("movx","a,@%s",rname);
7520 aopPut(AOP(result),"a",offset);
7525 pic14_emitcode("inc","%s",rname);
7529 /* now some housekeeping stuff */
7531 /* we had to allocate for this iCode */
7532 freeAsmop(NULL,aop,ic,TRUE);
7534 /* we did not allocate which means left
7535 already in a pointer register, then
7536 if size > 0 && this could be used again
7537 we have to point it back to where it
7539 if (AOP_SIZE(result) > 1 &&
7540 !OP_SYMBOL(left)->remat &&
7541 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7543 int size = AOP_SIZE(result) - 1;
7545 pic14_emitcode("dec","%s",rname);
7550 freeAsmop(result,NULL,ic,TRUE);
7555 /*-----------------------------------------------------------------*/
7556 /* genFarPointerGet - gget value from far space */
7557 /*-----------------------------------------------------------------*/
7558 static void genFarPointerGet (operand *left,
7559 operand *result, iCode *ic)
7562 sym_link *retype = getSpec(operandType(result));
7564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7566 aopOp(left,ic,FALSE);
7568 /* if the operand is already in dptr
7569 then we do nothing else we move the value to dptr */
7570 if (AOP_TYPE(left) != AOP_STR) {
7571 /* if this is remateriazable */
7572 if (AOP_TYPE(left) == AOP_IMMD)
7573 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7574 else { /* we need to get it byte by byte */
7575 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7576 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7577 if (options.model == MODEL_FLAT24)
7579 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7583 /* so dptr know contains the address */
7584 freeAsmop(left,NULL,ic,TRUE);
7585 aopOp(result,ic,FALSE);
7587 /* if bit then unpack */
7588 if (IS_BITVAR(retype))
7589 genUnpackBits(result,"dptr",FPOINTER);
7591 size = AOP_SIZE(result);
7595 pic14_emitcode("movx","a,@dptr");
7596 aopPut(AOP(result),"a",offset++);
7598 pic14_emitcode("inc","dptr");
7602 freeAsmop(result,NULL,ic,TRUE);
7605 /*-----------------------------------------------------------------*/
7606 /* pic14_emitcodePointerGet - gget value from code space */
7607 /*-----------------------------------------------------------------*/
7608 static void pic14_emitcodePointerGet (operand *left,
7609 operand *result, iCode *ic)
7612 sym_link *retype = getSpec(operandType(result));
7614 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7616 aopOp(left,ic,FALSE);
7618 /* if the operand is already in dptr
7619 then we do nothing else we move the value to dptr */
7620 if (AOP_TYPE(left) != AOP_STR) {
7621 /* if this is remateriazable */
7622 if (AOP_TYPE(left) == AOP_IMMD)
7623 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7624 else { /* we need to get it byte by byte */
7625 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7626 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7627 if (options.model == MODEL_FLAT24)
7629 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7633 /* so dptr know contains the address */
7634 freeAsmop(left,NULL,ic,TRUE);
7635 aopOp(result,ic,FALSE);
7637 /* if bit then unpack */
7638 if (IS_BITVAR(retype))
7639 genUnpackBits(result,"dptr",CPOINTER);
7641 size = AOP_SIZE(result);
7645 pic14_emitcode("clr","a");
7646 pic14_emitcode("movc","a,@a+dptr");
7647 aopPut(AOP(result),"a",offset++);
7649 pic14_emitcode("inc","dptr");
7653 freeAsmop(result,NULL,ic,TRUE);
7656 /*-----------------------------------------------------------------*/
7657 /* genGenPointerGet - gget value from generic pointer space */
7658 /*-----------------------------------------------------------------*/
7659 static void genGenPointerGet (operand *left,
7660 operand *result, iCode *ic)
7663 sym_link *retype = getSpec(operandType(result));
7665 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7666 aopOp(left,ic,FALSE);
7667 aopOp(result,ic,FALSE);
7670 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7672 /* if the operand is already in dptr
7673 then we do nothing else we move the value to dptr */
7674 if (AOP_TYPE(left) != AOP_STR) {
7675 /* if this is remateriazable */
7676 if (AOP_TYPE(left) == AOP_IMMD) {
7677 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7678 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7680 else { /* we need to get it byte by byte */
7682 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7683 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7685 size = AOP_SIZE(result);
7689 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7690 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7692 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7697 /* so dptr know contains the address */
7699 /* if bit then unpack */
7700 if (IS_BITVAR(retype))
7701 genUnpackBits(result,"dptr",GPOINTER);
7704 freeAsmop(left,NULL,ic,TRUE);
7705 freeAsmop(result,NULL,ic,TRUE);
7709 /*-----------------------------------------------------------------*/
7710 /* genPointerGet - generate code for pointer get */
7711 /*-----------------------------------------------------------------*/
7712 static void genPointerGet (iCode *ic)
7714 operand *left, *result ;
7715 sym_link *type, *etype;
7718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7721 result = IC_RESULT(ic) ;
7723 /* depending on the type of pointer we need to
7724 move it to the correct pointer register */
7725 type = operandType(left);
7726 etype = getSpec(type);
7727 /* if left is of type of pointer then it is simple */
7728 if (IS_PTR(type) && !IS_FUNC(type->next))
7729 p_type = DCL_TYPE(type);
7731 /* we have to go by the storage class */
7732 p_type = PTR_TYPE(SPEC_OCLS(etype));
7734 /* if (SPEC_OCLS(etype)->codesp ) { */
7735 /* p_type = CPOINTER ; */
7738 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7739 /* p_type = FPOINTER ; */
7741 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7742 /* p_type = PPOINTER; */
7744 /* if (SPEC_OCLS(etype) == idata ) */
7745 /* p_type = IPOINTER; */
7747 /* p_type = POINTER ; */
7750 /* now that we have the pointer type we assign
7751 the pointer values */
7756 genNearPointerGet (left,result,ic);
7760 genPagedPointerGet(left,result,ic);
7764 genFarPointerGet (left,result,ic);
7768 pic14_emitcodePointerGet (left,result,ic);
7772 genGenPointerGet (left,result,ic);
7778 /*-----------------------------------------------------------------*/
7779 /* genPackBits - generates code for packed bit storage */
7780 /*-----------------------------------------------------------------*/
7781 static void genPackBits (sym_link *etype ,
7783 char *rname, int p_type)
7791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7792 blen = SPEC_BLEN(etype);
7793 bstr = SPEC_BSTR(etype);
7795 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7798 /* if the bit lenth is less than or */
7799 /* it exactly fits a byte then */
7800 if (SPEC_BLEN(etype) <= 8 ) {
7801 shCount = SPEC_BSTR(etype) ;
7803 /* shift left acc */
7806 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7811 pic14_emitcode ("mov","b,a");
7812 pic14_emitcode("mov","a,@%s",rname);
7816 pic14_emitcode ("mov","b,a");
7817 pic14_emitcode("movx","a,@dptr");
7821 pic14_emitcode ("push","b");
7822 pic14_emitcode ("push","acc");
7823 pic14_emitcode ("lcall","__gptrget");
7824 pic14_emitcode ("pop","b");
7828 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7829 ((unsigned char)(0xFF << (blen+bstr)) |
7830 (unsigned char)(0xFF >> (8-bstr)) ) );
7831 pic14_emitcode ("orl","a,b");
7832 if (p_type == GPOINTER)
7833 pic14_emitcode("pop","b");
7839 pic14_emitcode("mov","@%s,a",rname);
7843 pic14_emitcode("movx","@dptr,a");
7847 DEBUGpic14_emitcode(";lcall","__gptrput");
7852 if ( SPEC_BLEN(etype) <= 8 )
7855 pic14_emitcode("inc","%s",rname);
7856 rLen = SPEC_BLEN(etype) ;
7858 /* now generate for lengths greater than one byte */
7861 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7871 pic14_emitcode("mov","@%s,a",rname);
7873 pic14_emitcode("mov","@%s,%s",rname,l);
7878 pic14_emitcode("movx","@dptr,a");
7883 DEBUGpic14_emitcode(";lcall","__gptrput");
7886 pic14_emitcode ("inc","%s",rname);
7891 /* last last was not complete */
7893 /* save the byte & read byte */
7896 pic14_emitcode ("mov","b,a");
7897 pic14_emitcode("mov","a,@%s",rname);
7901 pic14_emitcode ("mov","b,a");
7902 pic14_emitcode("movx","a,@dptr");
7906 pic14_emitcode ("push","b");
7907 pic14_emitcode ("push","acc");
7908 pic14_emitcode ("lcall","__gptrget");
7909 pic14_emitcode ("pop","b");
7913 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7914 pic14_emitcode ("orl","a,b");
7917 if (p_type == GPOINTER)
7918 pic14_emitcode("pop","b");
7923 pic14_emitcode("mov","@%s,a",rname);
7927 pic14_emitcode("movx","@dptr,a");
7931 DEBUGpic14_emitcode(";lcall","__gptrput");
7935 /*-----------------------------------------------------------------*/
7936 /* genDataPointerSet - remat pointer to data space */
7937 /*-----------------------------------------------------------------*/
7938 static void genDataPointerSet(operand *right,
7942 int size, offset = 0 ;
7943 char *l, buffer[256];
7945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7946 aopOp(right,ic,FALSE);
7948 l = aopGet(AOP(result),0,FALSE,TRUE);
7949 size = AOP_SIZE(right);
7950 // tsd, was l+1 - the underline `_' prefix was being stripped
7953 sprintf(buffer,"(%s + %d)",l,offset);
7955 sprintf(buffer,"%s",l);
7957 if (AOP_TYPE(right) == AOP_LIT) {
7958 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7959 lit = lit >> (8*offset);
7961 pic14_emitcode("movlw","%d",lit);
7962 pic14_emitcode("movwf","%s",buffer);
7964 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7965 emitpcode(POC_MOVWF, popRegFromString(buffer));
7968 pic14_emitcode("clrf","%s",buffer);
7969 emitpcode(POC_CLRF, popRegFromString(buffer));
7972 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7973 pic14_emitcode("movwf","%s",buffer);
7975 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7976 emitpcode(POC_MOVWF, popRegFromString(buffer));
7983 freeAsmop(right,NULL,ic,TRUE);
7984 freeAsmop(result,NULL,ic,TRUE);
7987 /*-----------------------------------------------------------------*/
7988 /* genNearPointerSet - pic14_emitcode for near pointer put */
7989 /*-----------------------------------------------------------------*/
7990 static void genNearPointerSet (operand *right,
7997 sym_link *ptype = operandType(result);
8000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 retype= getSpec(operandType(right));
8003 aopOp(result,ic,FALSE);
8005 /* if the result is rematerializable &
8006 in data space & not a bit variable */
8007 if (AOP_TYPE(result) == AOP_IMMD &&
8008 DCL_TYPE(ptype) == POINTER &&
8009 !IS_BITVAR(retype)) {
8010 genDataPointerSet (right,result,ic);
8014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8016 /* if the value is already in a pointer register
8017 then don't need anything more */
8018 if (!AOP_INPREG(AOP(result))) {
8019 /* otherwise get a free pointer register */
8020 //aop = newAsmop(0);
8021 //preg = getFreePtr(ic,&aop,FALSE);
8022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8023 //pic14_emitcode("mov","%s,%s",
8025 // aopGet(AOP(result),0,FALSE,TRUE));
8026 //rname = preg->name ;
8027 pic14_emitcode("movwf","fsr");
8029 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8031 freeAsmop(result,NULL,ic,TRUE);
8032 aopOp (right,ic,FALSE);
8033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 /* if bitfield then unpack the bits */
8036 if (IS_BITVAR(retype)) {
8037 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8038 "The programmer is obviously confused");
8039 //genPackBits (retype,right,rname,POINTER);
8043 /* we have can just get the values */
8044 int size = AOP_SIZE(right);
8047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8049 l = aopGet(AOP(right),offset,FALSE,TRUE);
8052 //pic14_emitcode("mov","@%s,a",rname);
8053 pic14_emitcode("movf","indf,w ;1");
8056 if (AOP_TYPE(right) == AOP_LIT) {
8057 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8059 pic14_emitcode("movlw","%s",l);
8060 pic14_emitcode("movwf","indf ;2");
8062 pic14_emitcode("clrf","indf");
8064 pic14_emitcode("movf","%s,w",l);
8065 pic14_emitcode("movwf","indf ;2");
8067 //pic14_emitcode("mov","@%s,%s",rname,l);
8070 pic14_emitcode("incf","fsr,f ;3");
8071 //pic14_emitcode("inc","%s",rname);
8076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8077 /* now some housekeeping stuff */
8079 /* we had to allocate for this iCode */
8080 freeAsmop(NULL,aop,ic,TRUE);
8082 /* we did not allocate which means left
8083 already in a pointer register, then
8084 if size > 0 && this could be used again
8085 we have to point it back to where it
8087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8088 if (AOP_SIZE(right) > 1 &&
8089 !OP_SYMBOL(result)->remat &&
8090 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8092 int size = AOP_SIZE(right) - 1;
8094 pic14_emitcode("decf","fsr,f");
8095 //pic14_emitcode("dec","%s",rname);
8099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8101 freeAsmop(right,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8108 /*-----------------------------------------------------------------*/
8109 static void genPagedPointerSet (operand *right,
8118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8120 retype= getSpec(operandType(right));
8122 aopOp(result,ic,FALSE);
8124 /* if the value is already in a pointer register
8125 then don't need anything more */
8126 if (!AOP_INPREG(AOP(result))) {
8127 /* otherwise get a free pointer register */
8129 preg = getFreePtr(ic,&aop,FALSE);
8130 pic14_emitcode("mov","%s,%s",
8132 aopGet(AOP(result),0,FALSE,TRUE));
8133 rname = preg->name ;
8135 rname = aopGet(AOP(result),0,FALSE,FALSE);
8137 freeAsmop(result,NULL,ic,TRUE);
8138 aopOp (right,ic,FALSE);
8140 /* if bitfield then unpack the bits */
8141 if (IS_BITVAR(retype))
8142 genPackBits (retype,right,rname,PPOINTER);
8144 /* we have can just get the values */
8145 int size = AOP_SIZE(right);
8149 l = aopGet(AOP(right),offset,FALSE,TRUE);
8152 pic14_emitcode("movx","@%s,a",rname);
8155 pic14_emitcode("inc","%s",rname);
8161 /* now some housekeeping stuff */
8163 /* we had to allocate for this iCode */
8164 freeAsmop(NULL,aop,ic,TRUE);
8166 /* we did not allocate which means left
8167 already in a pointer register, then
8168 if size > 0 && this could be used again
8169 we have to point it back to where it
8171 if (AOP_SIZE(right) > 1 &&
8172 !OP_SYMBOL(result)->remat &&
8173 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8175 int size = AOP_SIZE(right) - 1;
8177 pic14_emitcode("dec","%s",rname);
8182 freeAsmop(right,NULL,ic,TRUE);
8187 /*-----------------------------------------------------------------*/
8188 /* genFarPointerSet - set value from far space */
8189 /*-----------------------------------------------------------------*/
8190 static void genFarPointerSet (operand *right,
8191 operand *result, iCode *ic)
8194 sym_link *retype = getSpec(operandType(right));
8196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8197 aopOp(result,ic,FALSE);
8199 /* if the operand is already in dptr
8200 then we do nothing else we move the value to dptr */
8201 if (AOP_TYPE(result) != AOP_STR) {
8202 /* if this is remateriazable */
8203 if (AOP_TYPE(result) == AOP_IMMD)
8204 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8205 else { /* we need to get it byte by byte */
8206 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8207 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8208 if (options.model == MODEL_FLAT24)
8210 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8214 /* so dptr know contains the address */
8215 freeAsmop(result,NULL,ic,TRUE);
8216 aopOp(right,ic,FALSE);
8218 /* if bit then unpack */
8219 if (IS_BITVAR(retype))
8220 genPackBits(retype,right,"dptr",FPOINTER);
8222 size = AOP_SIZE(right);
8226 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8228 pic14_emitcode("movx","@dptr,a");
8230 pic14_emitcode("inc","dptr");
8234 freeAsmop(right,NULL,ic,TRUE);
8237 /*-----------------------------------------------------------------*/
8238 /* genGenPointerSet - set value from generic pointer space */
8239 /*-----------------------------------------------------------------*/
8240 static void genGenPointerSet (operand *right,
8241 operand *result, iCode *ic)
8244 sym_link *retype = getSpec(operandType(right));
8246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8248 aopOp(result,ic,FALSE);
8249 aopOp(right,ic,FALSE);
8250 size = AOP_SIZE(right);
8252 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8254 /* if the operand is already in dptr
8255 then we do nothing else we move the value to dptr */
8256 if (AOP_TYPE(result) != AOP_STR) {
8257 /* if this is remateriazable */
8258 if (AOP_TYPE(result) == AOP_IMMD) {
8259 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8260 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8262 else { /* we need to get it byte by byte */
8263 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8264 size = AOP_SIZE(right);
8267 /* hack hack! see if this the FSR. If so don't load W */
8268 if(AOP_TYPE(right) != AOP_ACC) {
8270 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8271 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8274 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8276 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8277 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8281 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8282 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8285 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8292 if(aopIdx(AOP(result),0) != 4) {
8294 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8298 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8303 /* so dptr know contains the address */
8306 /* if bit then unpack */
8307 if (IS_BITVAR(retype))
8308 genPackBits(retype,right,"dptr",GPOINTER);
8310 size = AOP_SIZE(right);
8314 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8316 pic14_emitcode("incf","fsr,f");
8317 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8318 pic14_emitcode("movwf","indf");
8320 //DEBUGpic14_emitcode(";lcall","__gptrput");
8322 // pic14_emitcode("inc","dptr");
8327 freeAsmop(right,NULL,ic,TRUE);
8328 freeAsmop(result,NULL,ic,TRUE);
8331 /*-----------------------------------------------------------------*/
8332 /* genPointerSet - stores the value into a pointer location */
8333 /*-----------------------------------------------------------------*/
8334 static void genPointerSet (iCode *ic)
8336 operand *right, *result ;
8337 sym_link *type, *etype;
8340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8342 right = IC_RIGHT(ic);
8343 result = IC_RESULT(ic) ;
8345 /* depending on the type of pointer we need to
8346 move it to the correct pointer register */
8347 type = operandType(result);
8348 etype = getSpec(type);
8349 /* if left is of type of pointer then it is simple */
8350 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8351 p_type = DCL_TYPE(type);
8354 /* we have to go by the storage class */
8355 p_type = PTR_TYPE(SPEC_OCLS(etype));
8357 /* if (SPEC_OCLS(etype)->codesp ) { */
8358 /* p_type = CPOINTER ; */
8361 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8362 /* p_type = FPOINTER ; */
8364 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8365 /* p_type = PPOINTER ; */
8367 /* if (SPEC_OCLS(etype) == idata ) */
8368 /* p_type = IPOINTER ; */
8370 /* p_type = POINTER ; */
8373 /* now that we have the pointer type we assign
8374 the pointer values */
8379 genNearPointerSet (right,result,ic);
8383 genPagedPointerSet (right,result,ic);
8387 genFarPointerSet (right,result,ic);
8391 genGenPointerSet (right,result,ic);
8397 /*-----------------------------------------------------------------*/
8398 /* genIfx - generate code for Ifx statement */
8399 /*-----------------------------------------------------------------*/
8400 static void genIfx (iCode *ic, iCode *popIc)
8402 operand *cond = IC_COND(ic);
8405 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8407 aopOp(cond,ic,FALSE);
8409 /* get the value into acc */
8410 if (AOP_TYPE(cond) != AOP_CRY)
8411 pic14_toBoolean(cond);
8414 /* the result is now in the accumulator */
8415 freeAsmop(cond,NULL,ic,TRUE);
8417 /* if there was something to be popped then do it */
8421 /* if the condition is a bit variable */
8422 if (isbit && IS_ITEMP(cond) &&
8424 genIfxJump(ic,SPIL_LOC(cond)->rname);
8425 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8428 if (isbit && !IS_ITEMP(cond))
8429 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8437 /*-----------------------------------------------------------------*/
8438 /* genAddrOf - generates code for address of */
8439 /*-----------------------------------------------------------------*/
8440 static void genAddrOf (iCode *ic)
8442 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8443 operand *right, *result, *left;
8444 //int size, offset ;
8446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8449 //aopOp(IC_RESULT(ic),ic,FALSE);
8451 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8452 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8453 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8455 DEBUGpic14_AopType(__LINE__,left,right,result);
8457 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8458 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8461 /* object not on stack then we need the name */
8462 size = AOP_SIZE(IC_RESULT(ic));
8466 char s[SDCC_NAME_MAX];
8468 sprintf(s,"#(%s >> %d)",
8472 sprintf(s,"#%s",sym->rname);
8473 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8478 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8479 freeAsmop(left,NULL,ic,FALSE);
8480 freeAsmop(result,NULL,ic,TRUE);
8485 /*-----------------------------------------------------------------*/
8486 /* genFarFarAssign - assignment when both are in far space */
8487 /*-----------------------------------------------------------------*/
8488 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8490 int size = AOP_SIZE(right);
8493 /* first push the right side on to the stack */
8495 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8497 pic14_emitcode ("push","acc");
8500 freeAsmop(right,NULL,ic,FALSE);
8501 /* now assign DPTR to result */
8502 aopOp(result,ic,FALSE);
8503 size = AOP_SIZE(result);
8505 pic14_emitcode ("pop","acc");
8506 aopPut(AOP(result),"a",--offset);
8508 freeAsmop(result,NULL,ic,FALSE);
8513 /*-----------------------------------------------------------------*/
8514 /* genAssign - generate code for assignment */
8515 /*-----------------------------------------------------------------*/
8516 static void genAssign (iCode *ic)
8518 operand *result, *right;
8519 int size, offset,know_W;
8520 unsigned long lit = 0L;
8522 result = IC_RESULT(ic);
8523 right = IC_RIGHT(ic) ;
8525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8527 /* if they are the same */
8528 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8531 aopOp(right,ic,FALSE);
8532 aopOp(result,ic,TRUE);
8534 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8536 /* if they are the same registers */
8537 if (pic14_sameRegs(AOP(right),AOP(result)))
8540 /* if the result is a bit */
8541 if (AOP_TYPE(result) == AOP_CRY) {
8543 /* if the right size is a literal then
8544 we know what the value is */
8545 if (AOP_TYPE(right) == AOP_LIT) {
8547 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8548 popGet(AOP(result),0));
8550 if (((int) operandLitValue(right)))
8551 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8552 AOP(result)->aopu.aop_dir,
8553 AOP(result)->aopu.aop_dir);
8555 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8556 AOP(result)->aopu.aop_dir,
8557 AOP(result)->aopu.aop_dir);
8561 /* the right is also a bit variable */
8562 if (AOP_TYPE(right) == AOP_CRY) {
8563 emitpcode(POC_BCF, popGet(AOP(result),0));
8564 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8565 emitpcode(POC_BSF, popGet(AOP(result),0));
8567 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8568 AOP(result)->aopu.aop_dir,
8569 AOP(result)->aopu.aop_dir);
8570 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8571 AOP(right)->aopu.aop_dir,
8572 AOP(right)->aopu.aop_dir);
8573 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8574 AOP(result)->aopu.aop_dir,
8575 AOP(result)->aopu.aop_dir);
8580 emitpcode(POC_BCF, popGet(AOP(result),0));
8581 pic14_toBoolean(right);
8583 emitpcode(POC_BSF, popGet(AOP(result),0));
8584 //aopPut(AOP(result),"a",0);
8588 /* bit variables done */
8590 size = AOP_SIZE(result);
8592 if(AOP_TYPE(right) == AOP_LIT)
8593 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8595 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8596 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8597 if(aopIdx(AOP(result),0) == 4) {
8598 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8599 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8600 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8603 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8608 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8609 if(AOP_TYPE(right) == AOP_LIT) {
8611 if(know_W != (lit&0xff))
8612 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8614 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8616 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8620 } else if (AOP_TYPE(right) == AOP_CRY) {
8621 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8623 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8624 emitpcode(POC_INCF, popGet(AOP(result),0));
8627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8628 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8629 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8637 freeAsmop (right,NULL,ic,FALSE);
8638 freeAsmop (result,NULL,ic,TRUE);
8641 /*-----------------------------------------------------------------*/
8642 /* genJumpTab - genrates code for jump table */
8643 /*-----------------------------------------------------------------*/
8644 static void genJumpTab (iCode *ic)
8649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8651 aopOp(IC_JTCOND(ic),ic,FALSE);
8652 /* get the condition into accumulator */
8653 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8655 /* multiply by three */
8656 pic14_emitcode("add","a,acc");
8657 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8659 jtab = newiTempLabel(NULL);
8660 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8661 pic14_emitcode("jmp","@a+dptr");
8662 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8664 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8665 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8667 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8668 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8669 emitpLabel(jtab->key);
8671 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8673 /* now generate the jump labels */
8674 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8675 jtab = setNextItem(IC_JTLABELS(ic))) {
8676 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8677 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8683 /*-----------------------------------------------------------------*/
8684 /* genMixedOperation - gen code for operators between mixed types */
8685 /*-----------------------------------------------------------------*/
8687 TSD - Written for the PIC port - but this unfortunately is buggy.
8688 This routine is good in that it is able to efficiently promote
8689 types to different (larger) sizes. Unfortunately, the temporary
8690 variables that are optimized out by this routine are sometimes
8691 used in other places. So until I know how to really parse the
8692 iCode tree, I'm going to not be using this routine :(.
8694 static int genMixedOperation (iCode *ic)
8697 operand *result = IC_RESULT(ic);
8698 sym_link *ctype = operandType(IC_LEFT(ic));
8699 operand *right = IC_RIGHT(ic);
8705 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8707 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8713 nextright = IC_RIGHT(nextic);
8714 nextleft = IC_LEFT(nextic);
8715 nextresult = IC_RESULT(nextic);
8717 aopOp(right,ic,FALSE);
8718 aopOp(result,ic,FALSE);
8719 aopOp(nextright, nextic, FALSE);
8720 aopOp(nextleft, nextic, FALSE);
8721 aopOp(nextresult, nextic, FALSE);
8723 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8729 pic14_emitcode(";remove right +","");
8731 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8737 pic14_emitcode(";remove left +","");
8741 big = AOP_SIZE(nextleft);
8742 small = AOP_SIZE(nextright);
8744 switch(nextic->op) {
8747 pic14_emitcode(";optimize a +","");
8748 /* if unsigned or not an integral type */
8749 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8750 pic14_emitcode(";add a bit to something","");
8753 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8755 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8756 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8757 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8759 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8767 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8768 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8769 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8772 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8774 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8775 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8776 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8777 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8778 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8781 pic14_emitcode("rlf","known_zero,w");
8788 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8789 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8790 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8792 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8802 freeAsmop(right,NULL,ic,TRUE);
8803 freeAsmop(result,NULL,ic,TRUE);
8804 freeAsmop(nextright,NULL,ic,TRUE);
8805 freeAsmop(nextleft,NULL,ic,TRUE);
8807 nextic->generated = 1;
8814 /*-----------------------------------------------------------------*/
8815 /* genCast - gen code for casting */
8816 /*-----------------------------------------------------------------*/
8817 static void genCast (iCode *ic)
8819 operand *result = IC_RESULT(ic);
8820 sym_link *ctype = operandType(IC_LEFT(ic));
8821 operand *right = IC_RIGHT(ic);
8824 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8825 /* if they are equivalent then do nothing */
8826 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8829 aopOp(right,ic,FALSE) ;
8830 aopOp(result,ic,FALSE);
8832 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8834 /* if the result is a bit */
8835 if (AOP_TYPE(result) == AOP_CRY) {
8836 /* if the right size is a literal then
8837 we know what the value is */
8838 if (AOP_TYPE(right) == AOP_LIT) {
8840 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8841 popGet(AOP(result),0));
8843 if (((int) operandLitValue(right)))
8844 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8845 AOP(result)->aopu.aop_dir,
8846 AOP(result)->aopu.aop_dir);
8848 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8849 AOP(result)->aopu.aop_dir,
8850 AOP(result)->aopu.aop_dir);
8855 /* the right is also a bit variable */
8856 if (AOP_TYPE(right) == AOP_CRY) {
8859 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8861 pic14_emitcode("clrc","");
8862 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8863 AOP(right)->aopu.aop_dir,
8864 AOP(right)->aopu.aop_dir);
8865 aopPut(AOP(result),"c",0);
8870 if (AOP_TYPE(right) == AOP_REG) {
8871 emitpcode(POC_BCF, popGet(AOP(result),0));
8872 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8873 emitpcode(POC_BSF, popGet(AOP(result),0));
8875 pic14_toBoolean(right);
8876 aopPut(AOP(result),"a",0);
8880 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8882 size = AOP_SIZE(result);
8884 emitpcode(POC_CLRF, popGet(AOP(result),0));
8885 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8886 emitpcode(POC_INCF, popGet(AOP(result),0));
8889 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8894 /* if they are the same size : or less */
8895 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8897 /* if they are in the same place */
8898 if (pic14_sameRegs(AOP(right),AOP(result)))
8901 /* if they in different places then copy */
8902 size = AOP_SIZE(result);
8906 aopGet(AOP(right),offset,FALSE,FALSE),
8914 /* if the result is of type pointer */
8915 if (IS_PTR(ctype)) {
8918 sym_link *type = operandType(right);
8919 sym_link *etype = getSpec(type);
8921 /* pointer to generic pointer */
8922 if (IS_GENPTR(ctype)) {
8926 p_type = DCL_TYPE(type);
8928 /* we have to go by the storage class */
8929 p_type = PTR_TYPE(SPEC_OCLS(etype));
8931 /* if (SPEC_OCLS(etype)->codesp ) */
8932 /* p_type = CPOINTER ; */
8934 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8935 /* p_type = FPOINTER ; */
8937 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8938 /* p_type = PPOINTER; */
8940 /* if (SPEC_OCLS(etype) == idata ) */
8941 /* p_type = IPOINTER ; */
8943 /* p_type = POINTER ; */
8946 /* the first two bytes are known */
8947 size = GPTRSIZE - 1;
8951 aopGet(AOP(right),offset,FALSE,FALSE),
8955 /* the last byte depending on type */
8972 /* this should never happen */
8973 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8974 "got unknown pointer type");
8977 aopPut(AOP(result),l, GPTRSIZE - 1);
8981 /* just copy the pointers */
8982 size = AOP_SIZE(result);
8986 aopGet(AOP(right),offset,FALSE,FALSE),
8995 /* so we now know that the size of destination is greater
8996 than the size of the source.
8997 Now, if the next iCode is an operator then we might be
8998 able to optimize the operation without performing a cast.
9000 if(genMixedOperation(ic))
9004 /* we move to result for the size of source */
9005 size = AOP_SIZE(right);
9008 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9009 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9013 /* now depending on the sign of the destination */
9014 size = AOP_SIZE(result) - AOP_SIZE(right);
9015 /* if unsigned or not an integral type */
9016 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
9018 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9020 /* we need to extend the sign :{ */
9023 /* Save one instruction of casting char to int */
9024 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9025 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9026 emitpcode(POC_DECF, popGet(AOP(result),offset));
9028 emitpcodeNULLop(POC_CLRW);
9031 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9033 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9035 emitpcode(POC_MOVLW, popGetLit(0xff));
9038 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9043 freeAsmop(right,NULL,ic,TRUE);
9044 freeAsmop(result,NULL,ic,TRUE);
9048 /*-----------------------------------------------------------------*/
9049 /* genDjnz - generate decrement & jump if not zero instrucion */
9050 /*-----------------------------------------------------------------*/
9051 static int genDjnz (iCode *ic, iCode *ifx)
9054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9059 /* if the if condition has a false label
9060 then we cannot save */
9064 /* if the minus is not of the form
9066 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9067 !IS_OP_LITERAL(IC_RIGHT(ic)))
9070 if (operandLitValue(IC_RIGHT(ic)) != 1)
9073 /* if the size of this greater than one then no
9075 if (getSize(operandType(IC_RESULT(ic))) > 1)
9078 /* otherwise we can save BIG */
9079 lbl = newiTempLabel(NULL);
9080 lbl1= newiTempLabel(NULL);
9082 aopOp(IC_RESULT(ic),ic,FALSE);
9084 if (IS_AOP_PREG(IC_RESULT(ic))) {
9085 pic14_emitcode("dec","%s",
9086 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9087 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9088 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9092 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9093 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9095 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9096 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9099 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9100 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9101 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9102 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9105 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9110 /*-----------------------------------------------------------------*/
9111 /* genReceive - generate code for a receive iCode */
9112 /*-----------------------------------------------------------------*/
9113 static void genReceive (iCode *ic)
9115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9117 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9118 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9119 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9121 int size = getSize(operandType(IC_RESULT(ic)));
9122 int offset = fReturnSizePic - size;
9124 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9125 fReturn[fReturnSizePic - offset - 1] : "acc"));
9128 aopOp(IC_RESULT(ic),ic,FALSE);
9129 size = AOP_SIZE(IC_RESULT(ic));
9132 pic14_emitcode ("pop","acc");
9133 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9138 aopOp(IC_RESULT(ic),ic,FALSE);
9140 assignResultValue(IC_RESULT(ic));
9143 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9146 /*-----------------------------------------------------------------*/
9147 /* genpic14Code - generate code for pic14 based controllers */
9148 /*-----------------------------------------------------------------*/
9150 * At this point, ralloc.c has gone through the iCode and attempted
9151 * to optimize in a way suitable for a PIC. Now we've got to generate
9152 * PIC instructions that correspond to the iCode.
9154 * Once the instructions are generated, we'll pass through both the
9155 * peep hole optimizer and the pCode optimizer.
9156 *-----------------------------------------------------------------*/
9158 void genpic14Code (iCode *lic)
9163 lineHead = lineCurr = NULL;
9165 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9168 /* if debug information required */
9169 /* if (options.debug && currFunc) { */
9171 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9173 if (IS_STATIC(currFunc->etype)) {
9174 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9175 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9177 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9178 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9184 for (ic = lic ; ic ; ic = ic->next ) {
9186 DEBUGpic14_emitcode(";ic","");
9187 if ( cln != ic->lineno ) {
9188 if ( options.debug ) {
9190 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9191 FileBaseName(ic->filename),ic->lineno,
9192 ic->level,ic->block);
9195 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9198 /* if the result is marked as
9199 spilt and rematerializable or code for
9200 this has already been generated then
9202 if (resultRemat(ic) || ic->generated )
9205 /* depending on the operation */
9224 /* IPOP happens only when trying to restore a
9225 spilt live range, if there is an ifx statement
9226 following this pop then the if statement might
9227 be using some of the registers being popped which
9228 would destory the contents of the register so
9229 we need to check for this condition and handle it */
9231 ic->next->op == IFX &&
9232 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9233 genIfx (ic->next,ic);
9251 genEndFunction (ic);
9271 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9288 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9292 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9299 /* note these two are xlated by algebraic equivalence
9300 during parsing SDCC.y */
9301 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9302 "got '>=' or '<=' shouldn't have come here");
9306 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9318 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9322 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9326 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9353 case GET_VALUE_AT_ADDRESS:
9358 if (POINTER_SET(ic))
9385 addSet(&_G.sendSet,ic);
9394 /* now we are ready to call the
9395 peep hole optimizer */
9396 if (!options.nopeep) {
9397 printf("peep hole optimizing\n");
9398 peepHole (&lineHead);
9400 /* now do the actual printing */
9401 printLine (lineHead,codeOutFile);
9403 printf("printing pBlock\n\n");
9404 printpBlock(stdout,pb);