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 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
71 /* max_key keeps track of the largest label number used in
72 a function. This is then used to adjust the label offset
73 for the next function.
76 static int GpsuedoStkPtr=0;
78 pCodeOp *popGetImmd(char *name, unsigned int offset);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
85 /* this is the down and dirty file with all kinds of
86 kludgy & hacky stuff. This is what it is all about
87 CODE GENERATION for a specific MCU . some of the
88 routines may be reusable, will have to see */
90 static char *zero = "#0x00";
91 static char *one = "#0x01";
92 static char *spname = "sp";
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
99 static char *accUse[] = {"a","b"};
101 //static short rbank = -1;
113 /* Resolved ifx structure. This structure stores information
114 about an iCode ifx that makes it easier to generate code.
116 typedef struct resolvedIfx {
117 symbol *lbl; /* pointer to a label */
118 int condition; /* true or false ifx */
119 int generated; /* set true when the code associated with the ifx
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
131 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
138 /*-----------------------------------------------------------------*/
139 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
140 /* exponent of 2 is returned, otherwise -1 is */
142 /* note that this is similar to the function `powof2' in SDCCsymt */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
150 if( (num & (num-1)) == 0) {
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174 ((result) ? AOP_SIZE(result) : 0));
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
183 ((result) ? AopType(AOP_TYPE(result)) : "-"),
184 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185 ((left) ? AopType(AOP_TYPE(left)) : "-"),
186 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
187 ((right) ? AopType(AOP_TYPE(right)) : "-"),
188 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 char lb[INITIAL_INLINEASM];
205 sprintf(lb,"%s\t",inst);
207 sprintf(lb,"%s",inst);
208 vsprintf(lb+(strlen(lb)),fmt,ap);
212 while (isspace(*lbp)) lbp++;
215 lineCurr = (lineCurr ?
216 connectLine(lineCurr,newLineNode(lb)) :
217 (lineHead = newLineNode(lb)));
218 lineCurr->isInline = _G.inLine;
219 lineCurr->isDebug = _G.debugLine;
221 addpCode2pBlock(pb,newpCodeCharP(lb));
227 void emitpLabel(int key)
229 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
236 addpCode2pBlock(pb,newpCode(poc,pcop));
238 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
241 void emitpcodeNULLop(PIC_OPCODE poc)
244 addpCode2pBlock(pb,newpCode(poc,NULL));
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
254 char lb[INITIAL_INLINEASM];
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
278 addpCode2pBlock(pb,newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 /* the logic: if r0 & r1 used in the instruction
293 then we are in trouble otherwise */
295 /* first check if r0 & r1 are used by this
296 instruction, in which case we are in trouble */
297 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
303 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
306 /* if no usage of r0 then return it */
307 if (!r0iu && !r0ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309 (*aopp)->type = AOP_R0;
311 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314 /* if no usage of r1 then return it */
315 if (!r1iu && !r1ou) {
316 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317 (*aopp)->type = AOP_R1;
319 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322 /* now we know they both have usage */
323 /* if r0 not used in this instruction */
325 /* push it if not already pushed */
327 //pic14_emitcode ("push","%s",
328 // pic14_regWithIdx(R0_IDX)->dname);
332 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333 (*aopp)->type = AOP_R0;
335 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338 /* if r1 not used then */
341 /* push it if not already pushed */
343 //pic14_emitcode ("push","%s",
344 // pic14_regWithIdx(R1_IDX)->dname);
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
350 return pic14_regWithIdx(R1_IDX);
354 /* I said end of world but not quite end of world yet */
355 /* if this is a result then we can push it on the stack*/
357 (*aopp)->type = AOP_STK;
361 /* other wise this is true end of the world */
362 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363 "getFreePtr should never reach here");
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
374 aop = Safe_calloc(1,sizeof(asmop));
379 static void genSetDPTR(int n)
383 pic14_emitcode(";", "Select standard DPTR");
384 pic14_emitcode("mov", "dps, #0x00");
388 pic14_emitcode(";", "Select alternate DPTR");
389 pic14_emitcode("mov", "dps, #0x01");
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for */
395 /* generating code */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
404 resIfx->condition = 1; /* assume that the ifx is true */
405 resIfx->generated = 0; /* indicate that the ifx has not been used */
408 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
409 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410 __FUNCTION__,__LINE__,resIfx->lbl->key);
413 resIfx->lbl = IC_TRUE(ifx);
415 resIfx->lbl = IC_FALSE(ifx);
416 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
424 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
433 return PTR_TYPE(SPEC_OCLS(etype));
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
443 memmap *space= SPEC_OCLS(sym->etype);
445 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446 /* if already has one */
450 /* assign depending on the storage class */
451 /* if it is on the stack or indirectly addressable */
452 /* space we need to assign either r0 or r1 to it */
453 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454 sym->aop = aop = newAsmop(0);
455 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456 aop->size = getSize(sym->type);
458 /* now assign the address of the variable to
459 the pointer register */
460 if (aop->type != AOP_STK) {
464 pic14_emitcode("push","acc");
466 pic14_emitcode("mov","a,_bp");
467 pic14_emitcode("add","a,#0x%02x",
469 ((char)(sym->stack - _G.nRegsSaved )) :
470 ((char)sym->stack)) & 0xff);
471 pic14_emitcode("mov","%s,a",
472 aop->aopu.aop_ptr->name);
475 pic14_emitcode("pop","acc");
477 pic14_emitcode("mov","%s,#%s",
478 aop->aopu.aop_ptr->name,
480 aop->paged = space->paged;
482 aop->aopu.aop_stk = sym->stack;
486 if (sym->onStack && options.stack10bit)
488 /* It's on the 10 bit stack, which is located in
492 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 pic14_emitcode("push","acc");
497 pic14_emitcode("mov","a,_bp");
498 pic14_emitcode("add","a,#0x%02x",
500 ((char)(sym->stack - _G.nRegsSaved )) :
501 ((char)sym->stack)) & 0xff);
504 pic14_emitcode ("mov","dpx1,#0x40");
505 pic14_emitcode ("mov","dph1,#0x00");
506 pic14_emitcode ("mov","dpl1, a");
510 pic14_emitcode("pop","acc");
512 sym->aop = aop = newAsmop(AOP_DPTR2);
513 aop->size = getSize(sym->type);
517 //DEBUGpic14_emitcode(";","%d",__LINE__);
518 /* if in bit space */
519 if (IN_BITSPACE(space)) {
520 sym->aop = aop = newAsmop (AOP_CRY);
521 aop->aopu.aop_dir = sym->rname ;
522 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526 /* if it is in direct space */
527 if (IN_DIRSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_DIR);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
535 /* special case for a function */
536 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_IMMD);
538 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540 strcpy(aop->aopu.aop_immd,sym->rname);
541 aop->size = FPTRSIZE;
542 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547 /* only remaining is far space */
548 /* in which case DPTR gets the address */
549 sym->aop = aop = newAsmop(AOP_DPTR);
550 pic14_emitcode ("mov","dptr,#%s", sym->rname);
551 aop->size = getSize(sym->type);
553 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
554 /* if it is in code space */
555 if (IN_CODESPACE(space))
561 /*-----------------------------------------------------------------*/
562 /* aopForRemat - rematerialzes an object */
563 /*-----------------------------------------------------------------*/
564 static asmop *aopForRemat (symbol *sym)
566 iCode *ic = sym->rematiCode;
567 //X asmop *aop = newAsmop(AOP_IMMD);
568 asmop *aop = newAsmop(AOP_PCODE);
572 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
576 val += (int) operandLitValue(IC_RIGHT(ic));
577 } else if (ic->op == '-') {
578 val -= (int) operandLitValue(IC_RIGHT(ic));
582 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
586 sprintf(buffer,"(%s %c 0x%04x)",
587 OP_SYMBOL(IC_LEFT(ic))->rname,
588 val >= 0 ? '+' : '-',
590 fprintf(stderr,"hmmm %s\n",buffer);
592 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
594 //ic = sym->rematiCode;
595 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
596 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,val);
597 DEBUGpic14_emitcode(";"," rname %s, val %d ",OP_SYMBOL(IC_LEFT(ic))->rname,val);
598 //X aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
599 //X strcpy(aop->aopu.aop_immd,buffer);
601 allocDirReg (IC_LEFT(ic));
606 int aopIdx (asmop *aop, int offset)
611 if(aop->type != AOP_REG)
614 return aop->aopu.aop_reg[offset]->rIdx;
617 /*-----------------------------------------------------------------*/
618 /* regsInCommon - two operands have some registers in common */
619 /*-----------------------------------------------------------------*/
620 static bool regsInCommon (operand *op1, operand *op2)
625 /* if they have registers in common */
626 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
629 sym1 = OP_SYMBOL(op1);
630 sym2 = OP_SYMBOL(op2);
632 if (sym1->nRegs == 0 || sym2->nRegs == 0)
635 for (i = 0 ; i < sym1->nRegs ; i++) {
640 for (j = 0 ; j < sym2->nRegs ;j++ ) {
644 if (sym2->regs[j] == sym1->regs[i])
652 /*-----------------------------------------------------------------*/
653 /* operandsEqu - equivalent */
654 /*-----------------------------------------------------------------*/
655 static bool operandsEqu ( operand *op1, operand *op2)
659 /* if they not symbols */
660 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
663 sym1 = OP_SYMBOL(op1);
664 sym2 = OP_SYMBOL(op2);
666 /* if both are itemps & one is spilt
667 and the other is not then false */
668 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
669 sym1->isspilt != sym2->isspilt )
672 /* if they are the same */
676 if (strcmp(sym1->rname,sym2->rname) == 0)
680 /* if left is a tmp & right is not */
684 (sym1->usl.spillLoc == sym2))
691 (sym2->usl.spillLoc == sym1))
697 /*-----------------------------------------------------------------*/
698 /* pic14_sameRegs - two asmops have the same registers */
699 /*-----------------------------------------------------------------*/
700 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
707 if (aop1->type != AOP_REG ||
708 aop2->type != AOP_REG )
711 if (aop1->size != aop2->size )
714 for (i = 0 ; i < aop1->size ; i++ )
715 if (aop1->aopu.aop_reg[i] !=
716 aop2->aopu.aop_reg[i] )
722 /*-----------------------------------------------------------------*/
723 /* aopOp - allocates an asmop for an operand : */
724 /*-----------------------------------------------------------------*/
725 void aopOp (operand *op, iCode *ic, bool result)
734 // DEBUGpic14_emitcode(";","%d",__LINE__);
735 /* if this a literal */
736 if (IS_OP_LITERAL(op)) {
737 op->aop = aop = newAsmop(AOP_LIT);
738 aop->aopu.aop_lit = op->operand.valOperand;
739 aop->size = getSize(operandType(op));
744 sym_link *type = operandType(op);
745 if(IS_PTR_CONST(type))
746 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
749 /* if already has a asmop then continue */
753 /* if the underlying symbol has a aop */
754 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
755 DEBUGpic14_emitcode(";","%d",__LINE__);
756 op->aop = OP_SYMBOL(op)->aop;
760 /* if this is a true symbol */
761 if (IS_TRUE_SYMOP(op)) {
762 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
763 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
767 /* this is a temporary : this has
773 e) can be a return use only */
778 /* if the type is a conditional */
779 if (sym->regType == REG_CND) {
780 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
785 /* if it is spilt then two situations
787 b) has a spill location */
788 if (sym->isspilt || sym->nRegs == 0) {
790 DEBUGpic14_emitcode(";","%d",__LINE__);
791 /* rematerialize it NOW */
793 sym->aop = op->aop = aop =
795 aop->size = getSize(sym->type);
796 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
802 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
803 aop->size = getSize(sym->type);
804 for ( i = 0 ; i < 2 ; i++ )
805 aop->aopu.aop_str[i] = accUse[i];
806 DEBUGpic14_emitcode(";","%d",__LINE__);
812 aop = op->aop = sym->aop = newAsmop(AOP_STR);
813 aop->size = getSize(sym->type);
814 for ( i = 0 ; i < fReturnSizePic ; i++ )
815 aop->aopu.aop_str[i] = fReturn[i];
816 DEBUGpic14_emitcode(";","%d",__LINE__);
820 /* else spill location */
821 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
822 /* force a new aop if sizes differ */
823 sym->usl.spillLoc->aop = NULL;
825 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
826 __FUNCTION__,__LINE__,
827 sym->usl.spillLoc->rname,
828 sym->rname, sym->usl.spillLoc->offset);
829 // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
830 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
831 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,sym->usl.spillLoc->offset);
832 //allocDirReg (IC_LEFT(ic));
833 aop->size = getSize(sym->type);
839 sym_link *type = operandType(op);
840 if(IS_PTR_CONST(type))
841 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
844 /* must be in a register */
845 sym->aop = op->aop = aop = newAsmop(AOP_REG);
846 aop->size = sym->nRegs;
847 for ( i = 0 ; i < sym->nRegs ;i++)
848 aop->aopu.aop_reg[i] = sym->regs[i];
851 /*-----------------------------------------------------------------*/
852 /* freeAsmop - free up the asmop given to an operand */
853 /*----------------------------------------------------------------*/
854 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
871 /* depending on the asmop type only three cases need work AOP_RO
872 , AOP_R1 && AOP_STK */
878 pic14_emitcode ("pop","ar0");
882 bitVectUnSetBit(ic->rUsed,R0_IDX);
888 pic14_emitcode ("pop","ar1");
892 bitVectUnSetBit(ic->rUsed,R1_IDX);
898 int stk = aop->aopu.aop_stk + aop->size;
899 bitVectUnSetBit(ic->rUsed,R0_IDX);
900 bitVectUnSetBit(ic->rUsed,R1_IDX);
902 getFreePtr(ic,&aop,FALSE);
904 if (options.stack10bit)
906 /* I'm not sure what to do here yet... */
909 "*** Warning: probably generating bad code for "
910 "10 bit stack mode.\n");
914 pic14_emitcode ("mov","a,_bp");
915 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
916 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
918 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
922 pic14_emitcode("pop","acc");
923 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
925 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
928 freeAsmop(op,NULL,ic,TRUE);
930 pic14_emitcode("pop","ar0");
935 pic14_emitcode("pop","ar1");
943 /* all other cases just dealloc */
947 OP_SYMBOL(op)->aop = NULL;
948 /* if the symbol has a spill */
950 SPIL_LOC(op)->aop = NULL;
955 /*-----------------------------------------------------------------*/
956 /* aopGet - for fetching value of the aop */
957 /*-----------------------------------------------------------------*/
958 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
963 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
964 /* offset is greater than
966 if (offset > (aop->size - 1) &&
967 aop->type != AOP_LIT)
970 /* depending on type */
975 DEBUGpic14_emitcode(";","%d",__LINE__);
976 /* if we need to increment it */
977 while (offset > aop->coff) {
978 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
982 while (offset < aop->coff) {
983 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
989 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
990 return (dname ? "acc" : "a");
992 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
993 rs = Safe_calloc(1,strlen(s)+1);
999 DEBUGpic14_emitcode(";","%d",__LINE__);
1000 if (aop->type == AOP_DPTR2)
1005 while (offset > aop->coff) {
1006 pic14_emitcode ("inc","dptr");
1010 while (offset < aop->coff) {
1011 pic14_emitcode("lcall","__decdptr");
1017 pic14_emitcode("clr","a");
1018 pic14_emitcode("movc","a,@a+dptr");
1021 pic14_emitcode("movx","a,@dptr");
1024 if (aop->type == AOP_DPTR2)
1029 return (dname ? "acc" : "a");
1034 sprintf (s,"%s",aop->aopu.aop_immd);
1037 sprintf(s,"(%s >> %d)",
1042 aop->aopu.aop_immd);
1043 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1044 rs = Safe_calloc(1,strlen(s)+1);
1050 sprintf(s,"(%s + %d)",
1053 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1055 sprintf(s,"%s",aop->aopu.aop_dir);
1056 rs = Safe_calloc(1,strlen(s)+1);
1062 // return aop->aopu.aop_reg[offset]->dname;
1064 return aop->aopu.aop_reg[offset]->name;
1067 //pic14_emitcode(";","%d",__LINE__);
1068 return aop->aopu.aop_dir;
1071 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1072 return "AOP_accumulator_bug";
1075 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1076 rs = Safe_calloc(1,strlen(s)+1);
1081 DEBUGpic14_emitcode(";","%d",__LINE__);
1082 aop->coff = offset ;
1083 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1087 return aop->aopu.aop_str[offset];
1091 pCodeOp *pcop = aop->aopu.pcop;
1092 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1094 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1095 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1096 sprintf(s,"%s", pcop->name);
1098 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1101 rs = Safe_calloc(1,strlen(s)+1);
1107 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1108 "aopget got unsupported aop->type");
1113 /*-----------------------------------------------------------------*/
1114 /* popGetTempReg - create a new temporary pCodeOp */
1115 /*-----------------------------------------------------------------*/
1116 pCodeOp *popGetTempReg(void)
1121 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1122 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1123 PCOR(pcop)->r->wasUsed=1;
1124 PCOR(pcop)->r->isFree=0;
1130 /*-----------------------------------------------------------------*/
1131 /* popGetTempReg - create a new temporary pCodeOp */
1132 /*-----------------------------------------------------------------*/
1133 void popReleaseTempReg(pCodeOp *pcop)
1136 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1137 PCOR(pcop)->r->isFree = 1;
1140 /*-----------------------------------------------------------------*/
1141 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1142 /*-----------------------------------------------------------------*/
1143 pCodeOp *popGetLabel(unsigned int key)
1146 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1151 return newpCodeOpLabel(NULL,key+100+labelOffset);
1154 /*-----------------------------------------------------------------*/
1155 /* popCopyReg - copy a pcode operator */
1156 /*-----------------------------------------------------------------*/
1157 pCodeOp *popCopyReg(pCodeOpReg *pc)
1161 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1162 pcor->pcop.type = pc->pcop.type;
1164 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1165 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1167 pcor->pcop.name = NULL;
1170 pcor->rIdx = pc->rIdx;
1173 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1177 /*-----------------------------------------------------------------*/
1178 /* popGet - asm operator to pcode operator conversion */
1179 /*-----------------------------------------------------------------*/
1180 pCodeOp *popGetLit(unsigned int lit)
1183 return newpCodeOpLit(lit);
1187 /*-----------------------------------------------------------------*/
1188 /* popGetImmd - asm operator to pcode immediate conversion */
1189 /*-----------------------------------------------------------------*/
1190 pCodeOp *popGetImmd(char *name, unsigned int offset)
1193 return newpCodeOpImmd(name, offset);
1197 /*-----------------------------------------------------------------*/
1198 /* popGet - asm operator to pcode operator conversion */
1199 /*-----------------------------------------------------------------*/
1200 pCodeOp *popGetWithString(char *str)
1206 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1210 pcop = newpCodeOp(str,PO_STR);
1215 pCodeOp *popRegFromString(char *str)
1218 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1219 pcop->type = PO_DIR;
1221 DEBUGpic14_emitcode(";","%d",__LINE__);
1222 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1227 pCodeOp *popRegFromIdx(int rIdx)
1231 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1232 __FUNCTION__,__LINE__,rIdx);
1234 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1236 PCOR(pcop)->rIdx = rIdx;
1237 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1238 PCOR(pcop)->r->isFree = 0;
1239 PCOR(pcop)->r->wasUsed = 1;
1241 pcop->type = PCOR(pcop)->r->pc_type;
1246 /*-----------------------------------------------------------------*/
1247 /* popGet - asm operator to pcode operator conversion */
1248 /*-----------------------------------------------------------------*/
1249 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1251 //char *s = buffer ;
1256 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1257 /* offset is greater than
1260 if (offset > (aop->size - 1) &&
1261 aop->type != AOP_LIT)
1262 return NULL; //zero;
1264 /* depending on type */
1265 switch (aop->type) {
1272 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1276 DEBUGpic14_emitcode(";","%d",__LINE__);
1277 return popGetImmd(aop->aopu.aop_immd,offset);
1280 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1281 pcop->type = PO_DIR;
1285 sprintf(s,"(%s + %d)",
1289 sprintf(s,"%s",aop->aopu.aop_dir);
1290 pcop->name = Safe_calloc(1,strlen(s)+1);
1291 strcpy(pcop->name,s);
1293 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1294 strcpy(pcop->name,aop->aopu.aop_dir);
1295 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1296 if(PCOR(pcop)->r == NULL) {
1297 fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1298 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1301 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1302 PCOR(pcop)->instance = offset;
1308 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1310 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1311 PCOR(pcop)->rIdx = rIdx;
1312 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1313 PCOR(pcop)->instance = offset;
1314 pcop->type = PCOR(pcop)->r->pc_type;
1315 //rs = aop->aopu.aop_reg[offset]->name;
1316 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1321 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1322 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1323 if(PCOR(pcop)->r == NULL)
1324 fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1328 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1331 DEBUGpic14_emitcode(";","%d",__LINE__);
1332 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1334 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1335 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1336 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1337 pcop->type = PCOR(pcop)->r->pc_type;
1338 pcop->name = PCOR(pcop)->r->name;
1344 DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1345 return pCodeOpCopy(aop->aopu.pcop);
1348 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1349 "popGet got unsupported aop->type");
1352 /*-----------------------------------------------------------------*/
1353 /* aopPut - puts a string for a aop */
1354 /*-----------------------------------------------------------------*/
1355 void aopPut (asmop *aop, char *s, int offset)
1360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1362 if (aop->size && offset > ( aop->size - 1)) {
1363 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1364 "aopPut got offset > aop->size");
1368 /* will assign value to value */
1369 /* depending on where it is ofcourse */
1370 switch (aop->type) {
1373 sprintf(d,"(%s + %d)",
1374 aop->aopu.aop_dir,offset);
1375 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1378 sprintf(d,"%s",aop->aopu.aop_dir);
1381 DEBUGpic14_emitcode(";","%d",__LINE__);
1383 pic14_emitcode("movf","%s,w",s);
1384 pic14_emitcode("movwf","%s",d);
1387 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1388 if(offset >= aop->size) {
1389 emitpcode(POC_CLRF,popGet(aop,offset));
1392 emitpcode(POC_MOVLW,popGetImmd(s,offset));
1395 emitpcode(POC_MOVWF,popGet(aop,offset));
1402 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1403 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1406 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 )
1414 pic14_emitcode("mov","%s,%s ; %d",
1415 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1420 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1422 pic14_emitcode("movwf","%s",
1423 aop->aopu.aop_reg[offset]->name);
1426 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1427 pcop->type = PO_GPR_REGISTER;
1429 PCOR(pcop)->rIdx = -1;
1430 PCOR(pcop)->r = NULL;
1432 DEBUGpic14_emitcode(";","%d",__LINE__);
1433 pcop->name = Safe_strdup(s);
1434 emitpcode(POC_MOVFW,pcop);
1436 emitpcode(POC_MOVWF,popGet(aop,offset));
1444 if (aop->type == AOP_DPTR2)
1450 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1451 "aopPut writting to code space");
1455 while (offset > aop->coff) {
1457 pic14_emitcode ("inc","dptr");
1460 while (offset < aop->coff) {
1462 pic14_emitcode("lcall","__decdptr");
1467 /* if not in accumulater */
1470 pic14_emitcode ("movx","@dptr,a");
1472 if (aop->type == AOP_DPTR2)
1480 while (offset > aop->coff) {
1482 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1484 while (offset < aop->coff) {
1486 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1492 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1497 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1499 if (strcmp(s,"r0") == 0 ||
1500 strcmp(s,"r1") == 0 ||
1501 strcmp(s,"r2") == 0 ||
1502 strcmp(s,"r3") == 0 ||
1503 strcmp(s,"r4") == 0 ||
1504 strcmp(s,"r5") == 0 ||
1505 strcmp(s,"r6") == 0 ||
1506 strcmp(s,"r7") == 0 ) {
1508 sprintf(buffer,"a%s",s);
1509 pic14_emitcode("mov","@%s,%s",
1510 aop->aopu.aop_ptr->name,buffer);
1512 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1517 if (strcmp(s,"a") == 0)
1518 pic14_emitcode("push","acc");
1520 pic14_emitcode("push","%s",s);
1525 /* if bit variable */
1526 if (!aop->aopu.aop_dir) {
1527 pic14_emitcode("clr","a");
1528 pic14_emitcode("rlc","a");
1531 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1534 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1537 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1539 lbl = newiTempLabel(NULL);
1541 if (strcmp(s,"a")) {
1544 pic14_emitcode("clr","c");
1545 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1546 pic14_emitcode("cpl","c");
1547 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1548 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1555 if (strcmp(aop->aopu.aop_str[offset],s))
1556 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1561 if (!offset && (strcmp(s,"acc") == 0))
1564 if (strcmp(aop->aopu.aop_str[offset],s))
1565 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1569 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1570 "aopPut got unsupported aop->type");
1576 /*-----------------------------------------------------------------*/
1577 /* reAdjustPreg - points a register back to where it should */
1578 /*-----------------------------------------------------------------*/
1579 static void reAdjustPreg (asmop *aop)
1583 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1585 if ((size = aop->size) <= 1)
1588 switch (aop->type) {
1592 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1596 if (aop->type == AOP_DPTR2)
1602 pic14_emitcode("lcall","__decdptr");
1605 if (aop->type == AOP_DPTR2)
1615 /*-----------------------------------------------------------------*/
1616 /* genNotFloat - generates not for float operations */
1617 /*-----------------------------------------------------------------*/
1618 static void genNotFloat (operand *op, operand *res)
1624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1625 /* we will put 127 in the first byte of
1627 aopPut(AOP(res),"#127",0);
1628 size = AOP_SIZE(op) - 1;
1631 l = aopGet(op->aop,offset++,FALSE,FALSE);
1635 pic14_emitcode("orl","a,%s",
1637 offset++,FALSE,FALSE));
1639 tlbl = newiTempLabel(NULL);
1641 tlbl = newiTempLabel(NULL);
1642 aopPut(res->aop,one,1);
1643 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1644 aopPut(res->aop,zero,1);
1645 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1647 size = res->aop->size - 2;
1649 /* put zeros in the rest */
1651 aopPut(res->aop,zero,offset++);
1655 /*-----------------------------------------------------------------*/
1656 /* opIsGptr: returns non-zero if the passed operand is */
1657 /* a generic pointer type. */
1658 /*-----------------------------------------------------------------*/
1659 static int opIsGptr(operand *op)
1661 sym_link *type = operandType(op);
1663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1664 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1672 /*-----------------------------------------------------------------*/
1673 /* pic14_getDataSize - get the operand data size */
1674 /*-----------------------------------------------------------------*/
1675 int pic14_getDataSize(operand *op)
1677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1680 return AOP_SIZE(op);
1682 // tsd- in the pic port, the genptr size is 1, so this code here
1683 // fails. ( in the 8051 port, the size was 4).
1686 size = AOP_SIZE(op);
1687 if (size == GPTRSIZE)
1689 sym_link *type = operandType(op);
1690 if (IS_GENPTR(type))
1692 /* generic pointer; arithmetic operations
1693 * should ignore the high byte (pointer type).
1696 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1703 /*-----------------------------------------------------------------*/
1704 /* pic14_outAcc - output Acc */
1705 /*-----------------------------------------------------------------*/
1706 void pic14_outAcc(operand *result)
1709 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1710 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1713 size = pic14_getDataSize(result);
1715 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1718 /* unsigned or positive */
1720 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1725 /*-----------------------------------------------------------------*/
1726 /* pic14_outBitC - output a bit C */
1727 /*-----------------------------------------------------------------*/
1728 void pic14_outBitC(operand *result)
1731 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1732 /* if the result is bit */
1733 if (AOP_TYPE(result) == AOP_CRY)
1734 aopPut(AOP(result),"c",0);
1736 pic14_emitcode("clr","a ; %d", __LINE__);
1737 pic14_emitcode("rlc","a");
1738 pic14_outAcc(result);
1742 /*-----------------------------------------------------------------*/
1743 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1744 /*-----------------------------------------------------------------*/
1745 void pic14_toBoolean(operand *oper)
1747 int size = AOP_SIZE(oper) - 1;
1750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1752 if ( AOP_TYPE(oper) != AOP_ACC) {
1753 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1756 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1761 /*-----------------------------------------------------------------*/
1762 /* genNot - generate code for ! operation */
1763 /*-----------------------------------------------------------------*/
1764 static void genNot (iCode *ic)
1767 sym_link *optype = operandType(IC_LEFT(ic));
1770 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1771 /* assign asmOps to operand & result */
1772 aopOp (IC_LEFT(ic),ic,FALSE);
1773 aopOp (IC_RESULT(ic),ic,TRUE);
1775 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1776 /* if in bit space then a special case */
1777 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1778 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1779 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1780 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1782 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1783 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1784 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1789 /* if type float then do float */
1790 if (IS_FLOAT(optype)) {
1791 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1795 size = AOP_SIZE(IC_RESULT(ic));
1797 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1798 emitpcode(POC_ANDLW,popGetLit(1));
1799 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1802 pic14_toBoolean(IC_LEFT(ic));
1804 tlbl = newiTempLabel(NULL);
1805 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1806 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1807 pic14_outBitC(IC_RESULT(ic));
1810 /* release the aops */
1811 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1812 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1816 /*-----------------------------------------------------------------*/
1817 /* genCpl - generate code for complement */
1818 /*-----------------------------------------------------------------*/
1819 static void genCpl (iCode *ic)
1825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 /* assign asmOps to operand & result */
1827 aopOp (IC_LEFT(ic),ic,FALSE);
1828 aopOp (IC_RESULT(ic),ic,TRUE);
1830 /* if both are in bit space then
1832 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1833 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1835 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1836 pic14_emitcode("cpl","c");
1837 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1841 size = AOP_SIZE(IC_RESULT(ic));
1843 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1845 pic14_emitcode("cpl","a");
1846 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1851 /* release the aops */
1852 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1853 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1856 /*-----------------------------------------------------------------*/
1857 /* genUminusFloat - unary minus for floating points */
1858 /*-----------------------------------------------------------------*/
1859 static void genUminusFloat(operand *op,operand *result)
1861 int size ,offset =0 ;
1864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1865 /* for this we just need to flip the
1866 first it then copy the rest in place */
1867 size = AOP_SIZE(op) - 1;
1868 l = aopGet(AOP(op),3,FALSE,FALSE);
1872 pic14_emitcode("cpl","acc.7");
1873 aopPut(AOP(result),"a",3);
1877 aopGet(AOP(op),offset,FALSE,FALSE),
1883 /*-----------------------------------------------------------------*/
1884 /* genUminus - unary minus code generation */
1885 /*-----------------------------------------------------------------*/
1886 static void genUminus (iCode *ic)
1889 sym_link *optype, *rtype;
1892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1894 aopOp(IC_LEFT(ic),ic,FALSE);
1895 aopOp(IC_RESULT(ic),ic,TRUE);
1897 /* if both in bit space then special
1899 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1900 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1902 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1903 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1904 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1909 optype = operandType(IC_LEFT(ic));
1910 rtype = operandType(IC_RESULT(ic));
1912 /* if float then do float stuff */
1913 if (IS_FLOAT(optype)) {
1914 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1918 /* otherwise subtract from zero by taking the 2's complement */
1919 size = AOP_SIZE(IC_LEFT(ic));
1921 for(i=0; i<size; i++) {
1922 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1923 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1925 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1926 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1930 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1931 for(i=1; i<size; i++) {
1933 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1937 /* release the aops */
1938 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1939 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1942 /*-----------------------------------------------------------------*/
1943 /* saveRegisters - will look for a call and save the registers */
1944 /*-----------------------------------------------------------------*/
1945 static void saveRegisters(iCode *lic)
1952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 for (ic = lic ; ic ; ic = ic->next)
1955 if (ic->op == CALL || ic->op == PCALL)
1959 fprintf(stderr,"found parameter push with no function call\n");
1963 /* if the registers have been saved already then
1965 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1968 /* find the registers in use at this time
1969 and push them away to safety */
1970 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1974 if (options.useXstack) {
1975 if (bitVectBitValue(rsave,R0_IDX))
1976 pic14_emitcode("mov","b,r0");
1977 pic14_emitcode("mov","r0,%s",spname);
1978 for (i = 0 ; i < pic14_nRegs ; i++) {
1979 if (bitVectBitValue(rsave,i)) {
1981 pic14_emitcode("mov","a,b");
1983 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1984 pic14_emitcode("movx","@r0,a");
1985 pic14_emitcode("inc","r0");
1988 pic14_emitcode("mov","%s,r0",spname);
1989 if (bitVectBitValue(rsave,R0_IDX))
1990 pic14_emitcode("mov","r0,b");
1992 //for (i = 0 ; i < pic14_nRegs ; i++) {
1993 // if (bitVectBitValue(rsave,i))
1994 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1997 dtype = operandType(IC_LEFT(ic));
1998 if (currFunc && dtype &&
1999 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2000 IFFUNC_ISISR(currFunc->type) &&
2003 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2006 /*-----------------------------------------------------------------*/
2007 /* unsaveRegisters - pop the pushed registers */
2008 /*-----------------------------------------------------------------*/
2009 static void unsaveRegisters (iCode *ic)
2014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2015 /* find the registers in use at this time
2016 and push them away to safety */
2017 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2020 if (options.useXstack) {
2021 pic14_emitcode("mov","r0,%s",spname);
2022 for (i = pic14_nRegs ; i >= 0 ; i--) {
2023 if (bitVectBitValue(rsave,i)) {
2024 pic14_emitcode("dec","r0");
2025 pic14_emitcode("movx","a,@r0");
2027 pic14_emitcode("mov","b,a");
2029 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2033 pic14_emitcode("mov","%s,r0",spname);
2034 if (bitVectBitValue(rsave,R0_IDX))
2035 pic14_emitcode("mov","r0,b");
2037 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2038 // if (bitVectBitValue(rsave,i))
2039 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2045 /*-----------------------------------------------------------------*/
2047 /*-----------------------------------------------------------------*/
2048 static void pushSide(operand * oper, int size)
2052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2054 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2055 if (AOP_TYPE(oper) != AOP_REG &&
2056 AOP_TYPE(oper) != AOP_DIR &&
2058 pic14_emitcode("mov","a,%s",l);
2059 pic14_emitcode("push","acc");
2061 pic14_emitcode("push","%s",l);
2066 /*-----------------------------------------------------------------*/
2067 /* assignResultValue - */
2068 /*-----------------------------------------------------------------*/
2069 static void assignResultValue(operand * oper)
2071 int size = AOP_SIZE(oper);
2073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2075 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2077 if(!GpsuedoStkPtr) {
2078 /* The last byte in the assignment is in W */
2080 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2085 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2087 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2092 /*-----------------------------------------------------------------*/
2093 /* genIpush - genrate code for pushing this gets a little complex */
2094 /*-----------------------------------------------------------------*/
2095 static void genIpush (iCode *ic)
2098 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2100 int size, offset = 0 ;
2104 /* if this is not a parm push : ie. it is spill push
2105 and spill push is always done on the local stack */
2106 if (!ic->parmPush) {
2108 /* and the item is spilt then do nothing */
2109 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2112 aopOp(IC_LEFT(ic),ic,FALSE);
2113 size = AOP_SIZE(IC_LEFT(ic));
2114 /* push it on the stack */
2116 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2121 pic14_emitcode("push","%s",l);
2126 /* this is a paramter push: in this case we call
2127 the routine to find the call and save those
2128 registers that need to be saved */
2131 /* then do the push */
2132 aopOp(IC_LEFT(ic),ic,FALSE);
2135 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2136 size = AOP_SIZE(IC_LEFT(ic));
2139 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2140 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2141 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2143 pic14_emitcode("mov","a,%s",l);
2144 pic14_emitcode("push","acc");
2146 pic14_emitcode("push","%s",l);
2149 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2153 /*-----------------------------------------------------------------*/
2154 /* genIpop - recover the registers: can happen only for spilling */
2155 /*-----------------------------------------------------------------*/
2156 static void genIpop (iCode *ic)
2158 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2163 /* if the temp was not pushed then */
2164 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2167 aopOp(IC_LEFT(ic),ic,FALSE);
2168 size = AOP_SIZE(IC_LEFT(ic));
2171 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2174 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2178 /*-----------------------------------------------------------------*/
2179 /* unsaverbank - restores the resgister bank from stack */
2180 /*-----------------------------------------------------------------*/
2181 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2183 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2189 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2191 if (options.useXstack) {
2193 r = getFreePtr(ic,&aop,FALSE);
2196 pic14_emitcode("mov","%s,_spx",r->name);
2197 pic14_emitcode("movx","a,@%s",r->name);
2198 pic14_emitcode("mov","psw,a");
2199 pic14_emitcode("dec","%s",r->name);
2202 pic14_emitcode ("pop","psw");
2205 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2206 if (options.useXstack) {
2207 pic14_emitcode("movx","a,@%s",r->name);
2208 //pic14_emitcode("mov","(%s+%d),a",
2209 // regspic14[i].base,8*bank+regspic14[i].offset);
2210 pic14_emitcode("dec","%s",r->name);
2213 pic14_emitcode("pop",""); //"(%s+%d)",
2214 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2217 if (options.useXstack) {
2219 pic14_emitcode("mov","_spx,%s",r->name);
2220 freeAsmop(NULL,aop,ic,TRUE);
2226 /*-----------------------------------------------------------------*/
2227 /* saverbank - saves an entire register bank on the stack */
2228 /*-----------------------------------------------------------------*/
2229 static void saverbank (int bank, iCode *ic, bool pushPsw)
2231 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2238 if (options.useXstack) {
2241 r = getFreePtr(ic,&aop,FALSE);
2242 pic14_emitcode("mov","%s,_spx",r->name);
2246 for (i = 0 ; i < pic14_nRegs ;i++) {
2247 if (options.useXstack) {
2248 pic14_emitcode("inc","%s",r->name);
2249 //pic14_emitcode("mov","a,(%s+%d)",
2250 // regspic14[i].base,8*bank+regspic14[i].offset);
2251 pic14_emitcode("movx","@%s,a",r->name);
2253 pic14_emitcode("push","");// "(%s+%d)",
2254 //regspic14[i].base,8*bank+regspic14[i].offset);
2258 if (options.useXstack) {
2259 pic14_emitcode("mov","a,psw");
2260 pic14_emitcode("movx","@%s,a",r->name);
2261 pic14_emitcode("inc","%s",r->name);
2262 pic14_emitcode("mov","_spx,%s",r->name);
2263 freeAsmop (NULL,aop,ic,TRUE);
2266 pic14_emitcode("push","psw");
2268 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2274 /*-----------------------------------------------------------------*/
2275 /* genCall - generates a call statement */
2276 /*-----------------------------------------------------------------*/
2277 static void genCall (iCode *ic)
2281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2283 /* if caller saves & we have not saved then */
2287 /* if we are calling a function that is not using
2288 the same register bank then we need to save the
2289 destination registers on the stack */
2290 dtype = operandType(IC_LEFT(ic));
2291 if (currFunc && dtype &&
2292 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2293 IFFUNC_ISISR(currFunc->type) &&
2296 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2298 /* if send set is not empty the assign */
2301 /* For the Pic port, there is no data stack.
2302 * So parameters passed to functions are stored
2303 * in registers. (The pCode optimizer will get
2304 * rid of most of these :).
2306 int psuedoStkPtr=-1;
2307 int firstTimeThruLoop = 1;
2309 _G.sendSet = reverseSet(_G.sendSet);
2311 /* First figure how many parameters are getting passed */
2312 for (sic = setFirstItem(_G.sendSet) ; sic ;
2313 sic = setNextItem(_G.sendSet)) {
2315 aopOp(IC_LEFT(sic),sic,FALSE);
2316 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2317 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2320 for (sic = setFirstItem(_G.sendSet) ; sic ;
2321 sic = setNextItem(_G.sendSet)) {
2322 int size, offset = 0;
2324 aopOp(IC_LEFT(sic),sic,FALSE);
2325 size = AOP_SIZE(IC_LEFT(sic));
2329 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2330 AopType(AOP_TYPE(IC_LEFT(sic))));
2332 if(!firstTimeThruLoop) {
2333 /* If this is not the first time we've been through the loop
2334 * then we need to save the parameter in a temporary
2335 * register. The last byte of the last parameter is
2337 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2340 firstTimeThruLoop=0;
2342 //if (strcmp(l,fReturn[offset])) {
2344 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2345 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2346 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2348 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2353 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2358 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2359 OP_SYMBOL(IC_LEFT(ic))->rname :
2360 OP_SYMBOL(IC_LEFT(ic))->name));
2363 /* if we need assign a result value */
2364 if ((IS_ITEMP(IC_RESULT(ic)) &&
2365 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2366 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2367 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2370 aopOp(IC_RESULT(ic),ic,FALSE);
2373 assignResultValue(IC_RESULT(ic));
2375 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2376 AopType(AOP_TYPE(IC_RESULT(ic))));
2378 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2381 /* adjust the stack for parameters if
2383 if (ic->parmBytes) {
2385 if (ic->parmBytes > 3) {
2386 pic14_emitcode("mov","a,%s",spname);
2387 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2388 pic14_emitcode("mov","%s,a",spname);
2390 for ( i = 0 ; i < ic->parmBytes ;i++)
2391 pic14_emitcode("dec","%s",spname);
2395 /* if register bank was saved then pop them */
2397 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2399 /* if we hade saved some registers then unsave them */
2400 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2401 unsaveRegisters (ic);
2406 /*-----------------------------------------------------------------*/
2407 /* genPcall - generates a call by pointer statement */
2408 /*-----------------------------------------------------------------*/
2409 static void genPcall (iCode *ic)
2412 symbol *rlbl = newiTempLabel(NULL);
2415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2416 /* if caller saves & we have not saved then */
2420 /* if we are calling a function that is not using
2421 the same register bank then we need to save the
2422 destination registers on the stack */
2423 dtype = operandType(IC_LEFT(ic));
2424 if (currFunc && dtype &&
2425 IFFUNC_ISISR(currFunc->type) &&
2426 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2427 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2430 /* push the return address on to the stack */
2431 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2432 pic14_emitcode("push","acc");
2433 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2434 pic14_emitcode("push","acc");
2436 if (options.model == MODEL_FLAT24)
2438 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2439 pic14_emitcode("push","acc");
2442 /* now push the calling address */
2443 aopOp(IC_LEFT(ic),ic,FALSE);
2445 pushSide(IC_LEFT(ic), FPTRSIZE);
2447 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2449 /* if send set is not empty the assign */
2453 for (sic = setFirstItem(_G.sendSet) ; sic ;
2454 sic = setNextItem(_G.sendSet)) {
2455 int size, offset = 0;
2456 aopOp(IC_LEFT(sic),sic,FALSE);
2457 size = AOP_SIZE(IC_LEFT(sic));
2459 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2461 if (strcmp(l,fReturn[offset]))
2462 pic14_emitcode("mov","%s,%s",
2467 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2472 pic14_emitcode("ret","");
2473 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2476 /* if we need assign a result value */
2477 if ((IS_ITEMP(IC_RESULT(ic)) &&
2478 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2479 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2480 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2483 aopOp(IC_RESULT(ic),ic,FALSE);
2486 assignResultValue(IC_RESULT(ic));
2488 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2491 /* adjust the stack for parameters if
2493 if (ic->parmBytes) {
2495 if (ic->parmBytes > 3) {
2496 pic14_emitcode("mov","a,%s",spname);
2497 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2498 pic14_emitcode("mov","%s,a",spname);
2500 for ( i = 0 ; i < ic->parmBytes ;i++)
2501 pic14_emitcode("dec","%s",spname);
2505 /* if register bank was saved then unsave them */
2506 if (currFunc && dtype &&
2507 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2508 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2510 /* if we hade saved some registers then
2513 unsaveRegisters (ic);
2517 /*-----------------------------------------------------------------*/
2518 /* resultRemat - result is rematerializable */
2519 /*-----------------------------------------------------------------*/
2520 static int resultRemat (iCode *ic)
2522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2523 if (SKIP_IC(ic) || ic->op == IFX)
2526 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2527 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2528 if (sym->remat && !POINTER_SET(ic))
2535 #if defined(__BORLANDC__) || defined(_MSC_VER)
2536 #define STRCASECMP stricmp
2538 #define STRCASECMP strcasecmp
2542 /*-----------------------------------------------------------------*/
2543 /* inExcludeList - return 1 if the string is in exclude Reg list */
2544 /*-----------------------------------------------------------------*/
2545 static bool inExcludeList(char *s)
2547 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2550 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2551 if (options.excludeRegs[i] &&
2552 STRCASECMP(options.excludeRegs[i],"none") == 0)
2555 for ( i = 0 ; options.excludeRegs[i]; i++) {
2556 if (options.excludeRegs[i] &&
2557 STRCASECMP(s,options.excludeRegs[i]) == 0)
2564 /*-----------------------------------------------------------------*/
2565 /* genFunction - generated code for function entry */
2566 /*-----------------------------------------------------------------*/
2567 static void genFunction (iCode *ic)
2572 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2574 labelOffset += (max_key+4);
2578 /* create the function header */
2579 pic14_emitcode(";","-----------------------------------------");
2580 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2581 pic14_emitcode(";","-----------------------------------------");
2583 pic14_emitcode("","%s:",sym->rname);
2584 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2586 ftype = operandType(IC_LEFT(ic));
2588 /* if critical function then turn interrupts off */
2589 if (IFFUNC_ISCRITICAL(ftype))
2590 pic14_emitcode("clr","ea");
2592 /* here we need to generate the equates for the
2593 register bank if required */
2595 if (FUNC_REGBANK(ftype) != rbank) {
2598 rbank = FUNC_REGBANK(ftype);
2599 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2600 if (strcmp(regspic14[i].base,"0") == 0)
2601 pic14_emitcode("","%s = 0x%02x",
2603 8*rbank+regspic14[i].offset);
2605 pic14_emitcode ("","%s = %s + 0x%02x",
2608 8*rbank+regspic14[i].offset);
2613 /* if this is an interrupt service routine then
2614 save acc, b, dpl, dph */
2615 if (IFFUNC_ISISR(sym->type)) {
2616 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2617 emitpcodeNULLop(POC_NOP);
2618 emitpcodeNULLop(POC_NOP);
2619 emitpcodeNULLop(POC_NOP);
2620 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2621 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2622 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2623 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2625 pBlockConvert2ISR(pb);
2627 if (!inExcludeList("acc"))
2628 pic14_emitcode ("push","acc");
2629 if (!inExcludeList("b"))
2630 pic14_emitcode ("push","b");
2631 if (!inExcludeList("dpl"))
2632 pic14_emitcode ("push","dpl");
2633 if (!inExcludeList("dph"))
2634 pic14_emitcode ("push","dph");
2635 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2637 pic14_emitcode ("push", "dpx");
2638 /* Make sure we're using standard DPTR */
2639 pic14_emitcode ("push", "dps");
2640 pic14_emitcode ("mov", "dps, #0x00");
2641 if (options.stack10bit)
2643 /* This ISR could conceivably use DPTR2. Better save it. */
2644 pic14_emitcode ("push", "dpl1");
2645 pic14_emitcode ("push", "dph1");
2646 pic14_emitcode ("push", "dpx1");
2649 /* if this isr has no bank i.e. is going to
2650 run with bank 0 , then we need to save more
2652 if (!FUNC_REGBANK(sym->type)) {
2654 /* if this function does not call any other
2655 function then we can be economical and
2656 save only those registers that are used */
2657 if (! IFFUNC_HASFCALL(sym->type)) {
2660 /* if any registers used */
2661 if (sym->regsUsed) {
2662 /* save the registers used */
2663 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2664 if (bitVectBitValue(sym->regsUsed,i) ||
2665 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2666 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2671 /* this function has a function call cannot
2672 determines register usage so we will have the
2674 saverbank(0,ic,FALSE);
2679 /* if callee-save to be used for this function
2680 then save the registers being used in this function */
2681 if (IFFUNC_CALLEESAVES(sym->type)) {
2684 /* if any registers used */
2685 if (sym->regsUsed) {
2686 /* save the registers used */
2687 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2688 if (bitVectBitValue(sym->regsUsed,i) ||
2689 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2690 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2698 /* set the register bank to the desired value */
2699 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2700 pic14_emitcode("push","psw");
2701 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2704 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2706 if (options.useXstack) {
2707 pic14_emitcode("mov","r0,%s",spname);
2708 pic14_emitcode("mov","a,_bp");
2709 pic14_emitcode("movx","@r0,a");
2710 pic14_emitcode("inc","%s",spname);
2714 /* set up the stack */
2715 pic14_emitcode ("push","_bp"); /* save the callers stack */
2717 pic14_emitcode ("mov","_bp,%s",spname);
2720 /* adjust the stack for the function */
2725 werror(W_STACK_OVERFLOW,sym->name);
2727 if (i > 3 && sym->recvSize < 4) {
2729 pic14_emitcode ("mov","a,sp");
2730 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2731 pic14_emitcode ("mov","sp,a");
2736 pic14_emitcode("inc","sp");
2741 pic14_emitcode ("mov","a,_spx");
2742 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2743 pic14_emitcode ("mov","_spx,a");
2748 /*-----------------------------------------------------------------*/
2749 /* genEndFunction - generates epilogue for functions */
2750 /*-----------------------------------------------------------------*/
2751 static void genEndFunction (iCode *ic)
2753 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2755 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2757 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2759 pic14_emitcode ("mov","%s,_bp",spname);
2762 /* if use external stack but some variables were
2763 added to the local stack then decrement the
2765 if (options.useXstack && sym->stack) {
2766 pic14_emitcode("mov","a,sp");
2767 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2768 pic14_emitcode("mov","sp,a");
2772 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2773 if (options.useXstack) {
2774 pic14_emitcode("mov","r0,%s",spname);
2775 pic14_emitcode("movx","a,@r0");
2776 pic14_emitcode("mov","_bp,a");
2777 pic14_emitcode("dec","%s",spname);
2781 pic14_emitcode ("pop","_bp");
2785 /* restore the register bank */
2786 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2787 pic14_emitcode ("pop","psw");
2789 if (IFFUNC_ISISR(sym->type)) {
2791 /* now we need to restore the registers */
2792 /* if this isr has no bank i.e. is going to
2793 run with bank 0 , then we need to save more
2795 if (!FUNC_REGBANK(sym->type)) {
2797 /* if this function does not call any other
2798 function then we can be economical and
2799 save only those registers that are used */
2800 if (! IFFUNC_HASFCALL(sym->type)) {
2803 /* if any registers used */
2804 if (sym->regsUsed) {
2805 /* save the registers used */
2806 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2807 if (bitVectBitValue(sym->regsUsed,i) ||
2808 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2809 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2814 /* this function has a function call cannot
2815 determines register usage so we will have the
2817 unsaverbank(0,ic,FALSE);
2821 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2823 if (options.stack10bit)
2825 pic14_emitcode ("pop", "dpx1");
2826 pic14_emitcode ("pop", "dph1");
2827 pic14_emitcode ("pop", "dpl1");
2829 pic14_emitcode ("pop", "dps");
2830 pic14_emitcode ("pop", "dpx");
2832 if (!inExcludeList("dph"))
2833 pic14_emitcode ("pop","dph");
2834 if (!inExcludeList("dpl"))
2835 pic14_emitcode ("pop","dpl");
2836 if (!inExcludeList("b"))
2837 pic14_emitcode ("pop","b");
2838 if (!inExcludeList("acc"))
2839 pic14_emitcode ("pop","acc");
2841 if (IFFUNC_ISCRITICAL(sym->type))
2842 pic14_emitcode("setb","ea");
2845 /* if debug then send end of function */
2846 /* if (options.debug && currFunc) { */
2849 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2850 FileBaseName(ic->filename),currFunc->lastLine,
2851 ic->level,ic->block);
2852 if (IS_STATIC(currFunc->etype))
2853 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2855 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2859 pic14_emitcode ("reti","");
2861 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2862 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2863 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2864 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2865 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2866 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2868 emitpcodeNULLop(POC_RETFIE);
2872 if (IFFUNC_ISCRITICAL(sym->type))
2873 pic14_emitcode("setb","ea");
2875 if (IFFUNC_CALLEESAVES(sym->type)) {
2878 /* if any registers used */
2879 if (sym->regsUsed) {
2880 /* save the registers used */
2881 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2882 if (bitVectBitValue(sym->regsUsed,i) ||
2883 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2884 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2890 /* if debug then send end of function */
2893 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2894 FileBaseName(ic->filename),currFunc->lastLine,
2895 ic->level,ic->block);
2896 if (IS_STATIC(currFunc->etype))
2897 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2899 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2903 pic14_emitcode ("return","");
2904 emitpcodeNULLop(POC_RETURN);
2906 /* Mark the end of a function */
2907 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2912 /*-----------------------------------------------------------------*/
2913 /* genRet - generate code for return statement */
2914 /*-----------------------------------------------------------------*/
2915 static void genRet (iCode *ic)
2917 int size,offset = 0 , pushed = 0;
2919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2920 /* if we have no return value then
2921 just generate the "ret" */
2925 /* we have something to return then
2926 move the return value into place */
2927 aopOp(IC_LEFT(ic),ic,FALSE);
2928 size = AOP_SIZE(IC_LEFT(ic));
2932 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2934 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2936 pic14_emitcode("push","%s",l);
2939 l = aopGet(AOP(IC_LEFT(ic)),offset,
2941 if (strcmp(fReturn[offset],l)) {
2942 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2943 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2944 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2946 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2949 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2950 pic14_emitcode("movwf","%s",fReturn[offset]);
2960 if (strcmp(fReturn[pushed],"a"))
2961 pic14_emitcode("pop",fReturn[pushed]);
2963 pic14_emitcode("pop","acc");
2966 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2969 /* generate a jump to the return label
2970 if the next is not the return statement */
2971 if (!(ic->next && ic->next->op == LABEL &&
2972 IC_LABEL(ic->next) == returnLabel)) {
2974 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2975 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2980 /*-----------------------------------------------------------------*/
2981 /* genLabel - generates a label */
2982 /*-----------------------------------------------------------------*/
2983 static void genLabel (iCode *ic)
2985 /* special case never generate */
2986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2987 if (IC_LABEL(ic) == entryLabel)
2990 emitpLabel(IC_LABEL(ic)->key);
2991 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2994 /*-----------------------------------------------------------------*/
2995 /* genGoto - generates a goto */
2996 /*-----------------------------------------------------------------*/
2998 static void genGoto (iCode *ic)
3000 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3001 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3005 /*-----------------------------------------------------------------*/
3006 /* genMultbits :- multiplication of bits */
3007 /*-----------------------------------------------------------------*/
3008 static void genMultbits (operand *left,
3012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3014 if(!pic14_sameRegs(AOP(result),AOP(right)))
3015 emitpcode(POC_BSF, popGet(AOP(result),0));
3017 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3018 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3019 emitpcode(POC_BCF, popGet(AOP(result),0));
3024 /*-----------------------------------------------------------------*/
3025 /* genMultOneByte : 8 bit multiplication & division */
3026 /*-----------------------------------------------------------------*/
3027 static void genMultOneByte (operand *left,
3031 sym_link *opetype = operandType(result);
3036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3037 DEBUGpic14_AopType(__LINE__,left,right,result);
3038 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3040 /* (if two literals, the value is computed before) */
3041 /* if one literal, literal on the right */
3042 if (AOP_TYPE(left) == AOP_LIT){
3048 size = AOP_SIZE(result);
3051 if (AOP_TYPE(right) == AOP_LIT){
3052 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3053 aopGet(AOP(right),0,FALSE,FALSE),
3054 aopGet(AOP(left),0,FALSE,FALSE),
3055 aopGet(AOP(result),0,FALSE,FALSE));
3056 pic14_emitcode("call","genMultLit");
3058 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3059 aopGet(AOP(right),0,FALSE,FALSE),
3060 aopGet(AOP(left),0,FALSE,FALSE),
3061 aopGet(AOP(result),0,FALSE,FALSE));
3062 pic14_emitcode("call","genMult8X8_8");
3065 genMult8X8_8 (left, right,result);
3068 /* signed or unsigned */
3069 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3070 //l = aopGet(AOP(left),0,FALSE,FALSE);
3072 //pic14_emitcode("mul","ab");
3073 /* if result size = 1, mul signed = mul unsigned */
3074 //aopPut(AOP(result),"a",0);
3076 } else { // (size > 1)
3078 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3079 aopGet(AOP(right),0,FALSE,FALSE),
3080 aopGet(AOP(left),0,FALSE,FALSE),
3081 aopGet(AOP(result),0,FALSE,FALSE));
3083 if (SPEC_USIGN(opetype)){
3084 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3085 genUMult8X8_16 (left, right, result, NULL);
3088 /* for filling the MSBs */
3089 emitpcode(POC_CLRF, popGet(AOP(result),2));
3090 emitpcode(POC_CLRF, popGet(AOP(result),3));
3094 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3096 pic14_emitcode("mov","a,b");
3098 /* adjust the MSB if left or right neg */
3100 /* if one literal */
3101 if (AOP_TYPE(right) == AOP_LIT){
3102 pic14_emitcode("multiply ","right is a lit");
3103 /* AND literal negative */
3104 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3105 /* adjust MSB (c==0 after mul) */
3106 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3110 genSMult8X8_16 (left, right, result, NULL);
3114 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3116 pic14_emitcode("rlc","a");
3117 pic14_emitcode("subb","a,acc");
3125 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3126 //aopPut(AOP(result),"a",offset++);
3130 /*-----------------------------------------------------------------*/
3131 /* genMult - generates code for multiplication */
3132 /*-----------------------------------------------------------------*/
3133 static void genMult (iCode *ic)
3135 operand *left = IC_LEFT(ic);
3136 operand *right = IC_RIGHT(ic);
3137 operand *result= IC_RESULT(ic);
3139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3140 /* assign the amsops */
3141 aopOp (left,ic,FALSE);
3142 aopOp (right,ic,FALSE);
3143 aopOp (result,ic,TRUE);
3145 DEBUGpic14_AopType(__LINE__,left,right,result);
3147 /* special cases first */
3149 if (AOP_TYPE(left) == AOP_CRY &&
3150 AOP_TYPE(right)== AOP_CRY) {
3151 genMultbits(left,right,result);
3155 /* if both are of size == 1 */
3156 if (AOP_SIZE(left) == 1 &&
3157 AOP_SIZE(right) == 1 ) {
3158 genMultOneByte(left,right,result);
3162 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3164 /* should have been converted to function call */
3168 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3169 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3170 freeAsmop(result,NULL,ic,TRUE);
3173 /*-----------------------------------------------------------------*/
3174 /* genDivbits :- division of bits */
3175 /*-----------------------------------------------------------------*/
3176 static void genDivbits (operand *left,
3183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3184 /* the result must be bit */
3185 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3186 l = aopGet(AOP(left),0,FALSE,FALSE);
3190 pic14_emitcode("div","ab");
3191 pic14_emitcode("rrc","a");
3192 aopPut(AOP(result),"c",0);
3195 /*-----------------------------------------------------------------*/
3196 /* genDivOneByte : 8 bit division */
3197 /*-----------------------------------------------------------------*/
3198 static void genDivOneByte (operand *left,
3202 sym_link *opetype = operandType(result);
3207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3208 size = AOP_SIZE(result) - 1;
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),"a",0);
3219 aopPut(AOP(result),zero,offset++);
3223 /* signed is a little bit more difficult */
3225 /* save the signs of the operands */
3226 l = aopGet(AOP(left),0,FALSE,FALSE);
3228 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3229 pic14_emitcode("push","acc"); /* save it on the stack */
3231 /* now sign adjust for both left & right */
3232 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 division */
3252 pic14_emitcode("div","ab");
3253 /* we are interested in the lower order
3255 pic14_emitcode("mov","b,a");
3256 lbl = newiTempLabel(NULL);
3257 pic14_emitcode("pop","acc");
3258 /* if there was an over flow we don't
3259 adjust the sign of the result */
3260 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3261 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3263 pic14_emitcode("clr","a");
3264 pic14_emitcode("subb","a,b");
3265 pic14_emitcode("mov","b,a");
3266 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3268 /* now we are done */
3269 aopPut(AOP(result),"b",0);
3271 pic14_emitcode("mov","c,b.7");
3272 pic14_emitcode("subb","a,acc");
3275 aopPut(AOP(result),"a",offset++);
3279 /*-----------------------------------------------------------------*/
3280 /* genDiv - generates code for division */
3281 /*-----------------------------------------------------------------*/
3282 static void genDiv (iCode *ic)
3284 operand *left = IC_LEFT(ic);
3285 operand *right = IC_RIGHT(ic);
3286 operand *result= IC_RESULT(ic);
3288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3289 /* assign the amsops */
3290 aopOp (left,ic,FALSE);
3291 aopOp (right,ic,FALSE);
3292 aopOp (result,ic,TRUE);
3294 /* special cases first */
3296 if (AOP_TYPE(left) == AOP_CRY &&
3297 AOP_TYPE(right)== AOP_CRY) {
3298 genDivbits(left,right,result);
3302 /* if both are of size == 1 */
3303 if (AOP_SIZE(left) == 1 &&
3304 AOP_SIZE(right) == 1 ) {
3305 genDivOneByte(left,right,result);
3309 /* should have been converted to function call */
3312 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3313 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3314 freeAsmop(result,NULL,ic,TRUE);
3317 /*-----------------------------------------------------------------*/
3318 /* genModbits :- modulus of bits */
3319 /*-----------------------------------------------------------------*/
3320 static void genModbits (operand *left,
3327 /* the result must be bit */
3328 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3329 l = aopGet(AOP(left),0,FALSE,FALSE);
3333 pic14_emitcode("div","ab");
3334 pic14_emitcode("mov","a,b");
3335 pic14_emitcode("rrc","a");
3336 aopPut(AOP(result),"c",0);
3339 /*-----------------------------------------------------------------*/
3340 /* genModOneByte : 8 bit modulus */
3341 /*-----------------------------------------------------------------*/
3342 static void genModOneByte (operand *left,
3346 sym_link *opetype = operandType(result);
3350 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3351 /* signed or unsigned */
3352 if (SPEC_USIGN(opetype)) {
3353 /* unsigned is easy */
3354 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3355 l = aopGet(AOP(left),0,FALSE,FALSE);
3357 pic14_emitcode("div","ab");
3358 aopPut(AOP(result),"b",0);
3362 /* signed is a little bit more difficult */
3364 /* save the signs of the operands */
3365 l = aopGet(AOP(left),0,FALSE,FALSE);
3368 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3369 pic14_emitcode("push","acc"); /* save it on the stack */
3371 /* now sign adjust for both left & right */
3372 l = aopGet(AOP(right),0,FALSE,FALSE);
3375 lbl = newiTempLabel(NULL);
3376 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3377 pic14_emitcode("cpl","a");
3378 pic14_emitcode("inc","a");
3379 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3380 pic14_emitcode("mov","b,a");
3382 /* sign adjust left side */
3383 l = aopGet(AOP(left),0,FALSE,FALSE);
3386 lbl = newiTempLabel(NULL);
3387 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3388 pic14_emitcode("cpl","a");
3389 pic14_emitcode("inc","a");
3390 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3392 /* now the multiplication */
3393 pic14_emitcode("div","ab");
3394 /* we are interested in the lower order
3396 lbl = newiTempLabel(NULL);
3397 pic14_emitcode("pop","acc");
3398 /* if there was an over flow we don't
3399 adjust the sign of the result */
3400 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3401 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3403 pic14_emitcode("clr","a");
3404 pic14_emitcode("subb","a,b");
3405 pic14_emitcode("mov","b,a");
3406 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3408 /* now we are done */
3409 aopPut(AOP(result),"b",0);
3413 /*-----------------------------------------------------------------*/
3414 /* genMod - generates code for division */
3415 /*-----------------------------------------------------------------*/
3416 static void genMod (iCode *ic)
3418 operand *left = IC_LEFT(ic);
3419 operand *right = IC_RIGHT(ic);
3420 operand *result= IC_RESULT(ic);
3422 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3423 /* assign the amsops */
3424 aopOp (left,ic,FALSE);
3425 aopOp (right,ic,FALSE);
3426 aopOp (result,ic,TRUE);
3428 /* special cases first */
3430 if (AOP_TYPE(left) == AOP_CRY &&
3431 AOP_TYPE(right)== AOP_CRY) {
3432 genModbits(left,right,result);
3436 /* if both are of size == 1 */
3437 if (AOP_SIZE(left) == 1 &&
3438 AOP_SIZE(right) == 1 ) {
3439 genModOneByte(left,right,result);
3443 /* should have been converted to function call */
3447 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3448 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3449 freeAsmop(result,NULL,ic,TRUE);
3452 /*-----------------------------------------------------------------*/
3453 /* genIfxJump :- will create a jump depending on the ifx */
3454 /*-----------------------------------------------------------------*/
3456 note: May need to add parameter to indicate when a variable is in bit space.
3458 static void genIfxJump (iCode *ic, char *jval)
3461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3462 /* if true label then we jump if condition
3464 if ( IC_TRUE(ic) ) {
3466 if(strcmp(jval,"a") == 0)
3468 else if (strcmp(jval,"c") == 0)
3471 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3472 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3475 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3476 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3480 /* false label is present */
3481 if(strcmp(jval,"a") == 0)
3483 else if (strcmp(jval,"c") == 0)
3486 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3487 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3490 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3491 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3496 /* mark the icode as generated */
3500 /*-----------------------------------------------------------------*/
3502 /*-----------------------------------------------------------------*/
3503 static void genSkip(iCode *ifx,int status_bit)
3508 if ( IC_TRUE(ifx) ) {
3509 switch(status_bit) {
3524 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3525 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3529 switch(status_bit) {
3543 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3544 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3550 /*-----------------------------------------------------------------*/
3552 /*-----------------------------------------------------------------*/
3553 static void genSkipc(resolvedIfx *rifx)
3563 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3564 rifx->generated = 1;
3567 /*-----------------------------------------------------------------*/
3569 /*-----------------------------------------------------------------*/
3570 static void genSkipz2(resolvedIfx *rifx)
3580 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3581 rifx->generated = 1;
3584 /*-----------------------------------------------------------------*/
3586 /*-----------------------------------------------------------------*/
3587 static void genSkipz(iCode *ifx, int condition)
3598 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3600 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3603 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3605 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3608 /*-----------------------------------------------------------------*/
3610 /*-----------------------------------------------------------------*/
3611 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3617 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3619 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3622 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3623 rifx->generated = 1;
3627 /*-----------------------------------------------------------------*/
3628 /* genChkZeroes :- greater or less than comparison */
3629 /* For each byte in a literal that is zero, inclusive or the */
3630 /* the corresponding byte in the operand with W */
3631 /* returns true if any of the bytes are zero */
3632 /*-----------------------------------------------------------------*/
3633 static int genChkZeroes(operand *op, int lit, int size)
3640 i = (lit >> (size*8)) & 0xff;
3644 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3646 emitpcode(POC_IORFW, popGet(AOP(op),size));
3655 /*-----------------------------------------------------------------*/
3656 /* genCmp :- greater or less than comparison */
3657 /*-----------------------------------------------------------------*/
3658 static void genCmp (operand *left,operand *right,
3659 operand *result, iCode *ifx, int sign)
3661 int size, offset = 0 ;
3662 unsigned long lit = 0L,i = 0;
3663 resolvedIfx rFalseIfx;
3664 // resolvedIfx rTrueIfx;
3666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3668 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3669 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3673 resolveIfx(&rFalseIfx,ifx);
3674 truelbl = newiTempLabel(NULL);
3676 //if(IC_TRUE(ifx) == NULL)
3677 /* if left & right are bit variables */
3678 if (AOP_TYPE(left) == AOP_CRY &&
3679 AOP_TYPE(right) == AOP_CRY ) {
3680 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3681 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3683 /* subtract right from left if at the
3684 end the carry flag is set then we know that
3685 left is greater than right */
3686 size = max(AOP_SIZE(left),AOP_SIZE(right));
3688 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3689 if((size == 1) && !sign &&
3690 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3691 symbol *lbl = newiTempLabel(NULL);
3692 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3693 aopGet(AOP(left),offset,FALSE,FALSE),
3694 aopGet(AOP(right),offset,FALSE,FALSE),
3696 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3699 symbol *lbl = newiTempLabel(NULL);
3701 if(AOP_TYPE(right) == AOP_LIT) {
3703 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3705 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3712 genSkipCond(&rFalseIfx,left,size-1,7);
3714 /* no need to compare to 0...*/
3715 /* NOTE: this is a de-generate compare that most certainly
3716 * creates some dead code. */
3717 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3719 if(ifx) ifx->generated = 1;
3726 //i = (lit >> (size*8)) & 0xff;
3727 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3729 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3731 i = ((0-lit) & 0xff);
3734 /* lit is 0x7f, all signed chars are less than
3735 * this except for 0x7f itself */
3736 emitpcode(POC_XORLW, popGetLit(0x7f));
3737 genSkipz2(&rFalseIfx);
3739 emitpcode(POC_ADDLW, popGetLit(0x80));
3740 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3741 genSkipc(&rFalseIfx);
3745 emitpcode(POC_ADDLW, popGetLit(i));
3746 genSkipc(&rFalseIfx);
3750 if(ifx) ifx->generated = 1;
3754 /* chars are out of the way. now do ints and longs */
3757 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3764 genSkipCond(&rFalseIfx,left,size,7);
3765 if(ifx) ifx->generated = 1;
3770 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3772 //rFalseIfx.condition ^= 1;
3773 //genSkipCond(&rFalseIfx,left,size,7);
3774 //rFalseIfx.condition ^= 1;
3776 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3777 if(rFalseIfx.condition)
3778 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3780 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3782 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3783 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3784 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3787 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3789 if(rFalseIfx.condition) {
3791 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3797 genSkipc(&rFalseIfx);
3798 emitpLabel(truelbl->key);
3799 if(ifx) ifx->generated = 1;
3806 if( (lit & 0xff) == 0) {
3807 /* lower byte is zero */
3808 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3809 i = ((lit >> 8) & 0xff) ^0x80;
3810 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3811 emitpcode(POC_ADDLW, popGetLit( 0x80));
3812 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3813 genSkipc(&rFalseIfx);
3816 if(ifx) ifx->generated = 1;
3821 /* Special cases for signed longs */
3822 if( (lit & 0xffffff) == 0) {
3823 /* lower byte is zero */
3824 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3825 i = ((lit >> 8*3) & 0xff) ^0x80;
3826 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3827 emitpcode(POC_ADDLW, popGetLit( 0x80));
3828 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3829 genSkipc(&rFalseIfx);
3832 if(ifx) ifx->generated = 1;
3840 if(lit & (0x80 << (size*8))) {
3841 /* lit is negative */
3842 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3844 //genSkipCond(&rFalseIfx,left,size,7);
3846 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3848 if(rFalseIfx.condition)
3849 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3851 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3855 /* lit is positive */
3856 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3857 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3858 if(rFalseIfx.condition)
3859 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3861 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3863 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3864 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3865 //rFalseIfx.condition ^= 1;
3866 //genSkipCond(&rFalseIfx,left,size,7);
3867 //rFalseIfx.condition ^= 1;
3871 This works, but is only good for ints.
3872 It also requires a "known zero" register.
3873 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3874 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3875 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3876 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3877 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3878 genSkipc(&rFalseIfx);
3880 emitpLabel(truelbl->key);
3881 if(ifx) ifx->generated = 1;
3885 /* There are no more special cases, so perform a general compare */
3887 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3888 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3892 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3894 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3896 //rFalseIfx.condition ^= 1;
3897 genSkipc(&rFalseIfx);
3899 emitpLabel(truelbl->key);
3901 if(ifx) ifx->generated = 1;
3908 /* sign is out of the way. So now do an unsigned compare */
3909 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3912 //genChkZeroes(left)
3914 /* General case - compare to an unsigned literal on the right.*/
3916 i = (lit >> (size*8)) & 0xff;
3917 emitpcode(POC_MOVLW, popGetLit(i));
3918 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3920 i = (lit >> (size*8)) & 0xff;
3923 emitpcode(POC_MOVLW, popGetLit(i));
3925 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3927 /* this byte of the lit is zero,
3928 *if it's not the last then OR in the variable */
3930 emitpcode(POC_IORFW, popGet(AOP(left),size));
3935 emitpLabel(lbl->key);
3936 //if(emitFinalCheck)
3937 genSkipc(&rFalseIfx);
3939 emitpLabel(truelbl->key);
3941 if(ifx) ifx->generated = 1;
3947 if(AOP_TYPE(left) == AOP_LIT) {
3948 //symbol *lbl = newiTempLabel(NULL);
3950 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3953 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3956 if((lit == 0) && (sign == 0)){
3959 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3961 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3963 //rFalseIfx.condition ^= 1;
3964 genSkipz2(&rFalseIfx);
3965 if(ifx) ifx->generated = 1;
3972 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3973 /* degenerate compare can never be true */
3974 if(rFalseIfx.condition == 0)
3975 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3977 if(ifx) ifx->generated = 1;
3983 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3984 emitpcode(POC_ADDLW, popGetLit(0x80));
3985 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3986 rFalseIfx.condition ^= 1;
3987 genSkipc(&rFalseIfx);
3989 rFalseIfx.condition ^= 1;
3990 genSkipCond(&rFalseIfx,right,0,7);
3995 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3996 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3998 rFalseIfx.condition ^= 1;
3999 genSkipc(&rFalseIfx);
4001 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4002 genSkipz2(&rFalseIfx);
4006 if(ifx) ifx->generated = 1;
4011 /* Size is greater than 1 */
4021 /* this means lit = 0xffffffff, or -1 */
4024 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4025 rFalseIfx.condition ^= 1;
4026 genSkipCond(&rFalseIfx,right,size,7);
4027 if(ifx) ifx->generated = 1;
4034 if(rFalseIfx.condition) {
4035 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4036 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4039 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4041 emitpcode(POC_IORFW, popGet(AOP(right),size));
4045 if(rFalseIfx.condition) {
4046 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4047 emitpLabel(truelbl->key);
4049 rFalseIfx.condition ^= 1;
4050 genSkipCond(&rFalseIfx,right,s,7);
4053 if(ifx) ifx->generated = 1;
4058 if(lit & (0x80 << (size*8))) {
4059 /* Lit is less than zero */
4060 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4061 //rFalseIfx.condition ^= 1;
4062 //genSkipCond(&rFalseIfx,left,size,7);
4063 //rFalseIfx.condition ^= 1;
4064 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4065 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4067 if(rFalseIfx.condition)
4068 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4070 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4074 /* Lit is greater than or equal to zero */
4075 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4076 //rFalseIfx.condition ^= 1;
4077 //genSkipCond(&rFalseIfx,right,size,7);
4078 //rFalseIfx.condition ^= 1;
4080 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4081 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4083 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4084 if(rFalseIfx.condition)
4085 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4087 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4090 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4091 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4095 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4097 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4099 rFalseIfx.condition ^= 1;
4100 //rFalseIfx.condition = 1;
4101 genSkipc(&rFalseIfx);
4103 emitpLabel(truelbl->key);
4105 if(ifx) ifx->generated = 1;
4109 /* Unsigned compare for sizes greater than 1 */
4112 i = (lit >> (size*8)) & 0xff;
4116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4117 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4118 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4120 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4123 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4124 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4131 emitpLabel(lbl->key);
4133 rFalseIfx.condition ^= 1;
4134 genSkipc(&rFalseIfx);
4138 emitpLabel(truelbl->key);
4139 if(ifx) ifx->generated = 1;
4143 /* Compare two variables */
4145 DEBUGpic14_emitcode(";sign","%d",sign);
4149 /* Sigh. thus sucks... */
4151 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4152 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4153 emitpcode(POC_MOVLW, popGetLit(0x80));
4154 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4155 emitpcode(POC_XORFW, popGet(AOP(right),size));
4156 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4158 /* Signed char comparison */
4159 /* Special thanks to Nikolai Golovchenko for this snippet */
4160 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4161 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4162 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4163 emitpcode(POC_XORFW, popGet(AOP(left),0));
4164 emitpcode(POC_XORFW, popGet(AOP(right),0));
4165 emitpcode(POC_ADDLW, popGetLit(0x80));
4167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4168 genSkipc(&rFalseIfx);
4170 if(ifx) ifx->generated = 1;
4176 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4177 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4181 /* The rest of the bytes of a multi-byte compare */
4185 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4188 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4189 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4194 emitpLabel(lbl->key);
4196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4197 genSkipc(&rFalseIfx);
4198 if(ifx) ifx->generated = 1;
4205 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4206 pic14_outBitC(result);
4208 /* if the result is used in the next
4209 ifx conditional branch then generate
4210 code a little differently */
4212 genIfxJump (ifx,"c");
4214 pic14_outBitC(result);
4215 /* leave the result in acc */
4220 /*-----------------------------------------------------------------*/
4221 /* genCmpGt :- greater than comparison */
4222 /*-----------------------------------------------------------------*/
4223 static void genCmpGt (iCode *ic, iCode *ifx)
4225 operand *left, *right, *result;
4226 sym_link *letype , *retype;
4229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4231 right= IC_RIGHT(ic);
4232 result = IC_RESULT(ic);
4234 letype = getSpec(operandType(left));
4235 retype =getSpec(operandType(right));
4236 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4237 /* assign the amsops */
4238 aopOp (left,ic,FALSE);
4239 aopOp (right,ic,FALSE);
4240 aopOp (result,ic,TRUE);
4242 genCmp(right, left, result, ifx, sign);
4244 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4245 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4246 freeAsmop(result,NULL,ic,TRUE);
4249 /*-----------------------------------------------------------------*/
4250 /* genCmpLt - less than comparisons */
4251 /*-----------------------------------------------------------------*/
4252 static void genCmpLt (iCode *ic, iCode *ifx)
4254 operand *left, *right, *result;
4255 sym_link *letype , *retype;
4258 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4260 right= IC_RIGHT(ic);
4261 result = IC_RESULT(ic);
4263 letype = getSpec(operandType(left));
4264 retype =getSpec(operandType(right));
4265 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4267 /* assign the amsops */
4268 aopOp (left,ic,FALSE);
4269 aopOp (right,ic,FALSE);
4270 aopOp (result,ic,TRUE);
4272 genCmp(left, right, result, ifx, sign);
4274 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4275 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4276 freeAsmop(result,NULL,ic,TRUE);
4279 /*-----------------------------------------------------------------*/
4280 /* genc16bit2lit - compare a 16 bit value to a literal */
4281 /*-----------------------------------------------------------------*/
4282 static void genc16bit2lit(operand *op, int lit, int offset)
4286 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4287 if( (lit&0xff) == 0)
4292 switch( BYTEofLONG(lit,i)) {
4294 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4297 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4300 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4303 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4304 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4309 switch( BYTEofLONG(lit,i)) {
4311 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4315 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4319 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4322 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4324 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4330 /*-----------------------------------------------------------------*/
4331 /* gencjneshort - compare and jump if not equal */
4332 /*-----------------------------------------------------------------*/
4333 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4335 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4340 unsigned long lit = 0L;
4341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4342 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4344 resolveIfx(&rIfx,ifx);
4345 lbl = newiTempLabel(NULL);
4348 /* if the left side is a literal or
4349 if the right is in a pointer register and left
4351 if ((AOP_TYPE(left) == AOP_LIT) ||
4352 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4357 if(AOP_TYPE(right) == AOP_LIT)
4358 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4360 /* if the right side is a literal then anything goes */
4361 if (AOP_TYPE(right) == AOP_LIT &&
4362 AOP_TYPE(left) != AOP_DIR ) {
4365 genc16bit2lit(left, lit, 0);
4367 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4372 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4373 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4375 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4379 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4387 /* if the right side is in a register or in direct space or
4388 if the left is a pointer register & right is not */
4389 else if (AOP_TYPE(right) == AOP_REG ||
4390 AOP_TYPE(right) == AOP_DIR ||
4391 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4392 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4395 genc16bit2lit(left, lit, 0);
4397 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4402 if((AOP_TYPE(left) == AOP_DIR) &&
4403 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4405 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4406 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4408 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4410 switch (lit & 0xff) {
4412 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4415 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4416 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4420 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4421 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4425 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4426 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4431 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4434 if(AOP_TYPE(result) == AOP_CRY) {
4435 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4440 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4442 /* fix me. probably need to check result size too */
4443 emitpcode(POC_CLRF,popGet(AOP(result),0));
4448 emitpcode(POC_INCF,popGet(AOP(result),0));
4458 } else if(AOP_TYPE(right) == AOP_REG &&
4459 AOP_TYPE(left) != AOP_DIR){
4462 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4463 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4464 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4469 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4474 /* right is a pointer reg need both a & b */
4476 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4478 pic14_emitcode("mov","b,%s",l);
4479 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4480 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4484 emitpLabel(lbl->key);
4491 /*-----------------------------------------------------------------*/
4492 /* gencjne - compare and jump if not equal */
4493 /*-----------------------------------------------------------------*/
4494 static void gencjne(operand *left, operand *right, iCode *ifx)
4496 symbol *tlbl = newiTempLabel(NULL);
4498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4499 gencjneshort(left, right, lbl);
4501 pic14_emitcode("mov","a,%s",one);
4502 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4503 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4504 pic14_emitcode("clr","a");
4505 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4507 emitpLabel(lbl->key);
4508 emitpLabel(tlbl->key);
4513 /*-----------------------------------------------------------------*/
4514 /* genCmpEq - generates code for equal to */
4515 /*-----------------------------------------------------------------*/
4516 static void genCmpEq (iCode *ic, iCode *ifx)
4518 operand *left, *right, *result;
4519 unsigned long lit = 0L;
4522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4525 DEBUGpic14_emitcode ("; ifx is non-null","");
4527 DEBUGpic14_emitcode ("; ifx is null","");
4529 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4530 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4531 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4533 size = max(AOP_SIZE(left),AOP_SIZE(right));
4535 DEBUGpic14_AopType(__LINE__,left,right,result);
4537 /* if literal, literal on the right or
4538 if the right is in a pointer register and left
4540 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4541 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4542 operand *tmp = right ;
4548 if(ifx && !AOP_SIZE(result)){
4550 /* if they are both bit variables */
4551 if (AOP_TYPE(left) == AOP_CRY &&
4552 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4553 if(AOP_TYPE(right) == AOP_LIT){
4554 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4556 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4557 pic14_emitcode("cpl","c");
4558 } else if(lit == 1L) {
4559 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4561 pic14_emitcode("clr","c");
4563 /* AOP_TYPE(right) == AOP_CRY */
4565 symbol *lbl = newiTempLabel(NULL);
4566 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4567 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4568 pic14_emitcode("cpl","c");
4569 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4571 /* if true label then we jump if condition
4573 tlbl = newiTempLabel(NULL);
4574 if ( IC_TRUE(ifx) ) {
4575 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4576 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4578 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4579 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4581 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4584 /* left and right are both bit variables, result is carry */
4587 resolveIfx(&rIfx,ifx);
4589 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4590 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4591 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4592 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4597 /* They're not both bit variables. Is the right a literal? */
4598 if(AOP_TYPE(right) == AOP_LIT) {
4599 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4604 switch(lit & 0xff) {
4606 if ( IC_TRUE(ifx) ) {
4607 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4609 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4611 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4612 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4616 if ( IC_TRUE(ifx) ) {
4617 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4619 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4621 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4622 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4626 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4628 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4633 /* end of size == 1 */
4637 genc16bit2lit(left,lit,offset);
4640 /* end of size == 2 */
4645 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4646 emitpcode(POC_IORFW,popGet(AOP(left),1));
4647 emitpcode(POC_IORFW,popGet(AOP(left),2));
4648 emitpcode(POC_IORFW,popGet(AOP(left),3));
4652 /* search for patterns that can be optimized */
4654 genc16bit2lit(left,lit,0);
4657 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4659 genc16bit2lit(left,lit,2);
4661 emitpcode(POC_IORFW,popGet(AOP(left),2));
4662 emitpcode(POC_IORFW,popGet(AOP(left),3));
4675 } else if(AOP_TYPE(right) == AOP_CRY ) {
4676 /* we know the left is not a bit, but that the right is */
4677 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4678 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4679 popGet(AOP(right),offset));
4680 emitpcode(POC_XORLW,popGetLit(1));
4682 /* if the two are equal, then W will be 0 and the Z bit is set
4683 * we could test Z now, or go ahead and check the high order bytes if
4684 * the variable we're comparing is larger than a byte. */
4687 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4689 if ( IC_TRUE(ifx) ) {
4691 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4692 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4695 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4696 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4700 /* They're both variables that are larger than bits */
4703 tlbl = newiTempLabel(NULL);
4706 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4707 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4709 if ( IC_TRUE(ifx) ) {
4712 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4713 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4716 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4717 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4721 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4722 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4726 if(s>1 && IC_TRUE(ifx)) {
4727 emitpLabel(tlbl->key);
4728 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4732 /* mark the icode as generated */
4737 /* if they are both bit variables */
4738 if (AOP_TYPE(left) == AOP_CRY &&
4739 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4740 if(AOP_TYPE(right) == AOP_LIT){
4741 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4743 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4744 pic14_emitcode("cpl","c");
4745 } else if(lit == 1L) {
4746 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4748 pic14_emitcode("clr","c");
4750 /* AOP_TYPE(right) == AOP_CRY */
4752 symbol *lbl = newiTempLabel(NULL);
4753 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4754 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4755 pic14_emitcode("cpl","c");
4756 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4759 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4760 pic14_outBitC(result);
4764 genIfxJump (ifx,"c");
4767 /* if the result is used in an arithmetic operation
4768 then put the result in place */
4769 pic14_outBitC(result);
4772 gencjne(left,right,result,ifx);
4775 gencjne(left,right,newiTempLabel(NULL));
4777 if(IC_TRUE(ifx)->key)
4778 gencjne(left,right,IC_TRUE(ifx)->key);
4780 gencjne(left,right,IC_FALSE(ifx)->key);
4784 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4785 aopPut(AOP(result),"a",0);
4790 genIfxJump (ifx,"a");
4794 /* if the result is used in an arithmetic operation
4795 then put the result in place */
4797 if (AOP_TYPE(result) != AOP_CRY)
4798 pic14_outAcc(result);
4800 /* leave the result in acc */
4804 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4805 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4806 freeAsmop(result,NULL,ic,TRUE);
4809 /*-----------------------------------------------------------------*/
4810 /* ifxForOp - returns the icode containing the ifx for operand */
4811 /*-----------------------------------------------------------------*/
4812 static iCode *ifxForOp ( operand *op, iCode *ic )
4814 /* if true symbol then needs to be assigned */
4815 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4816 if (IS_TRUE_SYMOP(op))
4819 /* if this has register type condition and
4820 the next instruction is ifx with the same operand
4821 and live to of the operand is upto the ifx only then */
4823 ic->next->op == IFX &&
4824 IC_COND(ic->next)->key == op->key &&
4825 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4829 ic->next->op == IFX &&
4830 IC_COND(ic->next)->key == op->key) {
4831 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4835 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4837 ic->next->op == IFX)
4838 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4841 ic->next->op == IFX &&
4842 IC_COND(ic->next)->key == op->key) {
4843 DEBUGpic14_emitcode ("; "," key is okay");
4844 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4845 OP_SYMBOL(op)->liveTo,
4852 /*-----------------------------------------------------------------*/
4853 /* genAndOp - for && operation */
4854 /*-----------------------------------------------------------------*/
4855 static void genAndOp (iCode *ic)
4857 operand *left,*right, *result;
4860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4861 /* note here that && operations that are in an
4862 if statement are taken away by backPatchLabels
4863 only those used in arthmetic operations remain */
4864 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4865 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4866 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4868 /* if both are bit variables */
4869 if (AOP_TYPE(left) == AOP_CRY &&
4870 AOP_TYPE(right) == AOP_CRY ) {
4871 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4872 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4873 pic14_outBitC(result);
4875 tlbl = newiTempLabel(NULL);
4876 pic14_toBoolean(left);
4877 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4878 pic14_toBoolean(right);
4879 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4880 pic14_outBitAcc(result);
4883 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4884 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4885 freeAsmop(result,NULL,ic,TRUE);
4889 /*-----------------------------------------------------------------*/
4890 /* genOrOp - for || operation */
4891 /*-----------------------------------------------------------------*/
4894 modified this code, but it doesn't appear to ever get called
4897 static void genOrOp (iCode *ic)
4899 operand *left,*right, *result;
4902 /* note here that || operations that are in an
4903 if statement are taken away by backPatchLabels
4904 only those used in arthmetic operations remain */
4905 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4906 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4907 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4908 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4910 DEBUGpic14_AopType(__LINE__,left,right,result);
4912 /* if both are bit variables */
4913 if (AOP_TYPE(left) == AOP_CRY &&
4914 AOP_TYPE(right) == AOP_CRY ) {
4915 pic14_emitcode("clrc","");
4916 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4917 AOP(left)->aopu.aop_dir,
4918 AOP(left)->aopu.aop_dir);
4919 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4920 AOP(right)->aopu.aop_dir,
4921 AOP(right)->aopu.aop_dir);
4922 pic14_emitcode("setc","");
4925 tlbl = newiTempLabel(NULL);
4926 pic14_toBoolean(left);
4928 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4929 pic14_toBoolean(right);
4930 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4932 pic14_outBitAcc(result);
4935 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4936 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4937 freeAsmop(result,NULL,ic,TRUE);
4940 /*-----------------------------------------------------------------*/
4941 /* isLiteralBit - test if lit == 2^n */
4942 /*-----------------------------------------------------------------*/
4943 static int isLiteralBit(unsigned long lit)
4945 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4946 0x100L,0x200L,0x400L,0x800L,
4947 0x1000L,0x2000L,0x4000L,0x8000L,
4948 0x10000L,0x20000L,0x40000L,0x80000L,
4949 0x100000L,0x200000L,0x400000L,0x800000L,
4950 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4951 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4955 for(idx = 0; idx < 32; idx++)
4961 /*-----------------------------------------------------------------*/
4962 /* continueIfTrue - */
4963 /*-----------------------------------------------------------------*/
4964 static void continueIfTrue (iCode *ic)
4966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4968 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4972 /*-----------------------------------------------------------------*/
4974 /*-----------------------------------------------------------------*/
4975 static void jumpIfTrue (iCode *ic)
4977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4979 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4983 /*-----------------------------------------------------------------*/
4984 /* jmpTrueOrFalse - */
4985 /*-----------------------------------------------------------------*/
4986 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4988 // ugly but optimized by peephole
4989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4991 symbol *nlbl = newiTempLabel(NULL);
4992 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4993 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4994 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4995 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4998 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4999 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5004 /*-----------------------------------------------------------------*/
5005 /* genAnd - code for and */
5006 /*-----------------------------------------------------------------*/
5007 static void genAnd (iCode *ic, iCode *ifx)
5009 operand *left, *right, *result;
5011 unsigned long lit = 0L;
5016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5017 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5018 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5019 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5021 resolveIfx(&rIfx,ifx);
5023 /* if left is a literal & right is not then exchange them */
5024 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5025 AOP_NEEDSACC(left)) {
5026 operand *tmp = right ;
5031 /* if result = right then exchange them */
5032 if(pic14_sameRegs(AOP(result),AOP(right))){
5033 operand *tmp = right ;
5038 /* if right is bit then exchange them */
5039 if (AOP_TYPE(right) == AOP_CRY &&
5040 AOP_TYPE(left) != AOP_CRY){
5041 operand *tmp = right ;
5045 if(AOP_TYPE(right) == AOP_LIT)
5046 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5048 size = AOP_SIZE(result);
5050 DEBUGpic14_AopType(__LINE__,left,right,result);
5053 // result = bit & yy;
5054 if (AOP_TYPE(left) == AOP_CRY){
5055 // c = bit & literal;
5056 if(AOP_TYPE(right) == AOP_LIT){
5058 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5061 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5064 if(size && (AOP_TYPE(result) == AOP_CRY)){
5065 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5068 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5072 pic14_emitcode("clr","c");
5075 if (AOP_TYPE(right) == AOP_CRY){
5077 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5078 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5081 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5083 pic14_emitcode("rrc","a");
5084 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5090 pic14_outBitC(result);
5092 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5093 genIfxJump(ifx, "c");
5097 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5098 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5099 if((AOP_TYPE(right) == AOP_LIT) &&
5100 (AOP_TYPE(result) == AOP_CRY) &&
5101 (AOP_TYPE(left) != AOP_CRY)){
5102 int posbit = isLiteralBit(lit);
5106 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5109 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5115 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5116 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5118 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5119 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5122 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5123 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5124 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5131 symbol *tlbl = newiTempLabel(NULL);
5132 int sizel = AOP_SIZE(left);
5134 pic14_emitcode("setb","c");
5136 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5137 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5139 if((posbit = isLiteralBit(bytelit)) != 0)
5140 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5142 if(bytelit != 0x0FFL)
5143 pic14_emitcode("anl","a,%s",
5144 aopGet(AOP(right),offset,FALSE,TRUE));
5145 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5150 // bit = left & literal
5152 pic14_emitcode("clr","c");
5153 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5155 // if(left & literal)
5158 jmpTrueOrFalse(ifx, tlbl);
5162 pic14_outBitC(result);
5166 /* if left is same as result */
5167 if(pic14_sameRegs(AOP(result),AOP(left))){
5169 for(;size--; offset++,lit>>=8) {
5170 if(AOP_TYPE(right) == AOP_LIT){
5171 switch(lit & 0xff) {
5173 /* and'ing with 0 has clears the result */
5174 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5175 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5178 /* and'ing with 0xff is a nop when the result and left are the same */
5183 int p = my_powof2( (~lit) & 0xff );
5185 /* only one bit is set in the literal, so use a bcf instruction */
5186 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5187 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5190 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5191 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5192 if(know_W != (lit&0xff))
5193 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5195 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5200 if (AOP_TYPE(left) == AOP_ACC) {
5201 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5203 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5204 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5211 // left & result in different registers
5212 if(AOP_TYPE(result) == AOP_CRY){
5214 // if(size), result in bit
5215 // if(!size && ifx), conditional oper: if(left & right)
5216 symbol *tlbl = newiTempLabel(NULL);
5217 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5219 pic14_emitcode("setb","c");
5221 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5222 pic14_emitcode("anl","a,%s",
5223 aopGet(AOP(left),offset,FALSE,FALSE));
5224 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5229 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5230 pic14_outBitC(result);
5232 jmpTrueOrFalse(ifx, tlbl);
5234 for(;(size--);offset++) {
5236 // result = left & right
5237 if(AOP_TYPE(right) == AOP_LIT){
5238 int t = (lit >> (offset*8)) & 0x0FFL;
5241 pic14_emitcode("clrf","%s",
5242 aopGet(AOP(result),offset,FALSE,FALSE));
5243 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5246 pic14_emitcode("movf","%s,w",
5247 aopGet(AOP(left),offset,FALSE,FALSE));
5248 pic14_emitcode("movwf","%s",
5249 aopGet(AOP(result),offset,FALSE,FALSE));
5250 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5251 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5254 pic14_emitcode("movlw","0x%x",t);
5255 pic14_emitcode("andwf","%s,w",
5256 aopGet(AOP(left),offset,FALSE,FALSE));
5257 pic14_emitcode("movwf","%s",
5258 aopGet(AOP(result),offset,FALSE,FALSE));
5260 emitpcode(POC_MOVLW, popGetLit(t));
5261 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5262 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5267 if (AOP_TYPE(left) == AOP_ACC) {
5268 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5269 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5271 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5272 pic14_emitcode("andwf","%s,w",
5273 aopGet(AOP(left),offset,FALSE,FALSE));
5274 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5275 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5277 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5278 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5284 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5285 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5286 freeAsmop(result,NULL,ic,TRUE);
5289 /*-----------------------------------------------------------------*/
5290 /* genOr - code for or */
5291 /*-----------------------------------------------------------------*/
5292 static void genOr (iCode *ic, iCode *ifx)
5294 operand *left, *right, *result;
5296 unsigned long lit = 0L;
5298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5300 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5301 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5302 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5304 DEBUGpic14_AopType(__LINE__,left,right,result);
5306 /* if left is a literal & right is not then exchange them */
5307 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5308 AOP_NEEDSACC(left)) {
5309 operand *tmp = right ;
5314 /* if result = right then exchange them */
5315 if(pic14_sameRegs(AOP(result),AOP(right))){
5316 operand *tmp = right ;
5321 /* if right is bit then exchange them */
5322 if (AOP_TYPE(right) == AOP_CRY &&
5323 AOP_TYPE(left) != AOP_CRY){
5324 operand *tmp = right ;
5329 DEBUGpic14_AopType(__LINE__,left,right,result);
5331 if(AOP_TYPE(right) == AOP_LIT)
5332 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5334 size = AOP_SIZE(result);
5338 if (AOP_TYPE(left) == AOP_CRY){
5339 if(AOP_TYPE(right) == AOP_LIT){
5340 // c = bit & literal;
5342 // lit != 0 => result = 1
5343 if(AOP_TYPE(result) == AOP_CRY){
5345 emitpcode(POC_BSF, popGet(AOP(result),0));
5346 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5347 // AOP(result)->aopu.aop_dir,
5348 // AOP(result)->aopu.aop_dir);
5350 continueIfTrue(ifx);
5354 // lit == 0 => result = left
5355 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5357 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5360 if (AOP_TYPE(right) == AOP_CRY){
5361 if(pic14_sameRegs(AOP(result),AOP(left))){
5363 emitpcode(POC_BCF, popGet(AOP(result),0));
5364 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5365 emitpcode(POC_BSF, popGet(AOP(result),0));
5367 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5368 AOP(result)->aopu.aop_dir,
5369 AOP(result)->aopu.aop_dir);
5370 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5371 AOP(right)->aopu.aop_dir,
5372 AOP(right)->aopu.aop_dir);
5373 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5374 AOP(result)->aopu.aop_dir,
5375 AOP(result)->aopu.aop_dir);
5377 if( AOP_TYPE(result) == AOP_ACC) {
5378 emitpcode(POC_MOVLW, popGetLit(0));
5379 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5380 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5381 emitpcode(POC_MOVLW, popGetLit(1));
5385 emitpcode(POC_BCF, popGet(AOP(result),0));
5386 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5387 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5388 emitpcode(POC_BSF, popGet(AOP(result),0));
5390 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5391 AOP(result)->aopu.aop_dir,
5392 AOP(result)->aopu.aop_dir);
5393 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5394 AOP(right)->aopu.aop_dir,
5395 AOP(right)->aopu.aop_dir);
5396 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5397 AOP(left)->aopu.aop_dir,
5398 AOP(left)->aopu.aop_dir);
5399 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5400 AOP(result)->aopu.aop_dir,
5401 AOP(result)->aopu.aop_dir);
5406 symbol *tlbl = newiTempLabel(NULL);
5407 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5410 emitpcode(POC_BCF, popGet(AOP(result),0));
5411 if( AOP_TYPE(right) == AOP_ACC) {
5412 emitpcode(POC_IORLW, popGetLit(0));
5414 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5415 emitpcode(POC_BSF, popGet(AOP(result),0));
5420 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5421 pic14_emitcode(";XXX setb","c");
5422 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5423 AOP(left)->aopu.aop_dir,tlbl->key+100);
5424 pic14_toBoolean(right);
5425 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5426 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5427 jmpTrueOrFalse(ifx, tlbl);
5431 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5438 pic14_outBitC(result);
5440 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5441 genIfxJump(ifx, "c");
5445 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5446 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5447 if((AOP_TYPE(right) == AOP_LIT) &&
5448 (AOP_TYPE(result) == AOP_CRY) &&
5449 (AOP_TYPE(left) != AOP_CRY)){
5451 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5454 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5456 continueIfTrue(ifx);
5459 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5460 // lit = 0, result = boolean(left)
5462 pic14_emitcode(";XXX setb","c");
5463 pic14_toBoolean(right);
5465 symbol *tlbl = newiTempLabel(NULL);
5466 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5468 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5470 genIfxJump (ifx,"a");
5474 pic14_outBitC(result);
5478 /* if left is same as result */
5479 if(pic14_sameRegs(AOP(result),AOP(left))){
5481 for(;size--; offset++,lit>>=8) {
5482 if(AOP_TYPE(right) == AOP_LIT){
5483 if((lit & 0xff) == 0)
5484 /* or'ing with 0 has no effect */
5487 int p = my_powof2(lit & 0xff);
5489 /* only one bit is set in the literal, so use a bsf instruction */
5491 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5493 if(know_W != (lit & 0xff))
5494 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5495 know_W = lit & 0xff;
5496 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5501 if (AOP_TYPE(left) == AOP_ACC) {
5502 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5503 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5505 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5506 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5508 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5509 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5515 // left & result in different registers
5516 if(AOP_TYPE(result) == AOP_CRY){
5518 // if(size), result in bit
5519 // if(!size && ifx), conditional oper: if(left | right)
5520 symbol *tlbl = newiTempLabel(NULL);
5521 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5522 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5526 pic14_emitcode(";XXX setb","c");
5528 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5529 pic14_emitcode(";XXX orl","a,%s",
5530 aopGet(AOP(left),offset,FALSE,FALSE));
5531 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5536 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5537 pic14_outBitC(result);
5539 jmpTrueOrFalse(ifx, tlbl);
5540 } else for(;(size--);offset++){
5542 // result = left & right
5543 if(AOP_TYPE(right) == AOP_LIT){
5544 int t = (lit >> (offset*8)) & 0x0FFL;
5547 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5548 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5550 pic14_emitcode("movf","%s,w",
5551 aopGet(AOP(left),offset,FALSE,FALSE));
5552 pic14_emitcode("movwf","%s",
5553 aopGet(AOP(result),offset,FALSE,FALSE));
5556 emitpcode(POC_MOVLW, popGetLit(t));
5557 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5558 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5560 pic14_emitcode("movlw","0x%x",t);
5561 pic14_emitcode("iorwf","%s,w",
5562 aopGet(AOP(left),offset,FALSE,FALSE));
5563 pic14_emitcode("movwf","%s",
5564 aopGet(AOP(result),offset,FALSE,FALSE));
5570 // faster than result <- left, anl result,right
5571 // and better if result is SFR
5572 if (AOP_TYPE(left) == AOP_ACC) {
5573 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5574 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5576 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5577 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5579 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5580 pic14_emitcode("iorwf","%s,w",
5581 aopGet(AOP(left),offset,FALSE,FALSE));
5583 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5584 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5589 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5590 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5591 freeAsmop(result,NULL,ic,TRUE);
5594 /*-----------------------------------------------------------------*/
5595 /* genXor - code for xclusive or */
5596 /*-----------------------------------------------------------------*/
5597 static void genXor (iCode *ic, iCode *ifx)
5599 operand *left, *right, *result;
5601 unsigned long lit = 0L;
5603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5605 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5606 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5607 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5609 /* if left is a literal & right is not ||
5610 if left needs acc & right does not */
5611 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5612 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5613 operand *tmp = right ;
5618 /* if result = right then exchange them */
5619 if(pic14_sameRegs(AOP(result),AOP(right))){
5620 operand *tmp = right ;
5625 /* if right is bit then exchange them */
5626 if (AOP_TYPE(right) == AOP_CRY &&
5627 AOP_TYPE(left) != AOP_CRY){
5628 operand *tmp = right ;
5632 if(AOP_TYPE(right) == AOP_LIT)
5633 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5635 size = AOP_SIZE(result);
5639 if (AOP_TYPE(left) == AOP_CRY){
5640 if(AOP_TYPE(right) == AOP_LIT){
5641 // c = bit & literal;
5643 // lit>>1 != 0 => result = 1
5644 if(AOP_TYPE(result) == AOP_CRY){
5646 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5647 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5649 continueIfTrue(ifx);
5652 pic14_emitcode("setb","c");
5656 // lit == 0, result = left
5657 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5659 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5661 // lit == 1, result = not(left)
5662 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5663 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5664 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5665 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5668 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5669 pic14_emitcode("cpl","c");
5676 symbol *tlbl = newiTempLabel(NULL);
5677 if (AOP_TYPE(right) == AOP_CRY){
5679 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5682 int sizer = AOP_SIZE(right);
5684 // if val>>1 != 0, result = 1
5685 pic14_emitcode("setb","c");
5687 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5689 // test the msb of the lsb
5690 pic14_emitcode("anl","a,#0xfe");
5691 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5695 pic14_emitcode("rrc","a");
5697 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5698 pic14_emitcode("cpl","c");
5699 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5704 pic14_outBitC(result);
5706 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5707 genIfxJump(ifx, "c");
5711 if(pic14_sameRegs(AOP(result),AOP(left))){
5712 /* if left is same as result */
5713 for(;size--; offset++) {
5714 if(AOP_TYPE(right) == AOP_LIT){
5715 int t = (lit >> (offset*8)) & 0x0FFL;
5719 if (IS_AOP_PREG(left)) {
5720 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5721 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5722 aopPut(AOP(result),"a",offset);
5724 emitpcode(POC_MOVLW, popGetLit(t));
5725 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5726 pic14_emitcode("xrl","%s,%s",
5727 aopGet(AOP(left),offset,FALSE,TRUE),
5728 aopGet(AOP(right),offset,FALSE,FALSE));
5731 if (AOP_TYPE(left) == AOP_ACC)
5732 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5734 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5735 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5737 if (IS_AOP_PREG(left)) {
5738 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5739 aopPut(AOP(result),"a",offset);
5741 pic14_emitcode("xrl","%s,a",
5742 aopGet(AOP(left),offset,FALSE,TRUE));
5748 // left & result in different registers
5749 if(AOP_TYPE(result) == AOP_CRY){
5751 // if(size), result in bit
5752 // if(!size && ifx), conditional oper: if(left ^ right)
5753 symbol *tlbl = newiTempLabel(NULL);
5754 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5756 pic14_emitcode("setb","c");
5758 if((AOP_TYPE(right) == AOP_LIT) &&
5759 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5760 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5762 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5763 pic14_emitcode("xrl","a,%s",
5764 aopGet(AOP(left),offset,FALSE,FALSE));
5766 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5771 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5772 pic14_outBitC(result);
5774 jmpTrueOrFalse(ifx, tlbl);
5775 } else for(;(size--);offset++){
5777 // result = left & right
5778 if(AOP_TYPE(right) == AOP_LIT){
5779 int t = (lit >> (offset*8)) & 0x0FFL;
5782 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5783 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5784 pic14_emitcode("movf","%s,w",
5785 aopGet(AOP(left),offset,FALSE,FALSE));
5786 pic14_emitcode("movwf","%s",
5787 aopGet(AOP(result),offset,FALSE,FALSE));
5790 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5791 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5792 pic14_emitcode("comf","%s,w",
5793 aopGet(AOP(left),offset,FALSE,FALSE));
5794 pic14_emitcode("movwf","%s",
5795 aopGet(AOP(result),offset,FALSE,FALSE));
5798 emitpcode(POC_MOVLW, popGetLit(t));
5799 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5800 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5801 pic14_emitcode("movlw","0x%x",t);
5802 pic14_emitcode("xorwf","%s,w",
5803 aopGet(AOP(left),offset,FALSE,FALSE));
5804 pic14_emitcode("movwf","%s",
5805 aopGet(AOP(result),offset,FALSE,FALSE));
5811 // faster than result <- left, anl result,right
5812 // and better if result is SFR
5813 if (AOP_TYPE(left) == AOP_ACC) {
5814 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5815 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5817 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5818 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5819 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5820 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5822 if ( AOP_TYPE(result) != AOP_ACC){
5823 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5824 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5830 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5831 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5832 freeAsmop(result,NULL,ic,TRUE);
5835 /*-----------------------------------------------------------------*/
5836 /* genInline - write the inline code out */
5837 /*-----------------------------------------------------------------*/
5838 static void genInline (iCode *ic)
5840 char *buffer, *bp, *bp1;
5842 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5844 _G.inLine += (!options.asmpeep);
5846 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5847 strcpy(buffer,IC_INLINE(ic));
5849 /* emit each line as a code */
5853 pic14_emitcode(bp1,"");
5860 pic14_emitcode(bp1,"");
5867 pic14_emitcode(bp1,"");
5868 /* pic14_emitcode("",buffer); */
5869 _G.inLine -= (!options.asmpeep);
5872 /*-----------------------------------------------------------------*/
5873 /* genRRC - rotate right with carry */
5874 /*-----------------------------------------------------------------*/
5875 static void genRRC (iCode *ic)
5877 operand *left , *result ;
5878 int size, offset = 0, same;
5880 /* rotate right with carry */
5882 result=IC_RESULT(ic);
5883 aopOp (left,ic,FALSE);
5884 aopOp (result,ic,FALSE);
5886 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5888 same = pic14_sameRegs(AOP(result),AOP(left));
5890 size = AOP_SIZE(result);
5892 /* get the lsb and put it into the carry */
5893 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5900 emitpcode(POC_RRF, popGet(AOP(left),offset));
5902 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5903 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5909 freeAsmop(left,NULL,ic,TRUE);
5910 freeAsmop(result,NULL,ic,TRUE);
5913 /*-----------------------------------------------------------------*/
5914 /* genRLC - generate code for rotate left with carry */
5915 /*-----------------------------------------------------------------*/
5916 static void genRLC (iCode *ic)
5918 operand *left , *result ;
5919 int size, offset = 0;
5922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5923 /* rotate right with carry */
5925 result=IC_RESULT(ic);
5926 aopOp (left,ic,FALSE);
5927 aopOp (result,ic,FALSE);
5929 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5931 same = pic14_sameRegs(AOP(result),AOP(left));
5933 /* move it to the result */
5934 size = AOP_SIZE(result);
5936 /* get the msb and put it into the carry */
5937 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5944 emitpcode(POC_RLF, popGet(AOP(left),offset));
5946 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5947 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5954 freeAsmop(left,NULL,ic,TRUE);
5955 freeAsmop(result,NULL,ic,TRUE);
5958 /*-----------------------------------------------------------------*/
5959 /* genGetHbit - generates code get highest order bit */
5960 /*-----------------------------------------------------------------*/
5961 static void genGetHbit (iCode *ic)
5963 operand *left, *result;
5965 result=IC_RESULT(ic);
5966 aopOp (left,ic,FALSE);
5967 aopOp (result,ic,FALSE);
5969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5970 /* get the highest order byte into a */
5971 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5972 if(AOP_TYPE(result) == AOP_CRY){
5973 pic14_emitcode("rlc","a");
5974 pic14_outBitC(result);
5977 pic14_emitcode("rl","a");
5978 pic14_emitcode("anl","a,#0x01");
5979 pic14_outAcc(result);
5983 freeAsmop(left,NULL,ic,TRUE);
5984 freeAsmop(result,NULL,ic,TRUE);
5987 /*-----------------------------------------------------------------*/
5988 /* AccRol - rotate left accumulator by known count */
5989 /*-----------------------------------------------------------------*/
5990 static void AccRol (int shCount)
5992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5993 shCount &= 0x0007; // shCount : 0..7
5998 pic14_emitcode("rl","a");
6001 pic14_emitcode("rl","a");
6002 pic14_emitcode("rl","a");
6005 pic14_emitcode("swap","a");
6006 pic14_emitcode("rr","a");
6009 pic14_emitcode("swap","a");
6012 pic14_emitcode("swap","a");
6013 pic14_emitcode("rl","a");
6016 pic14_emitcode("rr","a");
6017 pic14_emitcode("rr","a");
6020 pic14_emitcode("rr","a");
6025 /*-----------------------------------------------------------------*/
6026 /* AccLsh - left shift accumulator by known count */
6027 /*-----------------------------------------------------------------*/
6028 static void AccLsh (int shCount)
6030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6033 pic14_emitcode("add","a,acc");
6036 pic14_emitcode("add","a,acc");
6037 pic14_emitcode("add","a,acc");
6039 /* rotate left accumulator */
6041 /* and kill the lower order bits */
6042 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6047 /*-----------------------------------------------------------------*/
6048 /* AccRsh - right shift accumulator by known count */
6049 /*-----------------------------------------------------------------*/
6050 static void AccRsh (int shCount)
6052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6056 pic14_emitcode("rrc","a");
6058 /* rotate right accumulator */
6059 AccRol(8 - shCount);
6060 /* and kill the higher order bits */
6061 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6067 /*-----------------------------------------------------------------*/
6068 /* AccSRsh - signed right shift accumulator by known count */
6069 /*-----------------------------------------------------------------*/
6070 static void AccSRsh (int shCount)
6073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6076 pic14_emitcode("mov","c,acc.7");
6077 pic14_emitcode("rrc","a");
6078 } else if(shCount == 2){
6079 pic14_emitcode("mov","c,acc.7");
6080 pic14_emitcode("rrc","a");
6081 pic14_emitcode("mov","c,acc.7");
6082 pic14_emitcode("rrc","a");
6084 tlbl = newiTempLabel(NULL);
6085 /* rotate right accumulator */
6086 AccRol(8 - shCount);
6087 /* and kill the higher order bits */
6088 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6089 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6090 pic14_emitcode("orl","a,#0x%02x",
6091 (unsigned char)~SRMask[shCount]);
6092 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6097 /*-----------------------------------------------------------------*/
6098 /* shiftR1Left2Result - shift right one byte from left to result */
6099 /*-----------------------------------------------------------------*/
6100 static void shiftR1Left2ResultSigned (operand *left, int offl,
6101 operand *result, int offr,
6106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6108 same = (left == result) || (AOP(left) == AOP(result));
6112 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6114 emitpcode(POC_RRF, popGet(AOP(result),offr));
6116 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6117 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6127 /*-----------------------------------------------------------------*/
6128 /* shiftR1Left2Result - shift right one byte from left to result */
6129 /*-----------------------------------------------------------------*/
6130 static void shiftR1Left2Result (operand *left, int offl,
6131 operand *result, int offr,
6132 int shCount, int sign)
6136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6138 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6140 /* Copy the msb into the carry if signed. */
6142 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6152 emitpcode(POC_RRF, popGet(AOP(result),offr));
6154 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6155 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6161 emitpcode(POC_RRF, popGet(AOP(result),offr));
6163 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6164 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6167 emitpcode(POC_RRF, popGet(AOP(result),offr));
6172 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6174 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6175 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6178 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6179 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6180 emitpcode(POC_ANDLW, popGetLit(0x1f));
6181 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6185 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6186 emitpcode(POC_ANDLW, popGetLit(0x0f));
6187 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6191 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6192 emitpcode(POC_ANDLW, popGetLit(0x0f));
6193 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6195 emitpcode(POC_RRF, popGet(AOP(result),offr));
6200 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6201 emitpcode(POC_ANDLW, popGetLit(0x80));
6202 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6203 emitpcode(POC_RLF, popGet(AOP(result),offr));
6204 emitpcode(POC_RLF, popGet(AOP(result),offr));
6209 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6210 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6211 emitpcode(POC_RLF, popGet(AOP(result),offr));
6222 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6224 /* shift right accumulator */
6229 aopPut(AOP(result),"a",offr);
6233 /*-----------------------------------------------------------------*/
6234 /* shiftL1Left2Result - shift left one byte from left to result */
6235 /*-----------------------------------------------------------------*/
6236 static void shiftL1Left2Result (operand *left, int offl,
6237 operand *result, int offr, int shCount)
6242 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6244 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6245 DEBUGpic14_emitcode ("; ***","same = %d",same);
6246 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6248 /* shift left accumulator */
6249 //AccLsh(shCount); // don't comment out just yet...
6250 // aopPut(AOP(result),"a",offr);
6254 /* Shift left 1 bit position */
6255 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6257 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6259 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6260 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6264 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6265 emitpcode(POC_ANDLW,popGetLit(0x7e));
6266 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6267 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6270 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6271 emitpcode(POC_ANDLW,popGetLit(0x3e));
6272 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6273 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6274 emitpcode(POC_RLF, popGet(AOP(result),offr));
6277 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6278 emitpcode(POC_ANDLW, popGetLit(0xf0));
6279 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6282 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6283 emitpcode(POC_ANDLW, popGetLit(0xf0));
6284 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6285 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6288 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6289 emitpcode(POC_ANDLW, popGetLit(0x30));
6290 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6291 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6292 emitpcode(POC_RLF, popGet(AOP(result),offr));
6295 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6296 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6297 emitpcode(POC_RRF, popGet(AOP(result),offr));
6301 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6306 /*-----------------------------------------------------------------*/
6307 /* movLeft2Result - move byte from left to result */
6308 /*-----------------------------------------------------------------*/
6309 static void movLeft2Result (operand *left, int offl,
6310 operand *result, int offr, int sign)
6313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6314 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6315 l = aopGet(AOP(left),offl,FALSE,FALSE);
6317 if (*l == '@' && (IS_AOP_PREG(result))) {
6318 pic14_emitcode("mov","a,%s",l);
6319 aopPut(AOP(result),"a",offr);
6322 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6323 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6325 //aopPut(AOP(result),l,offr);
6327 /* MSB sign in acc.7 ! */
6328 if(pic14_getDataSize(left) == offl+1){
6329 pic14_emitcode("mov","a,%s",l);
6330 aopPut(AOP(result),"a",offr);
6337 /*-----------------------------------------------------------------*/
6338 /* shiftL2Left2Result - shift left two bytes from left to result */
6339 /*-----------------------------------------------------------------*/
6340 static void shiftL2Left2Result (operand *left, int offl,
6341 operand *result, int offr, int shCount)
6345 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6347 if(pic14_sameRegs(AOP(result), AOP(left))) {
6355 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6356 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6357 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6361 emitpcode(POC_RLF, popGet(AOP(result),offr));
6362 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6368 emitpcode(POC_MOVLW, popGetLit(0x0f));
6369 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6370 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6371 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6372 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6373 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6374 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6376 emitpcode(POC_RLF, popGet(AOP(result),offr));
6377 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6381 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6382 emitpcode(POC_RRF, popGet(AOP(result),offr));
6383 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6384 emitpcode(POC_RRF, popGet(AOP(result),offr));
6385 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6386 emitpcode(POC_ANDLW,popGetLit(0xc0));
6387 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6388 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6389 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6390 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6393 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6394 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6395 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6396 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6397 emitpcode(POC_RRF, popGet(AOP(result),offr));
6407 /* note, use a mov/add for the shift since the mov has a
6408 chance of getting optimized out */
6409 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6411 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6412 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6413 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6417 emitpcode(POC_RLF, popGet(AOP(result),offr));
6418 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6424 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6425 emitpcode(POC_ANDLW, popGetLit(0xF0));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6427 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6428 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429 emitpcode(POC_ANDLW, popGetLit(0xF0));
6430 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6431 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6435 emitpcode(POC_RLF, popGet(AOP(result),offr));
6436 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6440 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6441 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6442 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6443 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6446 emitpcode(POC_RRF, popGet(AOP(result),offr));
6447 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6448 emitpcode(POC_ANDLW,popGetLit(0xc0));
6449 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6450 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6451 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6452 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6455 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6456 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6457 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6458 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6459 emitpcode(POC_RRF, popGet(AOP(result),offr));
6464 /*-----------------------------------------------------------------*/
6465 /* shiftR2Left2Result - shift right two bytes from left to result */
6466 /*-----------------------------------------------------------------*/
6467 static void shiftR2Left2Result (operand *left, int offl,
6468 operand *result, int offr,
6469 int shCount, int sign)
6473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6474 same = pic14_sameRegs(AOP(result), AOP(left));
6476 if(same && ((offl + MSB16) == offr)){
6478 /* don't crash result[offr] */
6479 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6480 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6482 movLeft2Result(left,offl, result, offr, 0);
6483 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6485 /* a:x >> shCount (x = lsb(result))*/
6488 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6490 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6500 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6501 emitpcode(POC_RRF,popGet(AOP(result),offr));
6504 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6505 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6506 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6507 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6512 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6513 emitpcode(POC_RRF,popGet(AOP(result),offr));
6520 emitpcode(POC_MOVLW, popGetLit(0xf0));
6521 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6522 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6524 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6525 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6526 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6527 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6529 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6530 emitpcode(POC_ANDLW, popGetLit(0x0f));
6531 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6533 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6534 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6535 emitpcode(POC_ANDLW, popGetLit(0xf0));
6536 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6537 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6541 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6542 emitpcode(POC_RRF, popGet(AOP(result),offr));
6550 emitpcode(POC_RLF, popGet(AOP(result),offr));
6551 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6553 emitpcode(POC_RLF, popGet(AOP(result),offr));
6554 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6555 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6556 emitpcode(POC_ANDLW,popGetLit(0x03));
6557 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6558 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6559 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6560 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6562 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6564 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6565 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6567 emitpcode(POC_RLF, popGet(AOP(result),offr));
6568 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6569 emitpcode(POC_ANDLW,popGetLit(0x03));
6570 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6575 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6576 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6577 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6578 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6579 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6584 /*-----------------------------------------------------------------*/
6585 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6586 /*-----------------------------------------------------------------*/
6587 static void shiftLLeftOrResult (operand *left, int offl,
6588 operand *result, int offr, int shCount)
6590 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6591 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6592 /* shift left accumulator */
6594 /* or with result */
6595 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6596 /* back to result */
6597 aopPut(AOP(result),"a",offr);
6600 /*-----------------------------------------------------------------*/
6601 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6602 /*-----------------------------------------------------------------*/
6603 static void shiftRLeftOrResult (operand *left, int offl,
6604 operand *result, int offr, int shCount)
6606 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6607 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6608 /* shift right accumulator */
6610 /* or with result */
6611 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6612 /* back to result */
6613 aopPut(AOP(result),"a",offr);
6616 /*-----------------------------------------------------------------*/
6617 /* genlshOne - left shift a one byte quantity by known count */
6618 /*-----------------------------------------------------------------*/
6619 static void genlshOne (operand *result, operand *left, int shCount)
6621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6622 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6625 /*-----------------------------------------------------------------*/
6626 /* genlshTwo - left shift two bytes by known amount != 0 */
6627 /*-----------------------------------------------------------------*/
6628 static void genlshTwo (operand *result,operand *left, int shCount)
6632 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6633 size = pic14_getDataSize(result);
6635 /* if shCount >= 8 */
6641 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6643 movLeft2Result(left, LSB, result, MSB16, 0);
6645 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6648 /* 1 <= shCount <= 7 */
6651 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6653 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6657 /*-----------------------------------------------------------------*/
6658 /* shiftLLong - shift left one long from left to result */
6659 /* offl = LSB or MSB16 */
6660 /*-----------------------------------------------------------------*/
6661 static void shiftLLong (operand *left, operand *result, int offr )
6664 int size = AOP_SIZE(result);
6666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6667 if(size >= LSB+offr){
6668 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6670 pic14_emitcode("add","a,acc");
6671 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6672 size >= MSB16+offr && offr != LSB )
6673 pic14_emitcode("xch","a,%s",
6674 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6676 aopPut(AOP(result),"a",LSB+offr);
6679 if(size >= MSB16+offr){
6680 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6681 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6684 pic14_emitcode("rlc","a");
6685 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6686 size >= MSB24+offr && offr != LSB)
6687 pic14_emitcode("xch","a,%s",
6688 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6690 aopPut(AOP(result),"a",MSB16+offr);
6693 if(size >= MSB24+offr){
6694 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6695 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6698 pic14_emitcode("rlc","a");
6699 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6700 size >= MSB32+offr && offr != LSB )
6701 pic14_emitcode("xch","a,%s",
6702 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6704 aopPut(AOP(result),"a",MSB24+offr);
6707 if(size > MSB32+offr){
6708 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6709 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6712 pic14_emitcode("rlc","a");
6713 aopPut(AOP(result),"a",MSB32+offr);
6716 aopPut(AOP(result),zero,LSB);
6719 /*-----------------------------------------------------------------*/
6720 /* genlshFour - shift four byte by a known amount != 0 */
6721 /*-----------------------------------------------------------------*/
6722 static void genlshFour (operand *result, operand *left, int shCount)
6726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6727 size = AOP_SIZE(result);
6729 /* if shifting more that 3 bytes */
6730 if (shCount >= 24 ) {
6733 /* lowest order of left goes to the highest
6734 order of the destination */
6735 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6737 movLeft2Result(left, LSB, result, MSB32, 0);
6738 aopPut(AOP(result),zero,LSB);
6739 aopPut(AOP(result),zero,MSB16);
6740 aopPut(AOP(result),zero,MSB32);
6744 /* more than two bytes */
6745 else if ( shCount >= 16 ) {
6746 /* lower order two bytes goes to higher order two bytes */
6748 /* if some more remaining */
6750 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6752 movLeft2Result(left, MSB16, result, MSB32, 0);
6753 movLeft2Result(left, LSB, result, MSB24, 0);
6755 aopPut(AOP(result),zero,MSB16);
6756 aopPut(AOP(result),zero,LSB);
6760 /* if more than 1 byte */
6761 else if ( shCount >= 8 ) {
6762 /* lower order three bytes goes to higher order three bytes */
6766 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6768 movLeft2Result(left, LSB, result, MSB16, 0);
6770 else{ /* size = 4 */
6772 movLeft2Result(left, MSB24, result, MSB32, 0);
6773 movLeft2Result(left, MSB16, result, MSB24, 0);
6774 movLeft2Result(left, LSB, result, MSB16, 0);
6775 aopPut(AOP(result),zero,LSB);
6777 else if(shCount == 1)
6778 shiftLLong(left, result, MSB16);
6780 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6781 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6782 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6783 aopPut(AOP(result),zero,LSB);
6788 /* 1 <= shCount <= 7 */
6789 else if(shCount <= 2){
6790 shiftLLong(left, result, LSB);
6792 shiftLLong(result, result, LSB);
6794 /* 3 <= shCount <= 7, optimize */
6796 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6797 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6798 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6802 /*-----------------------------------------------------------------*/
6803 /* genLeftShiftLiteral - left shifting by known count */
6804 /*-----------------------------------------------------------------*/
6805 static void genLeftShiftLiteral (operand *left,
6810 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6813 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6814 freeAsmop(right,NULL,ic,TRUE);
6816 aopOp(left,ic,FALSE);
6817 aopOp(result,ic,FALSE);
6819 size = getSize(operandType(result));
6822 pic14_emitcode("; shift left ","result %d, left %d",size,
6826 /* I suppose that the left size >= result size */
6829 movLeft2Result(left, size, result, size, 0);
6833 else if(shCount >= (size * 8))
6835 aopPut(AOP(result),zero,size);
6839 genlshOne (result,left,shCount);
6844 genlshTwo (result,left,shCount);
6848 genlshFour (result,left,shCount);
6852 freeAsmop(left,NULL,ic,TRUE);
6853 freeAsmop(result,NULL,ic,TRUE);
6856 /*-----------------------------------------------------------------*
6857 * genMultiAsm - repeat assembly instruction for size of register.
6858 * if endian == 1, then the high byte (i.e base address + size of
6859 * register) is used first else the low byte is used first;
6860 *-----------------------------------------------------------------*/
6861 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6879 emitpcode(poc, popGet(AOP(reg),offset));
6884 /*-----------------------------------------------------------------*/
6885 /* genLeftShift - generates code for left shifting */
6886 /*-----------------------------------------------------------------*/
6887 static void genLeftShift (iCode *ic)
6889 operand *left,*right, *result;
6892 symbol *tlbl , *tlbl1;
6894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6896 right = IC_RIGHT(ic);
6898 result = IC_RESULT(ic);
6900 aopOp(right,ic,FALSE);
6902 /* if the shift count is known then do it
6903 as efficiently as possible */
6904 if (AOP_TYPE(right) == AOP_LIT) {
6905 genLeftShiftLiteral (left,right,result,ic);
6909 /* shift count is unknown then we have to form
6910 a loop get the loop count in B : Note: we take
6911 only the lower order byte since shifting
6912 more that 32 bits make no sense anyway, ( the
6913 largest size of an object can be only 32 bits ) */
6916 aopOp(left,ic,FALSE);
6917 aopOp(result,ic,FALSE);
6919 /* now move the left to the result if they are not the
6921 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6922 AOP_SIZE(result) > 1) {
6924 size = AOP_SIZE(result);
6927 l = aopGet(AOP(left),offset,FALSE,TRUE);
6928 if (*l == '@' && (IS_AOP_PREG(result))) {
6930 pic14_emitcode("mov","a,%s",l);
6931 aopPut(AOP(result),"a",offset);
6933 aopPut(AOP(result),l,offset);
6938 size = AOP_SIZE(result);
6940 /* if it is only one byte then */
6942 if(optimized_for_speed) {
6943 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6944 emitpcode(POC_ANDLW, popGetLit(0xf0));
6945 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6946 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6947 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6948 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6949 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6950 emitpcode(POC_RLFW, popGet(AOP(result),0));
6951 emitpcode(POC_ANDLW, popGetLit(0xfe));
6952 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6953 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6954 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6957 tlbl = newiTempLabel(NULL);
6958 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6959 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6960 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6963 emitpcode(POC_COMFW, popGet(AOP(right),0));
6964 emitpcode(POC_RRF, popGet(AOP(result),0));
6965 emitpLabel(tlbl->key);
6966 emitpcode(POC_RLF, popGet(AOP(result),0));
6967 emitpcode(POC_ADDLW, popGetLit(1));
6969 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6974 if (pic14_sameRegs(AOP(left),AOP(result))) {
6976 tlbl = newiTempLabel(NULL);
6977 emitpcode(POC_COMFW, popGet(AOP(right),0));
6978 genMultiAsm(POC_RRF, result, size,1);
6979 emitpLabel(tlbl->key);
6980 genMultiAsm(POC_RLF, result, size,0);
6981 emitpcode(POC_ADDLW, popGetLit(1));
6983 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6987 tlbl = newiTempLabel(NULL);
6989 tlbl1 = newiTempLabel(NULL);
6991 reAdjustPreg(AOP(result));
6993 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6994 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6995 l = aopGet(AOP(result),offset,FALSE,FALSE);
6997 pic14_emitcode("add","a,acc");
6998 aopPut(AOP(result),"a",offset++);
7000 l = aopGet(AOP(result),offset,FALSE,FALSE);
7002 pic14_emitcode("rlc","a");
7003 aopPut(AOP(result),"a",offset++);
7005 reAdjustPreg(AOP(result));
7007 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7008 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7010 freeAsmop (right,NULL,ic,TRUE);
7011 freeAsmop(left,NULL,ic,TRUE);
7012 freeAsmop(result,NULL,ic,TRUE);
7015 /*-----------------------------------------------------------------*/
7016 /* genrshOne - right shift a one byte quantity by known count */
7017 /*-----------------------------------------------------------------*/
7018 static void genrshOne (operand *result, operand *left,
7019 int shCount, int sign)
7021 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7022 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7025 /*-----------------------------------------------------------------*/
7026 /* genrshTwo - right shift two bytes by known amount != 0 */
7027 /*-----------------------------------------------------------------*/
7028 static void genrshTwo (operand *result,operand *left,
7029 int shCount, int sign)
7031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7032 /* if shCount >= 8 */
7036 shiftR1Left2Result(left, MSB16, result, LSB,
7039 movLeft2Result(left, MSB16, result, LSB, sign);
7041 addSign(result, MSB16, sign);
7043 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7047 /* 1 <= shCount <= 7 */
7049 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7052 /*-----------------------------------------------------------------*/
7053 /* shiftRLong - shift right one long from left to result */
7054 /* offl = LSB or MSB16 */
7055 /*-----------------------------------------------------------------*/
7056 static void shiftRLong (operand *left, int offl,
7057 operand *result, int sign)
7059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7061 pic14_emitcode("clr","c");
7062 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7064 pic14_emitcode("mov","c,acc.7");
7065 pic14_emitcode("rrc","a");
7066 aopPut(AOP(result),"a",MSB32-offl);
7068 /* add sign of "a" */
7069 addSign(result, MSB32, sign);
7071 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7072 pic14_emitcode("rrc","a");
7073 aopPut(AOP(result),"a",MSB24-offl);
7075 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7076 pic14_emitcode("rrc","a");
7077 aopPut(AOP(result),"a",MSB16-offl);
7080 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7081 pic14_emitcode("rrc","a");
7082 aopPut(AOP(result),"a",LSB);
7086 /*-----------------------------------------------------------------*/
7087 /* genrshFour - shift four byte by a known amount != 0 */
7088 /*-----------------------------------------------------------------*/
7089 static void genrshFour (operand *result, operand *left,
7090 int shCount, int sign)
7092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7093 /* if shifting more that 3 bytes */
7094 if(shCount >= 24 ) {
7097 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7099 movLeft2Result(left, MSB32, result, LSB, sign);
7100 addSign(result, MSB16, sign);
7102 else if(shCount >= 16){
7105 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7107 movLeft2Result(left, MSB24, result, LSB, 0);
7108 movLeft2Result(left, MSB32, result, MSB16, sign);
7110 addSign(result, MSB24, sign);
7112 else if(shCount >= 8){
7115 shiftRLong(left, MSB16, result, sign);
7116 else if(shCount == 0){
7117 movLeft2Result(left, MSB16, result, LSB, 0);
7118 movLeft2Result(left, MSB24, result, MSB16, 0);
7119 movLeft2Result(left, MSB32, result, MSB24, sign);
7120 addSign(result, MSB32, sign);
7123 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7124 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7125 /* the last shift is signed */
7126 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7127 addSign(result, MSB32, sign);
7130 else{ /* 1 <= shCount <= 7 */
7132 shiftRLong(left, LSB, result, sign);
7134 shiftRLong(result, LSB, result, sign);
7137 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7138 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7139 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7144 /*-----------------------------------------------------------------*/
7145 /* genRightShiftLiteral - right shifting by known count */
7146 /*-----------------------------------------------------------------*/
7147 static void genRightShiftLiteral (operand *left,
7153 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7157 freeAsmop(right,NULL,ic,TRUE);
7159 aopOp(left,ic,FALSE);
7160 aopOp(result,ic,FALSE);
7163 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7167 size = pic14_getDataSize(left);
7168 /* test the LEFT size !!! */
7170 /* I suppose that the left size >= result size */
7172 size = pic14_getDataSize(result);
7174 movLeft2Result(left, size, result, size, 0);
7177 else if(shCount >= (size * 8)){
7179 /* get sign in acc.7 */
7180 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7181 addSign(result, LSB, sign);
7185 genrshOne (result,left,shCount,sign);
7189 genrshTwo (result,left,shCount,sign);
7193 genrshFour (result,left,shCount,sign);
7199 freeAsmop(left,NULL,ic,TRUE);
7200 freeAsmop(result,NULL,ic,TRUE);
7204 /*-----------------------------------------------------------------*/
7205 /* genSignedRightShift - right shift of signed number */
7206 /*-----------------------------------------------------------------*/
7207 static void genSignedRightShift (iCode *ic)
7209 operand *right, *left, *result;
7212 symbol *tlbl, *tlbl1 ;
7214 /* we do it the hard way put the shift count in b
7215 and loop thru preserving the sign */
7216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7218 right = IC_RIGHT(ic);
7220 result = IC_RESULT(ic);
7222 aopOp(right,ic,FALSE);
7225 if ( AOP_TYPE(right) == AOP_LIT) {
7226 genRightShiftLiteral (left,right,result,ic,1);
7229 /* shift count is unknown then we have to form
7230 a loop get the loop count in B : Note: we take
7231 only the lower order byte since shifting
7232 more that 32 bits make no sense anyway, ( the
7233 largest size of an object can be only 32 bits ) */
7235 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7236 pic14_emitcode("inc","b");
7237 freeAsmop (right,NULL,ic,TRUE);
7238 aopOp(left,ic,FALSE);
7239 aopOp(result,ic,FALSE);
7241 /* now move the left to the result if they are not the
7243 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7244 AOP_SIZE(result) > 1) {
7246 size = AOP_SIZE(result);
7249 l = aopGet(AOP(left),offset,FALSE,TRUE);
7250 if (*l == '@' && IS_AOP_PREG(result)) {
7252 pic14_emitcode("mov","a,%s",l);
7253 aopPut(AOP(result),"a",offset);
7255 aopPut(AOP(result),l,offset);
7260 /* mov the highest order bit to OVR */
7261 tlbl = newiTempLabel(NULL);
7262 tlbl1= newiTempLabel(NULL);
7264 size = AOP_SIZE(result);
7266 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7267 pic14_emitcode("rlc","a");
7268 pic14_emitcode("mov","ov,c");
7269 /* if it is only one byte then */
7271 l = aopGet(AOP(left),0,FALSE,FALSE);
7273 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7274 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7275 pic14_emitcode("mov","c,ov");
7276 pic14_emitcode("rrc","a");
7277 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7278 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7279 aopPut(AOP(result),"a",0);
7283 reAdjustPreg(AOP(result));
7284 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7285 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7286 pic14_emitcode("mov","c,ov");
7288 l = aopGet(AOP(result),offset,FALSE,FALSE);
7290 pic14_emitcode("rrc","a");
7291 aopPut(AOP(result),"a",offset--);
7293 reAdjustPreg(AOP(result));
7294 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7295 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7298 freeAsmop(left,NULL,ic,TRUE);
7299 freeAsmop(result,NULL,ic,TRUE);
7302 /*-----------------------------------------------------------------*/
7303 /* genRightShift - generate code for right shifting */
7304 /*-----------------------------------------------------------------*/
7305 static void genRightShift (iCode *ic)
7307 operand *right, *left, *result;
7311 symbol *tlbl, *tlbl1 ;
7313 /* if signed then we do it the hard way preserve the
7314 sign bit moving it inwards */
7315 retype = getSpec(operandType(IC_RESULT(ic)));
7316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7318 if (!SPEC_USIGN(retype)) {
7319 genSignedRightShift (ic);
7323 /* signed & unsigned types are treated the same : i.e. the
7324 signed is NOT propagated inwards : quoting from the
7325 ANSI - standard : "for E1 >> E2, is equivalent to division
7326 by 2**E2 if unsigned or if it has a non-negative value,
7327 otherwise the result is implementation defined ", MY definition
7328 is that the sign does not get propagated */
7330 right = IC_RIGHT(ic);
7332 result = IC_RESULT(ic);
7334 aopOp(right,ic,FALSE);
7336 /* if the shift count is known then do it
7337 as efficiently as possible */
7338 if (AOP_TYPE(right) == AOP_LIT) {
7339 genRightShiftLiteral (left,right,result,ic, 0);
7343 /* shift count is unknown then we have to form
7344 a loop get the loop count in B : Note: we take
7345 only the lower order byte since shifting
7346 more that 32 bits make no sense anyway, ( the
7347 largest size of an object can be only 32 bits ) */
7349 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7350 pic14_emitcode("inc","b");
7351 aopOp(left,ic,FALSE);
7352 aopOp(result,ic,FALSE);
7354 /* now move the left to the result if they are not the
7356 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7357 AOP_SIZE(result) > 1) {
7359 size = AOP_SIZE(result);
7362 l = aopGet(AOP(left),offset,FALSE,TRUE);
7363 if (*l == '@' && IS_AOP_PREG(result)) {
7365 pic14_emitcode("mov","a,%s",l);
7366 aopPut(AOP(result),"a",offset);
7368 aopPut(AOP(result),l,offset);
7373 tlbl = newiTempLabel(NULL);
7374 tlbl1= newiTempLabel(NULL);
7375 size = AOP_SIZE(result);
7378 /* if it is only one byte then */
7381 l = aopGet(AOP(left),0,FALSE,FALSE);
7383 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7384 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7386 pic14_emitcode("rrc","a");
7387 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7388 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7389 aopPut(AOP(result),"a",0);
7391 tlbl = newiTempLabel(NULL);
7392 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7393 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7394 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7397 emitpcode(POC_COMFW, popGet(AOP(right),0));
7398 emitpcode(POC_RLF, popGet(AOP(result),0));
7399 emitpLabel(tlbl->key);
7400 emitpcode(POC_RRF, popGet(AOP(result),0));
7401 emitpcode(POC_ADDLW, popGetLit(1));
7403 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7408 reAdjustPreg(AOP(result));
7409 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7410 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7413 l = aopGet(AOP(result),offset,FALSE,FALSE);
7415 pic14_emitcode("rrc","a");
7416 aopPut(AOP(result),"a",offset--);
7418 reAdjustPreg(AOP(result));
7420 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7421 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7424 freeAsmop(left,NULL,ic,TRUE);
7425 freeAsmop (right,NULL,ic,TRUE);
7426 freeAsmop(result,NULL,ic,TRUE);
7429 /*-----------------------------------------------------------------*/
7430 /* genUnpackBits - generates code for unpacking bits */
7431 /*-----------------------------------------------------------------*/
7432 static void genUnpackBits (operand *result, char *rname, int ptype)
7439 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7440 etype = getSpec(operandType(result));
7442 /* read the first byte */
7447 pic14_emitcode("mov","a,@%s",rname);
7451 pic14_emitcode("movx","a,@%s",rname);
7455 pic14_emitcode("movx","a,@dptr");
7459 pic14_emitcode("clr","a");
7460 pic14_emitcode("movc","a","@a+dptr");
7464 pic14_emitcode("lcall","__gptrget");
7468 /* if we have bitdisplacement then it fits */
7469 /* into this byte completely or if length is */
7470 /* less than a byte */
7471 if ((shCnt = SPEC_BSTR(etype)) ||
7472 (SPEC_BLEN(etype) <= 8)) {
7474 /* shift right acc */
7477 pic14_emitcode("anl","a,#0x%02x",
7478 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7479 aopPut(AOP(result),"a",offset);
7483 /* bit field did not fit in a byte */
7484 rlen = SPEC_BLEN(etype) - 8;
7485 aopPut(AOP(result),"a",offset++);
7492 pic14_emitcode("inc","%s",rname);
7493 pic14_emitcode("mov","a,@%s",rname);
7497 pic14_emitcode("inc","%s",rname);
7498 pic14_emitcode("movx","a,@%s",rname);
7502 pic14_emitcode("inc","dptr");
7503 pic14_emitcode("movx","a,@dptr");
7507 pic14_emitcode("clr","a");
7508 pic14_emitcode("inc","dptr");
7509 pic14_emitcode("movc","a","@a+dptr");
7513 pic14_emitcode("inc","dptr");
7514 pic14_emitcode("lcall","__gptrget");
7519 /* if we are done */
7523 aopPut(AOP(result),"a",offset++);
7528 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7529 aopPut(AOP(result),"a",offset);
7536 /*-----------------------------------------------------------------*/
7537 /* genDataPointerGet - generates code when ptr offset is known */
7538 /*-----------------------------------------------------------------*/
7539 static void genDataPointerGet (operand *left,
7543 int size , offset = 0;
7546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7549 /* optimization - most of the time, left and result are the same
7550 * address, but different types. for the pic code, we could omit
7554 aopOp(result,ic,TRUE);
7556 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7558 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7560 size = AOP_SIZE(result);
7563 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7567 freeAsmop(left,NULL,ic,TRUE);
7568 freeAsmop(result,NULL,ic,TRUE);
7571 /*-----------------------------------------------------------------*/
7572 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7573 /*-----------------------------------------------------------------*/
7574 static void genNearPointerGet (operand *left,
7581 sym_link *rtype, *retype;
7582 sym_link *ltype = operandType(left);
7585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7587 rtype = operandType(result);
7588 retype= getSpec(rtype);
7590 aopOp(left,ic,FALSE);
7592 /* if left is rematerialisable and
7593 result is not bit variable type and
7594 the left is pointer to data space i.e
7595 lower 128 bytes of space */
7596 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7597 !IS_BITVAR(retype) &&
7598 DCL_TYPE(ltype) == POINTER) {
7599 //genDataPointerGet (left,result,ic);
7603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7605 /* if the value is already in a pointer register
7606 then don't need anything more */
7607 if (!AOP_INPREG(AOP(left))) {
7608 /* otherwise get a free pointer register */
7609 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7611 preg = getFreePtr(ic,&aop,FALSE);
7612 pic14_emitcode("mov","%s,%s",
7614 aopGet(AOP(left),0,FALSE,TRUE));
7615 rname = preg->name ;
7617 rname = aopGet(AOP(left),0,FALSE,FALSE);
7619 freeAsmop(left,NULL,ic,TRUE);
7620 aopOp (result,ic,FALSE);
7622 /* if bitfield then unpack the bits */
7623 if (IS_BITVAR(retype))
7624 genUnpackBits (result,rname,POINTER);
7626 /* we have can just get the values */
7627 int size = AOP_SIZE(result);
7630 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7632 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7634 pic14_emitcode("mov","a,@%s",rname);
7635 aopPut(AOP(result),"a",offset);
7637 sprintf(buffer,"@%s",rname);
7638 aopPut(AOP(result),buffer,offset);
7642 pic14_emitcode("inc","%s",rname);
7646 /* now some housekeeping stuff */
7648 /* we had to allocate for this iCode */
7649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7650 freeAsmop(NULL,aop,ic,TRUE);
7652 /* we did not allocate which means left
7653 already in a pointer register, then
7654 if size > 0 && this could be used again
7655 we have to point it back to where it
7657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7658 if (AOP_SIZE(result) > 1 &&
7659 !OP_SYMBOL(left)->remat &&
7660 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7662 int size = AOP_SIZE(result) - 1;
7664 pic14_emitcode("dec","%s",rname);
7669 freeAsmop(result,NULL,ic,TRUE);
7673 /*-----------------------------------------------------------------*/
7674 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7675 /*-----------------------------------------------------------------*/
7676 static void genPagedPointerGet (operand *left,
7683 sym_link *rtype, *retype;
7685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7687 rtype = operandType(result);
7688 retype= getSpec(rtype);
7690 aopOp(left,ic,FALSE);
7692 /* if the value is already in a pointer register
7693 then don't need anything more */
7694 if (!AOP_INPREG(AOP(left))) {
7695 /* otherwise get a free pointer register */
7697 preg = getFreePtr(ic,&aop,FALSE);
7698 pic14_emitcode("mov","%s,%s",
7700 aopGet(AOP(left),0,FALSE,TRUE));
7701 rname = preg->name ;
7703 rname = aopGet(AOP(left),0,FALSE,FALSE);
7705 freeAsmop(left,NULL,ic,TRUE);
7706 aopOp (result,ic,FALSE);
7708 /* if bitfield then unpack the bits */
7709 if (IS_BITVAR(retype))
7710 genUnpackBits (result,rname,PPOINTER);
7712 /* we have can just get the values */
7713 int size = AOP_SIZE(result);
7718 pic14_emitcode("movx","a,@%s",rname);
7719 aopPut(AOP(result),"a",offset);
7724 pic14_emitcode("inc","%s",rname);
7728 /* now some housekeeping stuff */
7730 /* we had to allocate for this iCode */
7731 freeAsmop(NULL,aop,ic,TRUE);
7733 /* we did not allocate which means left
7734 already in a pointer register, then
7735 if size > 0 && this could be used again
7736 we have to point it back to where it
7738 if (AOP_SIZE(result) > 1 &&
7739 !OP_SYMBOL(left)->remat &&
7740 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7742 int size = AOP_SIZE(result) - 1;
7744 pic14_emitcode("dec","%s",rname);
7749 freeAsmop(result,NULL,ic,TRUE);
7754 /*-----------------------------------------------------------------*/
7755 /* genFarPointerGet - gget value from far space */
7756 /*-----------------------------------------------------------------*/
7757 static void genFarPointerGet (operand *left,
7758 operand *result, iCode *ic)
7761 sym_link *retype = getSpec(operandType(result));
7763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7765 aopOp(left,ic,FALSE);
7767 /* if the operand is already in dptr
7768 then we do nothing else we move the value to dptr */
7769 if (AOP_TYPE(left) != AOP_STR) {
7770 /* if this is remateriazable */
7771 if (AOP_TYPE(left) == AOP_IMMD)
7772 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7773 else { /* we need to get it byte by byte */
7774 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7775 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7776 if (options.model == MODEL_FLAT24)
7778 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7782 /* so dptr know contains the address */
7783 freeAsmop(left,NULL,ic,TRUE);
7784 aopOp(result,ic,FALSE);
7786 /* if bit then unpack */
7787 if (IS_BITVAR(retype))
7788 genUnpackBits(result,"dptr",FPOINTER);
7790 size = AOP_SIZE(result);
7794 pic14_emitcode("movx","a,@dptr");
7795 aopPut(AOP(result),"a",offset++);
7797 pic14_emitcode("inc","dptr");
7801 freeAsmop(result,NULL,ic,TRUE);
7804 /*-----------------------------------------------------------------*/
7805 /* genCodePointerGet - get value from code space */
7806 /*-----------------------------------------------------------------*/
7807 static void genCodePointerGet (operand *left,
7808 operand *result, iCode *ic)
7811 sym_link *retype = getSpec(operandType(result));
7813 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7815 aopOp(left,ic,FALSE);
7817 /* if the operand is already in dptr
7818 then we do nothing else we move the value to dptr */
7819 if (AOP_TYPE(left) != AOP_STR) {
7820 /* if this is remateriazable */
7821 if (AOP_TYPE(left) == AOP_IMMD)
7822 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7823 else { /* we need to get it byte by byte */
7824 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7825 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7826 if (options.model == MODEL_FLAT24)
7828 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7832 /* so dptr know contains the address */
7833 freeAsmop(left,NULL,ic,TRUE);
7834 aopOp(result,ic,FALSE);
7836 /* if bit then unpack */
7837 if (IS_BITVAR(retype))
7838 genUnpackBits(result,"dptr",CPOINTER);
7840 size = AOP_SIZE(result);
7844 pic14_emitcode("clr","a");
7845 pic14_emitcode("movc","a,@a+dptr");
7846 aopPut(AOP(result),"a",offset++);
7848 pic14_emitcode("inc","dptr");
7852 freeAsmop(result,NULL,ic,TRUE);
7855 /*-----------------------------------------------------------------*/
7856 /* genGenPointerGet - gget value from generic pointer space */
7857 /*-----------------------------------------------------------------*/
7858 static void genGenPointerGet (operand *left,
7859 operand *result, iCode *ic)
7862 sym_link *retype = getSpec(operandType(result));
7864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7865 aopOp(left,ic,FALSE);
7866 aopOp(result,ic,FALSE);
7869 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7871 /* if the operand is already in dptr
7872 then we do nothing else we move the value to dptr */
7873 // if (AOP_TYPE(left) != AOP_STR) {
7874 /* if this is remateriazable */
7875 if (AOP_TYPE(left) == AOP_IMMD) {
7876 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7877 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7879 else { /* we need to get it byte by byte */
7881 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7882 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7884 size = AOP_SIZE(result);
7888 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7889 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7891 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7896 /* so dptr know contains the address */
7898 /* if bit then unpack */
7899 //if (IS_BITVAR(retype))
7900 // genUnpackBits(result,"dptr",GPOINTER);
7903 freeAsmop(left,NULL,ic,TRUE);
7904 freeAsmop(result,NULL,ic,TRUE);
7908 /*-----------------------------------------------------------------*/
7909 /* genConstPointerGet - get value from const generic pointer space */
7910 /*-----------------------------------------------------------------*/
7911 static void genConstPointerGet (operand *left,
7912 operand *result, iCode *ic)
7914 //sym_link *retype = getSpec(operandType(result));
7915 symbol *albl = newiTempLabel(NULL);
7916 symbol *blbl = newiTempLabel(NULL);
7919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7920 aopOp(left,ic,FALSE);
7921 aopOp(result,ic,FALSE);
7924 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7926 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
7928 emitpcode(POC_CALL,popGetLabel(albl->key));
7929 emitpcode(POC_GOTO,popGetLabel(blbl->key));
7930 emitpLabel(albl->key);
7932 poc = ( (AOP_TYPE(left) == AOP_IMMD) ? POC_MOVLW : POC_MOVFW);
7934 emitpcode(poc,popGet(AOP(left),1));
7935 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
7936 emitpcode(poc,popGet(AOP(left),0));
7937 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
7939 emitpLabel(blbl->key);
7941 emitpcode(POC_MOVWF,popGet(AOP(result),0));
7944 freeAsmop(left,NULL,ic,TRUE);
7945 freeAsmop(result,NULL,ic,TRUE);
7948 /*-----------------------------------------------------------------*/
7949 /* genPointerGet - generate code for pointer get */
7950 /*-----------------------------------------------------------------*/
7951 static void genPointerGet (iCode *ic)
7953 operand *left, *result ;
7954 sym_link *type, *etype;
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7960 result = IC_RESULT(ic) ;
7962 /* depending on the type of pointer we need to
7963 move it to the correct pointer register */
7964 type = operandType(left);
7965 etype = getSpec(type);
7967 if (IS_PTR_CONST(type))
7968 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
7970 /* if left is of type of pointer then it is simple */
7971 if (IS_PTR(type) && !IS_FUNC(type->next))
7972 p_type = DCL_TYPE(type);
7974 /* we have to go by the storage class */
7975 p_type = PTR_TYPE(SPEC_OCLS(etype));
7977 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
7979 if (SPEC_OCLS(etype)->codesp ) {
7980 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
7981 //p_type = CPOINTER ;
7984 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
7985 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
7986 /*p_type = FPOINTER ;*/
7988 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
7989 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
7990 /* p_type = PPOINTER; */
7992 if (SPEC_OCLS(etype) == idata )
7993 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
7994 /* p_type = IPOINTER; */
7996 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
7997 /* p_type = POINTER ; */
8000 /* now that we have the pointer type we assign
8001 the pointer values */
8006 genNearPointerGet (left,result,ic);
8010 genPagedPointerGet(left,result,ic);
8014 genFarPointerGet (left,result,ic);
8018 genConstPointerGet (left,result,ic);
8019 //pic14_emitcodePointerGet (left,result,ic);
8023 if (IS_PTR_CONST(type))
8024 genConstPointerGet (left,result,ic);
8026 genGenPointerGet (left,result,ic);
8032 /*-----------------------------------------------------------------*/
8033 /* genPackBits - generates code for packed bit storage */
8034 /*-----------------------------------------------------------------*/
8035 static void genPackBits (sym_link *etype ,
8037 char *rname, int p_type)
8045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8046 blen = SPEC_BLEN(etype);
8047 bstr = SPEC_BSTR(etype);
8049 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8052 /* if the bit lenth is less than or */
8053 /* it exactly fits a byte then */
8054 if (SPEC_BLEN(etype) <= 8 ) {
8055 shCount = SPEC_BSTR(etype) ;
8057 /* shift left acc */
8060 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8065 pic14_emitcode ("mov","b,a");
8066 pic14_emitcode("mov","a,@%s",rname);
8070 pic14_emitcode ("mov","b,a");
8071 pic14_emitcode("movx","a,@dptr");
8075 pic14_emitcode ("push","b");
8076 pic14_emitcode ("push","acc");
8077 pic14_emitcode ("lcall","__gptrget");
8078 pic14_emitcode ("pop","b");
8082 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8083 ((unsigned char)(0xFF << (blen+bstr)) |
8084 (unsigned char)(0xFF >> (8-bstr)) ) );
8085 pic14_emitcode ("orl","a,b");
8086 if (p_type == GPOINTER)
8087 pic14_emitcode("pop","b");
8093 pic14_emitcode("mov","@%s,a",rname);
8097 pic14_emitcode("movx","@dptr,a");
8101 DEBUGpic14_emitcode(";lcall","__gptrput");
8106 if ( SPEC_BLEN(etype) <= 8 )
8109 pic14_emitcode("inc","%s",rname);
8110 rLen = SPEC_BLEN(etype) ;
8112 /* now generate for lengths greater than one byte */
8115 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8125 pic14_emitcode("mov","@%s,a",rname);
8127 pic14_emitcode("mov","@%s,%s",rname,l);
8132 pic14_emitcode("movx","@dptr,a");
8137 DEBUGpic14_emitcode(";lcall","__gptrput");
8140 pic14_emitcode ("inc","%s",rname);
8145 /* last last was not complete */
8147 /* save the byte & read byte */
8150 pic14_emitcode ("mov","b,a");
8151 pic14_emitcode("mov","a,@%s",rname);
8155 pic14_emitcode ("mov","b,a");
8156 pic14_emitcode("movx","a,@dptr");
8160 pic14_emitcode ("push","b");
8161 pic14_emitcode ("push","acc");
8162 pic14_emitcode ("lcall","__gptrget");
8163 pic14_emitcode ("pop","b");
8167 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8168 pic14_emitcode ("orl","a,b");
8171 if (p_type == GPOINTER)
8172 pic14_emitcode("pop","b");
8177 pic14_emitcode("mov","@%s,a",rname);
8181 pic14_emitcode("movx","@dptr,a");
8185 DEBUGpic14_emitcode(";lcall","__gptrput");
8189 /*-----------------------------------------------------------------*/
8190 /* genDataPointerSet - remat pointer to data space */
8191 /*-----------------------------------------------------------------*/
8192 static void genDataPointerSet(operand *right,
8196 int size, offset = 0 ;
8197 char *l, buffer[256];
8199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8200 aopOp(right,ic,FALSE);
8202 l = aopGet(AOP(result),0,FALSE,TRUE);
8203 size = AOP_SIZE(right);
8204 if ( AOP_TYPE(result) == AOP_PCODE) {
8205 fprintf(stderr,"genDataPointerSet %s, %d\n",
8206 AOP(result)->aopu.pcop->name,
8207 PCOI(AOP(result)->aopu.pcop)->offset);
8210 // tsd, was l+1 - the underline `_' prefix was being stripped
8213 sprintf(buffer,"(%s + %d)",l,offset);
8214 fprintf(stderr,"oops %s\n",buffer);
8216 sprintf(buffer,"%s",l);
8218 if (AOP_TYPE(right) == AOP_LIT) {
8219 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8220 lit = lit >> (8*offset);
8222 pic14_emitcode("movlw","%d",lit);
8223 pic14_emitcode("movwf","%s",buffer);
8225 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8226 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8227 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8230 pic14_emitcode("clrf","%s",buffer);
8231 //emitpcode(POC_CLRF, popRegFromString(buffer));
8232 emitpcode(POC_CLRF, popGet(AOP(result),0));
8235 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8236 pic14_emitcode("movwf","%s",buffer);
8238 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8239 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8240 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8247 freeAsmop(right,NULL,ic,TRUE);
8248 freeAsmop(result,NULL,ic,TRUE);
8251 /*-----------------------------------------------------------------*/
8252 /* genNearPointerSet - pic14_emitcode for near pointer put */
8253 /*-----------------------------------------------------------------*/
8254 static void genNearPointerSet (operand *right,
8261 sym_link *ptype = operandType(result);
8264 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8265 retype= getSpec(operandType(right));
8267 aopOp(result,ic,FALSE);
8269 /* if the result is rematerializable &
8270 in data space & not a bit variable */
8271 //if (AOP_TYPE(result) == AOP_IMMD &&
8272 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8273 DCL_TYPE(ptype) == POINTER &&
8274 !IS_BITVAR(retype)) {
8275 genDataPointerSet (right,result,ic);
8279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8281 /* if the value is already in a pointer register
8282 then don't need anything more */
8283 if (!AOP_INPREG(AOP(result))) {
8284 /* otherwise get a free pointer register */
8285 //aop = newAsmop(0);
8286 //preg = getFreePtr(ic,&aop,FALSE);
8287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8288 //pic14_emitcode("mov","%s,%s",
8290 // aopGet(AOP(result),0,FALSE,TRUE));
8291 //rname = preg->name ;
8292 pic14_emitcode("movwf","fsr");
8294 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8296 freeAsmop(result,NULL,ic,TRUE);
8297 aopOp (right,ic,FALSE);
8298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8300 /* if bitfield then unpack the bits */
8301 if (IS_BITVAR(retype)) {
8302 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8303 "The programmer is obviously confused");
8304 //genPackBits (retype,right,rname,POINTER);
8308 /* we have can just get the values */
8309 int size = AOP_SIZE(right);
8312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8314 l = aopGet(AOP(right),offset,FALSE,TRUE);
8317 //pic14_emitcode("mov","@%s,a",rname);
8318 pic14_emitcode("movf","indf,w ;1");
8321 if (AOP_TYPE(right) == AOP_LIT) {
8322 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8324 pic14_emitcode("movlw","%s",l);
8325 pic14_emitcode("movwf","indf ;2");
8327 pic14_emitcode("clrf","indf");
8329 pic14_emitcode("movf","%s,w",l);
8330 pic14_emitcode("movwf","indf ;2");
8332 //pic14_emitcode("mov","@%s,%s",rname,l);
8335 pic14_emitcode("incf","fsr,f ;3");
8336 //pic14_emitcode("inc","%s",rname);
8341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8342 /* now some housekeeping stuff */
8344 /* we had to allocate for this iCode */
8345 freeAsmop(NULL,aop,ic,TRUE);
8347 /* we did not allocate which means left
8348 already in a pointer register, then
8349 if size > 0 && this could be used again
8350 we have to point it back to where it
8352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8353 if (AOP_SIZE(right) > 1 &&
8354 !OP_SYMBOL(result)->remat &&
8355 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8357 int size = AOP_SIZE(right) - 1;
8359 pic14_emitcode("decf","fsr,f");
8360 //pic14_emitcode("dec","%s",rname);
8364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8366 freeAsmop(right,NULL,ic,TRUE);
8371 /*-----------------------------------------------------------------*/
8372 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8373 /*-----------------------------------------------------------------*/
8374 static void genPagedPointerSet (operand *right,
8383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8385 retype= getSpec(operandType(right));
8387 aopOp(result,ic,FALSE);
8389 /* if the value is already in a pointer register
8390 then don't need anything more */
8391 if (!AOP_INPREG(AOP(result))) {
8392 /* otherwise get a free pointer register */
8394 preg = getFreePtr(ic,&aop,FALSE);
8395 pic14_emitcode("mov","%s,%s",
8397 aopGet(AOP(result),0,FALSE,TRUE));
8398 rname = preg->name ;
8400 rname = aopGet(AOP(result),0,FALSE,FALSE);
8402 freeAsmop(result,NULL,ic,TRUE);
8403 aopOp (right,ic,FALSE);
8405 /* if bitfield then unpack the bits */
8406 if (IS_BITVAR(retype))
8407 genPackBits (retype,right,rname,PPOINTER);
8409 /* we have can just get the values */
8410 int size = AOP_SIZE(right);
8414 l = aopGet(AOP(right),offset,FALSE,TRUE);
8417 pic14_emitcode("movx","@%s,a",rname);
8420 pic14_emitcode("inc","%s",rname);
8426 /* now some housekeeping stuff */
8428 /* we had to allocate for this iCode */
8429 freeAsmop(NULL,aop,ic,TRUE);
8431 /* we did not allocate which means left
8432 already in a pointer register, then
8433 if size > 0 && this could be used again
8434 we have to point it back to where it
8436 if (AOP_SIZE(right) > 1 &&
8437 !OP_SYMBOL(result)->remat &&
8438 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8440 int size = AOP_SIZE(right) - 1;
8442 pic14_emitcode("dec","%s",rname);
8447 freeAsmop(right,NULL,ic,TRUE);
8452 /*-----------------------------------------------------------------*/
8453 /* genFarPointerSet - set value from far space */
8454 /*-----------------------------------------------------------------*/
8455 static void genFarPointerSet (operand *right,
8456 operand *result, iCode *ic)
8459 sym_link *retype = getSpec(operandType(right));
8461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8462 aopOp(result,ic,FALSE);
8464 /* if the operand is already in dptr
8465 then we do nothing else we move the value to dptr */
8466 if (AOP_TYPE(result) != AOP_STR) {
8467 /* if this is remateriazable */
8468 if (AOP_TYPE(result) == AOP_IMMD)
8469 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8470 else { /* we need to get it byte by byte */
8471 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8472 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8473 if (options.model == MODEL_FLAT24)
8475 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8479 /* so dptr know contains the address */
8480 freeAsmop(result,NULL,ic,TRUE);
8481 aopOp(right,ic,FALSE);
8483 /* if bit then unpack */
8484 if (IS_BITVAR(retype))
8485 genPackBits(retype,right,"dptr",FPOINTER);
8487 size = AOP_SIZE(right);
8491 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8493 pic14_emitcode("movx","@dptr,a");
8495 pic14_emitcode("inc","dptr");
8499 freeAsmop(right,NULL,ic,TRUE);
8502 /*-----------------------------------------------------------------*/
8503 /* genGenPointerSet - set value from generic pointer space */
8504 /*-----------------------------------------------------------------*/
8505 static void genGenPointerSet (operand *right,
8506 operand *result, iCode *ic)
8509 sym_link *retype = getSpec(operandType(right));
8511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8513 aopOp(result,ic,FALSE);
8514 aopOp(right,ic,FALSE);
8515 size = AOP_SIZE(right);
8517 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8519 /* if the operand is already in dptr
8520 then we do nothing else we move the value to dptr */
8521 if (AOP_TYPE(result) != AOP_STR) {
8522 /* if this is remateriazable */
8523 if (AOP_TYPE(result) == AOP_IMMD) {
8524 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8525 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8527 else { /* we need to get it byte by byte */
8528 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8529 size = AOP_SIZE(right);
8532 /* hack hack! see if this the FSR. If so don't load W */
8533 if(AOP_TYPE(right) != AOP_ACC) {
8535 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8536 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8539 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8541 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8542 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8546 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8547 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8550 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8557 if(aopIdx(AOP(result),0) != 4) {
8559 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8563 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8568 /* so dptr know contains the address */
8571 /* if bit then unpack */
8572 if (IS_BITVAR(retype))
8573 genPackBits(retype,right,"dptr",GPOINTER);
8575 size = AOP_SIZE(right);
8579 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8581 pic14_emitcode("incf","fsr,f");
8582 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8583 pic14_emitcode("movwf","indf");
8585 //DEBUGpic14_emitcode(";lcall","__gptrput");
8587 // pic14_emitcode("inc","dptr");
8592 freeAsmop(right,NULL,ic,TRUE);
8593 freeAsmop(result,NULL,ic,TRUE);
8596 /*-----------------------------------------------------------------*/
8597 /* genPointerSet - stores the value into a pointer location */
8598 /*-----------------------------------------------------------------*/
8599 static void genPointerSet (iCode *ic)
8601 operand *right, *result ;
8602 sym_link *type, *etype;
8605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8607 right = IC_RIGHT(ic);
8608 result = IC_RESULT(ic) ;
8610 /* depending on the type of pointer we need to
8611 move it to the correct pointer register */
8612 type = operandType(result);
8613 etype = getSpec(type);
8614 /* if left is of type of pointer then it is simple */
8615 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8616 p_type = DCL_TYPE(type);
8619 /* we have to go by the storage class */
8620 p_type = PTR_TYPE(SPEC_OCLS(etype));
8622 /* if (SPEC_OCLS(etype)->codesp ) { */
8623 /* p_type = CPOINTER ; */
8626 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8627 /* p_type = FPOINTER ; */
8629 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8630 /* p_type = PPOINTER ; */
8632 /* if (SPEC_OCLS(etype) == idata ) */
8633 /* p_type = IPOINTER ; */
8635 /* p_type = POINTER ; */
8638 /* now that we have the pointer type we assign
8639 the pointer values */
8644 genNearPointerSet (right,result,ic);
8648 genPagedPointerSet (right,result,ic);
8652 genFarPointerSet (right,result,ic);
8656 genGenPointerSet (right,result,ic);
8660 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8661 "genPointerSet: illegal pointer type");
8665 /*-----------------------------------------------------------------*/
8666 /* genIfx - generate code for Ifx statement */
8667 /*-----------------------------------------------------------------*/
8668 static void genIfx (iCode *ic, iCode *popIc)
8670 operand *cond = IC_COND(ic);
8673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8675 aopOp(cond,ic,FALSE);
8677 /* get the value into acc */
8678 if (AOP_TYPE(cond) != AOP_CRY)
8679 pic14_toBoolean(cond);
8682 /* the result is now in the accumulator */
8683 freeAsmop(cond,NULL,ic,TRUE);
8685 /* if there was something to be popped then do it */
8689 /* if the condition is a bit variable */
8690 if (isbit && IS_ITEMP(cond) &&
8692 genIfxJump(ic,SPIL_LOC(cond)->rname);
8693 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8696 if (isbit && !IS_ITEMP(cond))
8697 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8705 /*-----------------------------------------------------------------*/
8706 /* genAddrOf - generates code for address of */
8707 /*-----------------------------------------------------------------*/
8708 static void genAddrOf (iCode *ic)
8710 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8711 operand *right, *result, *left;
8712 //int size, offset ;
8714 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8717 //aopOp(IC_RESULT(ic),ic,FALSE);
8719 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8720 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8721 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8723 DEBUGpic14_AopType(__LINE__,left,right,result);
8725 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8726 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8729 /* object not on stack then we need the name */
8730 size = AOP_SIZE(IC_RESULT(ic));
8734 char s[SDCC_NAME_MAX];
8736 sprintf(s,"#(%s >> %d)",
8740 sprintf(s,"#%s",sym->rname);
8741 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8746 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8747 freeAsmop(left,NULL,ic,FALSE);
8748 freeAsmop(result,NULL,ic,TRUE);
8753 /*-----------------------------------------------------------------*/
8754 /* genFarFarAssign - assignment when both are in far space */
8755 /*-----------------------------------------------------------------*/
8756 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8758 int size = AOP_SIZE(right);
8761 /* first push the right side on to the stack */
8763 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8765 pic14_emitcode ("push","acc");
8768 freeAsmop(right,NULL,ic,FALSE);
8769 /* now assign DPTR to result */
8770 aopOp(result,ic,FALSE);
8771 size = AOP_SIZE(result);
8773 pic14_emitcode ("pop","acc");
8774 aopPut(AOP(result),"a",--offset);
8776 freeAsmop(result,NULL,ic,FALSE);
8781 /*-----------------------------------------------------------------*/
8782 /* genAssign - generate code for assignment */
8783 /*-----------------------------------------------------------------*/
8784 static void genAssign (iCode *ic)
8786 operand *result, *right;
8787 int size, offset,know_W;
8788 unsigned long lit = 0L;
8790 result = IC_RESULT(ic);
8791 right = IC_RIGHT(ic) ;
8793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8795 /* if they are the same */
8796 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8799 aopOp(right,ic,FALSE);
8800 aopOp(result,ic,TRUE);
8802 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8804 /* if they are the same registers */
8805 if (pic14_sameRegs(AOP(right),AOP(result)))
8808 /* if the result is a bit */
8809 if (AOP_TYPE(result) == AOP_CRY) {
8811 /* if the right size is a literal then
8812 we know what the value is */
8813 if (AOP_TYPE(right) == AOP_LIT) {
8815 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8816 popGet(AOP(result),0));
8818 if (((int) operandLitValue(right)))
8819 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8820 AOP(result)->aopu.aop_dir,
8821 AOP(result)->aopu.aop_dir);
8823 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8824 AOP(result)->aopu.aop_dir,
8825 AOP(result)->aopu.aop_dir);
8829 /* the right is also a bit variable */
8830 if (AOP_TYPE(right) == AOP_CRY) {
8831 emitpcode(POC_BCF, popGet(AOP(result),0));
8832 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8833 emitpcode(POC_BSF, popGet(AOP(result),0));
8835 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8836 AOP(result)->aopu.aop_dir,
8837 AOP(result)->aopu.aop_dir);
8838 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8839 AOP(right)->aopu.aop_dir,
8840 AOP(right)->aopu.aop_dir);
8841 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8842 AOP(result)->aopu.aop_dir,
8843 AOP(result)->aopu.aop_dir);
8848 emitpcode(POC_BCF, popGet(AOP(result),0));
8849 pic14_toBoolean(right);
8851 emitpcode(POC_BSF, popGet(AOP(result),0));
8852 //aopPut(AOP(result),"a",0);
8856 /* bit variables done */
8858 size = AOP_SIZE(result);
8860 if(AOP_TYPE(right) == AOP_LIT)
8861 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8863 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8865 if(aopIdx(AOP(result),0) == 4) {
8866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8867 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8868 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8871 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8877 if(AOP_TYPE(right) == AOP_LIT) {
8879 if(know_W != (lit&0xff))
8880 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8882 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8884 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8888 } else if (AOP_TYPE(right) == AOP_CRY) {
8889 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8891 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8892 emitpcode(POC_INCF, popGet(AOP(result),0));
8895 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8896 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8897 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8905 freeAsmop (right,NULL,ic,FALSE);
8906 freeAsmop (result,NULL,ic,TRUE);
8909 /*-----------------------------------------------------------------*/
8910 /* genJumpTab - genrates code for jump table */
8911 /*-----------------------------------------------------------------*/
8912 static void genJumpTab (iCode *ic)
8917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8919 aopOp(IC_JTCOND(ic),ic,FALSE);
8920 /* get the condition into accumulator */
8921 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8923 /* multiply by three */
8924 pic14_emitcode("add","a,acc");
8925 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8927 jtab = newiTempLabel(NULL);
8928 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8929 pic14_emitcode("jmp","@a+dptr");
8930 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8932 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8933 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8935 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8936 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8937 emitpLabel(jtab->key);
8939 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8941 /* now generate the jump labels */
8942 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8943 jtab = setNextItem(IC_JTLABELS(ic))) {
8944 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8945 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8951 /*-----------------------------------------------------------------*/
8952 /* genMixedOperation - gen code for operators between mixed types */
8953 /*-----------------------------------------------------------------*/
8955 TSD - Written for the PIC port - but this unfortunately is buggy.
8956 This routine is good in that it is able to efficiently promote
8957 types to different (larger) sizes. Unfortunately, the temporary
8958 variables that are optimized out by this routine are sometimes
8959 used in other places. So until I know how to really parse the
8960 iCode tree, I'm going to not be using this routine :(.
8962 static int genMixedOperation (iCode *ic)
8965 operand *result = IC_RESULT(ic);
8966 sym_link *ctype = operandType(IC_LEFT(ic));
8967 operand *right = IC_RIGHT(ic);
8973 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8975 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8981 nextright = IC_RIGHT(nextic);
8982 nextleft = IC_LEFT(nextic);
8983 nextresult = IC_RESULT(nextic);
8985 aopOp(right,ic,FALSE);
8986 aopOp(result,ic,FALSE);
8987 aopOp(nextright, nextic, FALSE);
8988 aopOp(nextleft, nextic, FALSE);
8989 aopOp(nextresult, nextic, FALSE);
8991 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8997 pic14_emitcode(";remove right +","");
8999 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9005 pic14_emitcode(";remove left +","");
9009 big = AOP_SIZE(nextleft);
9010 small = AOP_SIZE(nextright);
9012 switch(nextic->op) {
9015 pic14_emitcode(";optimize a +","");
9016 /* if unsigned or not an integral type */
9017 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9018 pic14_emitcode(";add a bit to something","");
9021 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9023 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9024 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9025 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9027 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9035 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9036 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9037 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9040 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9042 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9043 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9044 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9045 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9046 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9049 pic14_emitcode("rlf","known_zero,w");
9056 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9057 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9058 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9060 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9070 freeAsmop(right,NULL,ic,TRUE);
9071 freeAsmop(result,NULL,ic,TRUE);
9072 freeAsmop(nextright,NULL,ic,TRUE);
9073 freeAsmop(nextleft,NULL,ic,TRUE);
9075 nextic->generated = 1;
9082 /*-----------------------------------------------------------------*/
9083 /* genCast - gen code for casting */
9084 /*-----------------------------------------------------------------*/
9085 static void genCast (iCode *ic)
9087 operand *result = IC_RESULT(ic);
9088 sym_link *ctype = operandType(IC_LEFT(ic));
9089 sym_link *rtype = operandType(IC_RIGHT(ic));
9090 operand *right = IC_RIGHT(ic);
9093 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9094 /* if they are equivalent then do nothing */
9095 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9098 aopOp(right,ic,FALSE) ;
9099 aopOp(result,ic,FALSE);
9101 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9103 /* if the result is a bit */
9104 if (AOP_TYPE(result) == AOP_CRY) {
9105 /* if the right size is a literal then
9106 we know what the value is */
9107 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9108 if (AOP_TYPE(right) == AOP_LIT) {
9110 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9111 popGet(AOP(result),0));
9113 if (((int) operandLitValue(right)))
9114 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9115 AOP(result)->aopu.aop_dir,
9116 AOP(result)->aopu.aop_dir);
9118 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9119 AOP(result)->aopu.aop_dir,
9120 AOP(result)->aopu.aop_dir);
9125 /* the right is also a bit variable */
9126 if (AOP_TYPE(right) == AOP_CRY) {
9129 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9131 pic14_emitcode("clrc","");
9132 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9133 AOP(right)->aopu.aop_dir,
9134 AOP(right)->aopu.aop_dir);
9135 aopPut(AOP(result),"c",0);
9140 if (AOP_TYPE(right) == AOP_REG) {
9141 emitpcode(POC_BCF, popGet(AOP(result),0));
9142 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9143 emitpcode(POC_BSF, popGet(AOP(result),0));
9145 pic14_toBoolean(right);
9146 aopPut(AOP(result),"a",0);
9150 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9152 size = AOP_SIZE(result);
9154 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9156 emitpcode(POC_CLRF, popGet(AOP(result),0));
9157 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9158 emitpcode(POC_INCF, popGet(AOP(result),0));
9161 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9166 /* if they are the same size : or less */
9167 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9169 /* if they are in the same place */
9170 if (pic14_sameRegs(AOP(right),AOP(result)))
9173 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9174 if (IS_PTR_CONST(rtype))
9175 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9176 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9177 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9179 /* if they in different places then copy */
9180 size = AOP_SIZE(result);
9183 if(AOP_TYPE(right) == AOP_IMMD)
9184 emitpcode(POC_MOVLW, popGetImmd(AOP(right)->aopu.aop_dir,offset));
9186 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9187 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9189 //aopPut(AOP(result),
9190 // aopGet(AOP(right),offset,FALSE,FALSE),
9199 /* if the result is of type pointer */
9200 if (IS_PTR(ctype)) {
9203 sym_link *type = operandType(right);
9204 sym_link *etype = getSpec(type);
9205 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9207 /* pointer to generic pointer */
9208 if (IS_GENPTR(ctype)) {
9212 p_type = DCL_TYPE(type);
9214 /* we have to go by the storage class */
9215 p_type = PTR_TYPE(SPEC_OCLS(etype));
9217 /* if (SPEC_OCLS(etype)->codesp ) */
9218 /* p_type = CPOINTER ; */
9220 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9221 /* p_type = FPOINTER ; */
9223 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9224 /* p_type = PPOINTER; */
9226 /* if (SPEC_OCLS(etype) == idata ) */
9227 /* p_type = IPOINTER ; */
9229 /* p_type = POINTER ; */
9232 /* the first two bytes are known */
9233 size = GPTRSIZE - 1;
9236 if(offset < AOP_SIZE(right))
9238 aopGet(AOP(right),offset,FALSE,FALSE),
9241 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9244 /* the last byte depending on type */
9248 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9251 pic14_emitcode(";BUG!? ","%d",__LINE__);
9255 pic14_emitcode(";BUG!? ","%d",__LINE__);
9259 pic14_emitcode(";BUG!? ","%d",__LINE__);
9264 /* this should never happen */
9265 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9266 "got unknown pointer type");
9269 //aopPut(AOP(result),l, GPTRSIZE - 1);
9273 /* just copy the pointers */
9274 size = AOP_SIZE(result);
9278 aopGet(AOP(right),offset,FALSE,FALSE),
9287 /* so we now know that the size of destination is greater
9288 than the size of the source.
9289 Now, if the next iCode is an operator then we might be
9290 able to optimize the operation without performing a cast.
9292 if(genMixedOperation(ic))
9295 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9297 /* we move to result for the size of source */
9298 size = AOP_SIZE(right);
9301 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9302 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9306 /* now depending on the sign of the destination */
9307 size = AOP_SIZE(result) - AOP_SIZE(right);
9308 /* if unsigned or not an integral type */
9309 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9311 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9313 /* we need to extend the sign :{ */
9316 /* Save one instruction of casting char to int */
9317 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9318 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9319 emitpcode(POC_DECF, popGet(AOP(result),offset));
9321 emitpcodeNULLop(POC_CLRW);
9324 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9326 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9328 emitpcode(POC_MOVLW, popGetLit(0xff));
9331 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9336 freeAsmop(right,NULL,ic,TRUE);
9337 freeAsmop(result,NULL,ic,TRUE);
9341 /*-----------------------------------------------------------------*/
9342 /* genDjnz - generate decrement & jump if not zero instrucion */
9343 /*-----------------------------------------------------------------*/
9344 static int genDjnz (iCode *ic, iCode *ifx)
9347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9352 /* if the if condition has a false label
9353 then we cannot save */
9357 /* if the minus is not of the form
9359 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9360 !IS_OP_LITERAL(IC_RIGHT(ic)))
9363 if (operandLitValue(IC_RIGHT(ic)) != 1)
9366 /* if the size of this greater than one then no
9368 if (getSize(operandType(IC_RESULT(ic))) > 1)
9371 /* otherwise we can save BIG */
9372 lbl = newiTempLabel(NULL);
9373 lbl1= newiTempLabel(NULL);
9375 aopOp(IC_RESULT(ic),ic,FALSE);
9377 if (IS_AOP_PREG(IC_RESULT(ic))) {
9378 pic14_emitcode("dec","%s",
9379 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9380 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9381 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9385 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9386 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9388 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9389 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9392 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9393 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9394 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9395 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9398 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9403 /*-----------------------------------------------------------------*/
9404 /* genReceive - generate code for a receive iCode */
9405 /*-----------------------------------------------------------------*/
9406 static void genReceive (iCode *ic)
9408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9410 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9411 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9412 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9414 int size = getSize(operandType(IC_RESULT(ic)));
9415 int offset = fReturnSizePic - size;
9417 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9418 fReturn[fReturnSizePic - offset - 1] : "acc"));
9421 aopOp(IC_RESULT(ic),ic,FALSE);
9422 size = AOP_SIZE(IC_RESULT(ic));
9425 pic14_emitcode ("pop","acc");
9426 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9431 aopOp(IC_RESULT(ic),ic,FALSE);
9433 assignResultValue(IC_RESULT(ic));
9436 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9439 /*-----------------------------------------------------------------*/
9440 /* genpic14Code - generate code for pic14 based controllers */
9441 /*-----------------------------------------------------------------*/
9443 * At this point, ralloc.c has gone through the iCode and attempted
9444 * to optimize in a way suitable for a PIC. Now we've got to generate
9445 * PIC instructions that correspond to the iCode.
9447 * Once the instructions are generated, we'll pass through both the
9448 * peep hole optimizer and the pCode optimizer.
9449 *-----------------------------------------------------------------*/
9451 void genpic14Code (iCode *lic)
9456 lineHead = lineCurr = NULL;
9458 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9461 /* if debug information required */
9462 if (options.debug && currFunc) {
9464 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9466 if (IS_STATIC(currFunc->etype)) {
9467 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9468 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9470 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9471 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9478 for (ic = lic ; ic ; ic = ic->next ) {
9480 DEBUGpic14_emitcode(";ic","");
9481 if ( cln != ic->lineno ) {
9482 if ( options.debug ) {
9484 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9485 FileBaseName(ic->filename),ic->lineno,
9486 ic->level,ic->block);
9489 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9490 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9491 printCLine(ic->filename, ic->lineno));
9495 /* if the result is marked as
9496 spilt and rematerializable or code for
9497 this has already been generated then
9499 if (resultRemat(ic) || ic->generated )
9502 /* depending on the operation */
9521 /* IPOP happens only when trying to restore a
9522 spilt live range, if there is an ifx statement
9523 following this pop then the if statement might
9524 be using some of the registers being popped which
9525 would destory the contents of the register so
9526 we need to check for this condition and handle it */
9528 ic->next->op == IFX &&
9529 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9530 genIfx (ic->next,ic);
9548 genEndFunction (ic);
9568 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9585 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9589 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9596 /* note these two are xlated by algebraic equivalence
9597 during parsing SDCC.y */
9598 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9599 "got '>=' or '<=' shouldn't have come here");
9603 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9615 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9619 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9623 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9650 case GET_VALUE_AT_ADDRESS:
9655 if (POINTER_SET(ic))
9682 addSet(&_G.sendSet,ic);
9691 /* now we are ready to call the
9692 peep hole optimizer */
9693 if (!options.nopeep) {
9694 peepHole (&lineHead);
9696 /* now do the actual printing */
9697 printLine (lineHead,codeOutFile);
9700 DFPRINTF((stderr,"printing pBlock\n\n"));
9701 printpBlock(stdout,pb);