1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 static int labelOffset=0;
64 static int debug_verbose=1;
65 static int optimized_for_speed = 0;
67 /* max_key keeps track of the largest label number used in
68 a function. This is then used to adjust the label offset
69 for the next function.
72 static int GpsuedoStkPtr=0;
74 unsigned int pic14aopLiteral (value *val, int offset);
75 const char *AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic14[] = {"FSR","dph","b","a" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic14;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic14_ptrRegReq ;
119 extern int pic14_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
186 sprintf(lb,"%s\t",inst);
188 sprintf(lb,"%s",inst);
189 vsprintf(lb+(strlen(lb)),fmt,ap);
193 while (isspace(*lbp)) lbp++;
196 lineCurr = (lineCurr ?
197 connectLine(lineCurr,newLineNode(lb)) :
198 (lineHead = newLineNode(lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
202 addpCode2pBlock(pb,newpCodeCharP(lb));
208 static void emitpLabel(int key)
210 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
213 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
229 /*-----------------------------------------------------------------*/
230 /* pic14_emitcode - writes the code into a file : for now it is simple */
231 /*-----------------------------------------------------------------*/
232 void pic14_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
242 sprintf(lb,"%s\t",inst);
244 sprintf(lb,"%s",inst);
245 vsprintf(lb+(strlen(lb)),fmt,ap);
249 while (isspace(*lbp)) lbp++;
252 lineCurr = (lineCurr ?
253 connectLine(lineCurr,newLineNode(lb)) :
254 (lineHead = newLineNode(lb)));
255 lineCurr->isInline = _G.inLine;
256 lineCurr->isDebug = _G.debugLine;
259 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
267 /*-----------------------------------------------------------------*/
268 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
270 bool r0iu = FALSE , r1iu = FALSE;
271 bool r0ou = FALSE , r1ou = FALSE;
273 /* the logic: if r0 & r1 used in the instruction
274 then we are in trouble otherwise */
276 /* first check if r0 & r1 are used by this
277 instruction, in which case we are in trouble */
278 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
279 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
284 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
285 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
287 /* if no usage of r0 then return it */
288 if (!r0iu && !r0ou) {
289 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
290 (*aopp)->type = AOP_R0;
292 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
295 /* if no usage of r1 then return it */
296 if (!r1iu && !r1ou) {
297 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
298 (*aopp)->type = AOP_R1;
300 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
303 /* now we know they both have usage */
304 /* if r0 not used in this instruction */
306 /* push it if not already pushed */
308 pic14_emitcode ("push","%s",
309 pic14_regWithIdx(R0_IDX)->dname);
313 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
314 (*aopp)->type = AOP_R0;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
319 /* if r1 not used then */
322 /* push it if not already pushed */
324 pic14_emitcode ("push","%s",
325 pic14_regWithIdx(R1_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
330 (*aopp)->type = AOP_R1;
331 return pic14_regWithIdx(R1_IDX);
335 /* I said end of world but not quite end of world yet */
336 /* if this is a result then we can push it on the stack*/
338 (*aopp)->type = AOP_STK;
342 /* other wise this is true end of the world */
343 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
344 "getFreePtr should never reach here");
348 /*-----------------------------------------------------------------*/
349 /* newAsmop - creates a new asmOp */
350 /*-----------------------------------------------------------------*/
351 asmop *newAsmop (short type)
355 aop = Safe_calloc(1,sizeof(asmop));
360 static void genSetDPTR(int n)
364 pic14_emitcode(";", "Select standard DPTR");
365 pic14_emitcode("mov", "dps, #0x00");
369 pic14_emitcode(";", "Select alternate DPTR");
370 pic14_emitcode("mov", "dps, #0x01");
374 /*-----------------------------------------------------------------*/
375 /* resolveIfx - converts an iCode ifx into a form more useful for */
376 /* generating code */
377 /*-----------------------------------------------------------------*/
378 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
385 resIfx->condition = 1; /* assume that the ifx is true */
386 resIfx->generated = 0; /* indicate that the ifx has not been used */
389 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
390 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
391 __FUNCTION__,__LINE__,resIfx->lbl->key);
394 resIfx->lbl = IC_TRUE(ifx);
396 resIfx->lbl = IC_FALSE(ifx);
397 resIfx->condition = 0;
400 DEBUGpic14_emitcode("; ***","ifx true is non-null");
402 DEBUGpic14_emitcode("; ***","ifx false is non-null");
405 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
408 /*-----------------------------------------------------------------*/
409 /* pointerCode - returns the code for a pointer type */
410 /*-----------------------------------------------------------------*/
411 static int pointerCode (sym_link *etype)
414 return PTR_TYPE(SPEC_OCLS(etype));
418 /*-----------------------------------------------------------------*/
419 /* aopForSym - for a true symbol */
420 /*-----------------------------------------------------------------*/
421 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
424 memmap *space= SPEC_OCLS(sym->etype);
426 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
427 /* if already has one */
431 /* assign depending on the storage class */
432 /* if it is on the stack or indirectly addressable */
433 /* space we need to assign either r0 or r1 to it */
434 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
435 sym->aop = aop = newAsmop(0);
436 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
437 aop->size = getSize(sym->type);
439 /* now assign the address of the variable to
440 the pointer register */
441 if (aop->type != AOP_STK) {
445 pic14_emitcode("push","acc");
447 pic14_emitcode("mov","a,_bp");
448 pic14_emitcode("add","a,#0x%02x",
450 ((char)(sym->stack - _G.nRegsSaved )) :
451 ((char)sym->stack)) & 0xff);
452 pic14_emitcode("mov","%s,a",
453 aop->aopu.aop_ptr->name);
456 pic14_emitcode("pop","acc");
458 pic14_emitcode("mov","%s,#%s",
459 aop->aopu.aop_ptr->name,
461 aop->paged = space->paged;
463 aop->aopu.aop_stk = sym->stack;
467 if (sym->onStack && options.stack10bit)
469 /* It's on the 10 bit stack, which is located in
473 //DEBUGpic14_emitcode(";","%d",__LINE__);
476 pic14_emitcode("push","acc");
478 pic14_emitcode("mov","a,_bp");
479 pic14_emitcode("add","a,#0x%02x",
481 ((char)(sym->stack - _G.nRegsSaved )) :
482 ((char)sym->stack)) & 0xff);
485 pic14_emitcode ("mov","dpx1,#0x40");
486 pic14_emitcode ("mov","dph1,#0x00");
487 pic14_emitcode ("mov","dpl1, a");
491 pic14_emitcode("pop","acc");
493 sym->aop = aop = newAsmop(AOP_DPTR2);
494 aop->size = getSize(sym->type);
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 /* if in bit space */
500 if (IN_BITSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_CRY);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
507 /* if it is in direct space */
508 if (IN_DIRSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_DIR);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
516 /* special case for a function */
517 if (IS_FUNC(sym->type)) {
518 sym->aop = aop = newAsmop(AOP_IMMD);
519 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
520 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
521 strcpy(aop->aopu.aop_immd,sym->rname);
522 aop->size = FPTRSIZE;
527 /* only remaining is far space */
528 /* in which case DPTR gets the address */
529 sym->aop = aop = newAsmop(AOP_DPTR);
530 pic14_emitcode ("mov","dptr,#%s", sym->rname);
531 aop->size = getSize(sym->type);
533 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
534 /* if it is in code space */
535 if (IN_CODESPACE(space))
541 /*-----------------------------------------------------------------*/
542 /* aopForRemat - rematerialzes an object */
543 /*-----------------------------------------------------------------*/
544 static asmop *aopForRemat (symbol *sym)
546 iCode *ic = sym->rematiCode;
547 asmop *aop = newAsmop(AOP_IMMD);
549 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
552 val += (int) operandLitValue(IC_RIGHT(ic));
553 else if (ic->op == '-')
554 val -= (int) operandLitValue(IC_RIGHT(ic));
558 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
562 sprintf(buffer,"(%s %c 0x%04x)",
563 OP_SYMBOL(IC_LEFT(ic))->rname,
564 val >= 0 ? '+' : '-',
567 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
569 //DEBUGpic14_emitcode(";","%s",buffer);
570 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
571 strcpy(aop->aopu.aop_immd,buffer);
575 int aopIdx (asmop *aop, int offset)
580 if(aop->type != AOP_REG)
583 return aop->aopu.aop_reg[offset]->rIdx;
586 /*-----------------------------------------------------------------*/
587 /* regsInCommon - two operands have some registers in common */
588 /*-----------------------------------------------------------------*/
589 static bool regsInCommon (operand *op1, operand *op2)
594 /* if they have registers in common */
595 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
598 sym1 = OP_SYMBOL(op1);
599 sym2 = OP_SYMBOL(op2);
601 if (sym1->nRegs == 0 || sym2->nRegs == 0)
604 for (i = 0 ; i < sym1->nRegs ; i++) {
609 for (j = 0 ; j < sym2->nRegs ;j++ ) {
613 if (sym2->regs[j] == sym1->regs[i])
621 /*-----------------------------------------------------------------*/
622 /* operandsEqu - equivalent */
623 /*-----------------------------------------------------------------*/
624 static bool operandsEqu ( operand *op1, operand *op2)
628 /* if they not symbols */
629 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
632 sym1 = OP_SYMBOL(op1);
633 sym2 = OP_SYMBOL(op2);
635 /* if both are itemps & one is spilt
636 and the other is not then false */
637 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
638 sym1->isspilt != sym2->isspilt )
641 /* if they are the same */
645 if (strcmp(sym1->rname,sym2->rname) == 0)
649 /* if left is a tmp & right is not */
653 (sym1->usl.spillLoc == sym2))
660 (sym2->usl.spillLoc == sym1))
666 /*-----------------------------------------------------------------*/
667 /* pic14_sameRegs - two asmops have the same registers */
668 /*-----------------------------------------------------------------*/
669 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
676 if (aop1->type != AOP_REG ||
677 aop2->type != AOP_REG )
680 if (aop1->size != aop2->size )
683 for (i = 0 ; i < aop1->size ; i++ )
684 if (aop1->aopu.aop_reg[i] !=
685 aop2->aopu.aop_reg[i] )
691 /*-----------------------------------------------------------------*/
692 /* aopOp - allocates an asmop for an operand : */
693 /*-----------------------------------------------------------------*/
694 void aopOp (operand *op, iCode *ic, bool result)
703 // DEBUGpic14_emitcode(";","%d",__LINE__);
704 /* if this a literal */
705 if (IS_OP_LITERAL(op)) {
706 op->aop = aop = newAsmop(AOP_LIT);
707 aop->aopu.aop_lit = op->operand.valOperand;
708 aop->size = getSize(operandType(op));
712 /* if already has a asmop then continue */
716 /* if the underlying symbol has a aop */
717 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
718 DEBUGpic14_emitcode(";","%d",__LINE__);
719 op->aop = OP_SYMBOL(op)->aop;
723 /* if this is a true symbol */
724 if (IS_TRUE_SYMOP(op)) {
725 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
726 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
730 /* this is a temporary : this has
736 e) can be a return use only */
741 /* if the type is a conditional */
742 if (sym->regType == REG_CND) {
743 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
748 /* if it is spilt then two situations
750 b) has a spill location */
751 if (sym->isspilt || sym->nRegs == 0) {
753 DEBUGpic14_emitcode(";","%d",__LINE__);
754 /* rematerialize it NOW */
756 sym->aop = op->aop = aop =
758 aop->size = getSize(sym->type);
764 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
765 aop->size = getSize(sym->type);
766 for ( i = 0 ; i < 2 ; i++ )
767 aop->aopu.aop_str[i] = accUse[i];
768 DEBUGpic14_emitcode(";","%d",__LINE__);
774 aop = op->aop = sym->aop = newAsmop(AOP_STR);
775 aop->size = getSize(sym->type);
776 for ( i = 0 ; i < fReturnSizePic ; i++ )
777 aop->aopu.aop_str[i] = fReturn[i];
778 DEBUGpic14_emitcode(";","%d",__LINE__);
782 /* else spill location */
783 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
784 /* force a new aop if sizes differ */
785 sym->usl.spillLoc->aop = NULL;
787 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
788 sym->aop = op->aop = aop =
789 aopForSym(ic,sym->usl.spillLoc,result);
790 aop->size = getSize(sym->type);
794 /* must be in a register */
795 sym->aop = op->aop = aop = newAsmop(AOP_REG);
796 aop->size = sym->nRegs;
797 for ( i = 0 ; i < sym->nRegs ;i++)
798 aop->aopu.aop_reg[i] = sym->regs[i];
801 /*-----------------------------------------------------------------*/
802 /* freeAsmop - free up the asmop given to an operand */
803 /*----------------------------------------------------------------*/
804 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
821 /* depending on the asmop type only three cases need work AOP_RO
822 , AOP_R1 && AOP_STK */
828 pic14_emitcode ("pop","ar0");
832 bitVectUnSetBit(ic->rUsed,R0_IDX);
838 pic14_emitcode ("pop","ar1");
842 bitVectUnSetBit(ic->rUsed,R1_IDX);
848 int stk = aop->aopu.aop_stk + aop->size;
849 bitVectUnSetBit(ic->rUsed,R0_IDX);
850 bitVectUnSetBit(ic->rUsed,R1_IDX);
852 getFreePtr(ic,&aop,FALSE);
854 if (options.stack10bit)
856 /* I'm not sure what to do here yet... */
859 "*** Warning: probably generating bad code for "
860 "10 bit stack mode.\n");
864 pic14_emitcode ("mov","a,_bp");
865 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
866 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
868 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
872 pic14_emitcode("pop","acc");
873 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
875 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
878 freeAsmop(op,NULL,ic,TRUE);
880 pic14_emitcode("pop","ar0");
885 pic14_emitcode("pop","ar1");
893 /* all other cases just dealloc */
897 OP_SYMBOL(op)->aop = NULL;
898 /* if the symbol has a spill */
900 SPIL_LOC(op)->aop = NULL;
905 /*-----------------------------------------------------------------*/
906 /* aopGet - for fetching value of the aop */
907 /*-----------------------------------------------------------------*/
908 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
913 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
914 /* offset is greater than
916 if (offset > (aop->size - 1) &&
917 aop->type != AOP_LIT)
920 /* depending on type */
925 DEBUGpic14_emitcode(";","%d",__LINE__);
926 /* if we need to increment it */
927 while (offset > aop->coff) {
928 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
932 while (offset < aop->coff) {
933 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
939 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
940 return (dname ? "acc" : "a");
942 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
943 rs = Safe_calloc(1,strlen(s)+1);
949 DEBUGpic14_emitcode(";","%d",__LINE__);
950 if (aop->type == AOP_DPTR2)
955 while (offset > aop->coff) {
956 pic14_emitcode ("inc","dptr");
960 while (offset < aop->coff) {
961 pic14_emitcode("lcall","__decdptr");
967 pic14_emitcode("clr","a");
968 pic14_emitcode("movc","a,@a+dptr");
971 pic14_emitcode("movx","a,@dptr");
974 if (aop->type == AOP_DPTR2)
979 return (dname ? "acc" : "a");
983 DEBUGpic14_emitcode(";","%d",__LINE__);
985 sprintf (s,"%s",aop->aopu.aop_immd);
988 sprintf(s,"(%s >> %d)",
994 rs = Safe_calloc(1,strlen(s)+1);
1000 sprintf(s,"(%s + %d)",
1004 sprintf(s,"%s",aop->aopu.aop_dir);
1005 rs = Safe_calloc(1,strlen(s)+1);
1011 return aop->aopu.aop_reg[offset]->dname;
1013 return aop->aopu.aop_reg[offset]->name;
1016 //pic14_emitcode(";","%d",__LINE__);
1017 return aop->aopu.aop_dir;
1020 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1021 return "AOP_accumulator_bug";
1024 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1025 rs = Safe_calloc(1,strlen(s)+1);
1030 DEBUGpic14_emitcode(";","%d",__LINE__);
1031 aop->coff = offset ;
1032 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1036 return aop->aopu.aop_str[offset];
1040 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1041 "aopget got unsupported aop->type");
1045 /*-----------------------------------------------------------------*/
1046 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1047 /*-----------------------------------------------------------------*/
1048 pCodeOp *popGetLabel(unsigned int key)
1051 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1056 return newpCodeOpLabel(key+100+labelOffset);
1059 /*-----------------------------------------------------------------*/
1060 /* popCopyReg - copy a pcode operator */
1061 /*-----------------------------------------------------------------*/
1062 pCodeOp *popCopyReg(pCodeOpReg *pc)
1066 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1067 pcor->pcop.type = pc->pcop.type;
1068 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1069 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1071 pcor->rIdx = pc->rIdx;
1073 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1078 /*-----------------------------------------------------------------*/
1079 /* popCopy - copy a pcode operator */
1080 /*-----------------------------------------------------------------*/
1081 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1085 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1086 pcop->type = PO_BIT;
1087 if(!(pcop->name = Safe_strdup(pc->name)))
1088 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1089 ((pCodeOpBit *)pcop)->bit = bitval;
1091 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1096 /*-----------------------------------------------------------------*/
1097 /* popGet - asm operator to pcode operator conversion */
1098 /*-----------------------------------------------------------------*/
1099 pCodeOp *popGetLit(unsigned int lit)
1102 return newpCodeOpLit(lit);
1106 /*-----------------------------------------------------------------*/
1107 /* popGet - asm operator to pcode operator conversion */
1108 /*-----------------------------------------------------------------*/
1109 pCodeOp *popGetWithString(char *str)
1115 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1119 pcop = newpCodeOp(str,PO_STR);
1124 pCodeOp *popRegFromString(char *str)
1127 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1128 pcop->type = PO_GPR_REGISTER;
1130 PCOR(pcop)->rIdx = -1;
1131 PCOR(pcop)->r = NULL;
1133 DEBUGpic14_emitcode(";","%d",__LINE__);
1134 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1139 pCodeOp *popRegFromIdx(int rIdx)
1143 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1144 __FUNCTION__,__LINE__,rIdx);
1146 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1148 PCOR(pcop)->rIdx = rIdx;
1149 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1150 PCOR(pcop)->r->isFree = 0;
1151 PCOR(pcop)->r->wasUsed = 1;
1153 pcop->type = PCOR(pcop)->r->pc_type;
1158 /*-----------------------------------------------------------------*/
1159 /* popGet - asm operator to pcode operator conversion */
1160 /*-----------------------------------------------------------------*/
1161 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1168 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1169 /* offset is greater than
1172 if (offset > (aop->size - 1) &&
1173 aop->type != AOP_LIT)
1174 return NULL; //zero;
1176 /* depending on type */
1177 switch (aop->type) {
1184 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1185 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1186 //pcop->type = PO_SFR_REGISTER;
1188 //PCOR(pcop)->rIdx = -1;
1189 //PCOR(pcop)->r = NULL;
1190 // Really nasty hack to check for temporary registers
1192 //pcop->name = Safe_strdup("BAD_REGISTER");
1197 DEBUGpic14_emitcode(";","%d",__LINE__);
1198 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1199 pcop->type = PO_IMMEDIATE;
1201 // sprintf (s,"%s",aop->aopu.aop_immd);
1204 sprintf(s,"(%s >> %d)",
1209 aop->aopu.aop_immd);
1210 pcop->name = Safe_calloc(1,strlen(s)+1);
1211 strcpy(pcop->name,s);
1215 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1216 pcop->type = PO_DIR;
1218 sprintf(s,"(%s + %d)",
1222 sprintf(s,"%s",aop->aopu.aop_dir);
1223 pcop->name = Safe_calloc(1,strlen(s)+1);
1224 strcpy(pcop->name,s);
1229 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1231 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1232 PCOR(pcop)->rIdx = rIdx;
1233 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1234 pcop->type = PCOR(pcop)->r->pc_type;
1235 rs = aop->aopu.aop_reg[offset]->name;
1236 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1241 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1245 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1248 DEBUGpic14_emitcode(";","%d",__LINE__);
1250 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1251 pcop->type = PO_STR;
1253 //aop->coff = offset ;
1254 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1255 // sprintf(s,"%s","acc");
1257 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1258 pcop->name = Safe_calloc(1,strlen(s)+1);
1259 strcpy(pcop->name,s);
1264 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1265 "popGet got unsupported aop->type");
1268 /*-----------------------------------------------------------------*/
1269 /* aopPut - puts a string for a aop */
1270 /*-----------------------------------------------------------------*/
1271 void aopPut (asmop *aop, char *s, int offset)
1276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1278 if (aop->size && offset > ( aop->size - 1)) {
1279 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280 "aopPut got offset > aop->size");
1284 /* will assign value to value */
1285 /* depending on where it is ofcourse */
1286 switch (aop->type) {
1289 sprintf(d,"(%s + %d)",
1290 aop->aopu.aop_dir,offset);
1292 sprintf(d,"%s",aop->aopu.aop_dir);
1295 DEBUGpic14_emitcode(";","%d",__LINE__);
1297 pic14_emitcode("movf","%s,w",s);
1298 pic14_emitcode("movwf","%s",d);
1301 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1302 emitpcode(POC_MOVWF,popGet(aop,offset));
1309 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1310 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1313 strcmp(s,"r0") == 0 ||
1314 strcmp(s,"r1") == 0 ||
1315 strcmp(s,"r2") == 0 ||
1316 strcmp(s,"r3") == 0 ||
1317 strcmp(s,"r4") == 0 ||
1318 strcmp(s,"r5") == 0 ||
1319 strcmp(s,"r6") == 0 ||
1320 strcmp(s,"r7") == 0 )
1321 pic14_emitcode("mov","%s,%s ; %d",
1322 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1327 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1329 pic14_emitcode("movwf","%s",
1330 aop->aopu.aop_reg[offset]->name);
1333 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1334 pcop->type = PO_GPR_REGISTER;
1336 PCOR(pcop)->rIdx = -1;
1337 PCOR(pcop)->r = NULL;
1339 DEBUGpic14_emitcode(";","%d",__LINE__);
1340 pcop->name = Safe_strdup(s);
1341 emitpcode(POC_MOVFW,pcop);
1343 emitpcode(POC_MOVWF,popGet(aop,offset));
1351 if (aop->type == AOP_DPTR2)
1357 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1358 "aopPut writting to code space");
1362 while (offset > aop->coff) {
1364 pic14_emitcode ("inc","dptr");
1367 while (offset < aop->coff) {
1369 pic14_emitcode("lcall","__decdptr");
1374 /* if not in accumulater */
1377 pic14_emitcode ("movx","@dptr,a");
1379 if (aop->type == AOP_DPTR2)
1387 while (offset > aop->coff) {
1389 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1391 while (offset < aop->coff) {
1393 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1399 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1404 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1406 if (strcmp(s,"r0") == 0 ||
1407 strcmp(s,"r1") == 0 ||
1408 strcmp(s,"r2") == 0 ||
1409 strcmp(s,"r3") == 0 ||
1410 strcmp(s,"r4") == 0 ||
1411 strcmp(s,"r5") == 0 ||
1412 strcmp(s,"r6") == 0 ||
1413 strcmp(s,"r7") == 0 ) {
1415 sprintf(buffer,"a%s",s);
1416 pic14_emitcode("mov","@%s,%s",
1417 aop->aopu.aop_ptr->name,buffer);
1419 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1424 if (strcmp(s,"a") == 0)
1425 pic14_emitcode("push","acc");
1427 pic14_emitcode("push","%s",s);
1432 /* if bit variable */
1433 if (!aop->aopu.aop_dir) {
1434 pic14_emitcode("clr","a");
1435 pic14_emitcode("rlc","a");
1438 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1441 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1444 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1446 lbl = newiTempLabel(NULL);
1448 if (strcmp(s,"a")) {
1451 pic14_emitcode("clr","c");
1452 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1453 pic14_emitcode("cpl","c");
1454 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1455 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1462 if (strcmp(aop->aopu.aop_str[offset],s))
1463 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1468 if (!offset && (strcmp(s,"acc") == 0))
1471 if (strcmp(aop->aopu.aop_str[offset],s))
1472 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1476 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1477 "aopPut got unsupported aop->type");
1483 /*-----------------------------------------------------------------*/
1484 /* reAdjustPreg - points a register back to where it should */
1485 /*-----------------------------------------------------------------*/
1486 static void reAdjustPreg (asmop *aop)
1490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1492 if ((size = aop->size) <= 1)
1495 switch (aop->type) {
1499 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1503 if (aop->type == AOP_DPTR2)
1509 pic14_emitcode("lcall","__decdptr");
1512 if (aop->type == AOP_DPTR2)
1522 /*-----------------------------------------------------------------*/
1523 /* genNotFloat - generates not for float operations */
1524 /*-----------------------------------------------------------------*/
1525 static void genNotFloat (operand *op, operand *res)
1531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1532 /* we will put 127 in the first byte of
1534 aopPut(AOP(res),"#127",0);
1535 size = AOP_SIZE(op) - 1;
1538 l = aopGet(op->aop,offset++,FALSE,FALSE);
1542 pic14_emitcode("orl","a,%s",
1544 offset++,FALSE,FALSE));
1546 tlbl = newiTempLabel(NULL);
1548 tlbl = newiTempLabel(NULL);
1549 aopPut(res->aop,one,1);
1550 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1551 aopPut(res->aop,zero,1);
1552 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1554 size = res->aop->size - 2;
1556 /* put zeros in the rest */
1558 aopPut(res->aop,zero,offset++);
1562 /*-----------------------------------------------------------------*/
1563 /* opIsGptr: returns non-zero if the passed operand is */
1564 /* a generic pointer type. */
1565 /*-----------------------------------------------------------------*/
1566 static int opIsGptr(operand *op)
1568 sym_link *type = operandType(op);
1570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1571 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1579 /*-----------------------------------------------------------------*/
1580 /* pic14_getDataSize - get the operand data size */
1581 /*-----------------------------------------------------------------*/
1582 int pic14_getDataSize(operand *op)
1584 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1587 return AOP_SIZE(op);
1589 // tsd- in the pic port, the genptr size is 1, so this code here
1590 // fails. ( in the 8051 port, the size was 4).
1593 size = AOP_SIZE(op);
1594 if (size == GPTRSIZE)
1596 sym_link *type = operandType(op);
1597 if (IS_GENPTR(type))
1599 /* generic pointer; arithmetic operations
1600 * should ignore the high byte (pointer type).
1603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1610 /*-----------------------------------------------------------------*/
1611 /* pic14_outAcc - output Acc */
1612 /*-----------------------------------------------------------------*/
1613 void pic14_outAcc(operand *result)
1616 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1617 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1620 size = pic14_getDataSize(result);
1622 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1625 /* unsigned or positive */
1627 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1632 /*-----------------------------------------------------------------*/
1633 /* pic14_outBitC - output a bit C */
1634 /*-----------------------------------------------------------------*/
1635 void pic14_outBitC(operand *result)
1638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1639 /* if the result is bit */
1640 if (AOP_TYPE(result) == AOP_CRY)
1641 aopPut(AOP(result),"c",0);
1643 pic14_emitcode("clr","a ; %d", __LINE__);
1644 pic14_emitcode("rlc","a");
1645 pic14_outAcc(result);
1649 /*-----------------------------------------------------------------*/
1650 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1651 /*-----------------------------------------------------------------*/
1652 void pic14_toBoolean(operand *oper)
1654 int size = AOP_SIZE(oper) - 1;
1657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if ( AOP_TYPE(oper) != AOP_ACC) {
1660 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1663 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1668 /*-----------------------------------------------------------------*/
1669 /* genNot - generate code for ! operation */
1670 /*-----------------------------------------------------------------*/
1671 static void genNot (iCode *ic)
1674 sym_link *optype = operandType(IC_LEFT(ic));
1677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1678 /* assign asmOps to operand & result */
1679 aopOp (IC_LEFT(ic),ic,FALSE);
1680 aopOp (IC_RESULT(ic),ic,TRUE);
1682 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1683 /* if in bit space then a special case */
1684 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1685 pic14_emitcode("movlw","1<<%s");
1686 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1687 //pic14_emitcode("cpl","c");
1688 //pic14_outBitC(IC_RESULT(ic));
1692 /* if type float then do float */
1693 if (IS_FLOAT(optype)) {
1694 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1698 size = AOP_SIZE(IC_RESULT(ic));
1700 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1701 emitpcode(POC_ANDLW,popGetLit(1));
1702 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1705 pic14_toBoolean(IC_LEFT(ic));
1707 tlbl = newiTempLabel(NULL);
1708 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1710 pic14_outBitC(IC_RESULT(ic));
1713 /* release the aops */
1714 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1715 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1719 /*-----------------------------------------------------------------*/
1720 /* genCpl - generate code for complement */
1721 /*-----------------------------------------------------------------*/
1722 static void genCpl (iCode *ic)
1728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 /* assign asmOps to operand & result */
1730 aopOp (IC_LEFT(ic),ic,FALSE);
1731 aopOp (IC_RESULT(ic),ic,TRUE);
1733 /* if both are in bit space then
1735 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1736 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1738 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1739 pic14_emitcode("cpl","c");
1740 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1744 size = AOP_SIZE(IC_RESULT(ic));
1746 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1748 pic14_emitcode("cpl","a");
1749 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1754 /* release the aops */
1755 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1756 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1759 /*-----------------------------------------------------------------*/
1760 /* genUminusFloat - unary minus for floating points */
1761 /*-----------------------------------------------------------------*/
1762 static void genUminusFloat(operand *op,operand *result)
1764 int size ,offset =0 ;
1767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1768 /* for this we just need to flip the
1769 first it then copy the rest in place */
1770 size = AOP_SIZE(op) - 1;
1771 l = aopGet(AOP(op),3,FALSE,FALSE);
1775 pic14_emitcode("cpl","acc.7");
1776 aopPut(AOP(result),"a",3);
1780 aopGet(AOP(op),offset,FALSE,FALSE),
1786 /*-----------------------------------------------------------------*/
1787 /* genUminus - unary minus code generation */
1788 /*-----------------------------------------------------------------*/
1789 static void genUminus (iCode *ic)
1792 sym_link *optype, *rtype;
1795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 aopOp(IC_LEFT(ic),ic,FALSE);
1798 aopOp(IC_RESULT(ic),ic,TRUE);
1800 /* if both in bit space then special
1802 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1803 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1805 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1806 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1807 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1812 optype = operandType(IC_LEFT(ic));
1813 rtype = operandType(IC_RESULT(ic));
1815 /* if float then do float stuff */
1816 if (IS_FLOAT(optype)) {
1817 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1821 /* otherwise subtract from zero by taking the 2's complement */
1822 size = AOP_SIZE(IC_LEFT(ic));
1824 for(i=0; i<size; i++) {
1825 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1826 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1828 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1829 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1833 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1834 for(i=1; i<size; i++) {
1836 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1840 /* release the aops */
1841 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1842 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1845 /*-----------------------------------------------------------------*/
1846 /* saveRegisters - will look for a call and save the registers */
1847 /*-----------------------------------------------------------------*/
1848 static void saveRegisters(iCode *lic)
1855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1857 for (ic = lic ; ic ; ic = ic->next)
1858 if (ic->op == CALL || ic->op == PCALL)
1862 fprintf(stderr,"found parameter push with no function call\n");
1866 /* if the registers have been saved already then
1868 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1871 /* find the registers in use at this time
1872 and push them away to safety */
1873 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1877 if (options.useXstack) {
1878 if (bitVectBitValue(rsave,R0_IDX))
1879 pic14_emitcode("mov","b,r0");
1880 pic14_emitcode("mov","r0,%s",spname);
1881 for (i = 0 ; i < pic14_nRegs ; i++) {
1882 if (bitVectBitValue(rsave,i)) {
1884 pic14_emitcode("mov","a,b");
1886 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1887 pic14_emitcode("movx","@r0,a");
1888 pic14_emitcode("inc","r0");
1891 pic14_emitcode("mov","%s,r0",spname);
1892 if (bitVectBitValue(rsave,R0_IDX))
1893 pic14_emitcode("mov","r0,b");
1895 for (i = 0 ; i < pic14_nRegs ; i++) {
1896 if (bitVectBitValue(rsave,i))
1897 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1900 dtype = operandType(IC_LEFT(ic));
1901 if (currFunc && dtype &&
1902 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1903 IFFUNC_ISISR(currFunc->type) &&
1906 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1909 /*-----------------------------------------------------------------*/
1910 /* unsaveRegisters - pop the pushed registers */
1911 /*-----------------------------------------------------------------*/
1912 static void unsaveRegisters (iCode *ic)
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 /* find the registers in use at this time
1919 and push them away to safety */
1920 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1923 if (options.useXstack) {
1924 pic14_emitcode("mov","r0,%s",spname);
1925 for (i = pic14_nRegs ; i >= 0 ; i--) {
1926 if (bitVectBitValue(rsave,i)) {
1927 pic14_emitcode("dec","r0");
1928 pic14_emitcode("movx","a,@r0");
1930 pic14_emitcode("mov","b,a");
1932 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1936 pic14_emitcode("mov","%s,r0",spname);
1937 if (bitVectBitValue(rsave,R0_IDX))
1938 pic14_emitcode("mov","r0,b");
1940 for (i = pic14_nRegs ; i >= 0 ; i--) {
1941 if (bitVectBitValue(rsave,i))
1942 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1948 /*-----------------------------------------------------------------*/
1950 /*-----------------------------------------------------------------*/
1951 static void pushSide(operand * oper, int size)
1955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1957 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1958 if (AOP_TYPE(oper) != AOP_REG &&
1959 AOP_TYPE(oper) != AOP_DIR &&
1961 pic14_emitcode("mov","a,%s",l);
1962 pic14_emitcode("push","acc");
1964 pic14_emitcode("push","%s",l);
1969 /*-----------------------------------------------------------------*/
1970 /* assignResultValue - */
1971 /*-----------------------------------------------------------------*/
1972 static void assignResultValue(operand * oper)
1974 int size = AOP_SIZE(oper);
1976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1978 if(!GpsuedoStkPtr) {
1979 /* The last byte in the assignment is in W */
1981 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1986 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1988 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1993 /*-----------------------------------------------------------------*/
1994 /* genIpush - genrate code for pushing this gets a little complex */
1995 /*-----------------------------------------------------------------*/
1996 static void genIpush (iCode *ic)
1999 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2001 int size, offset = 0 ;
2005 /* if this is not a parm push : ie. it is spill push
2006 and spill push is always done on the local stack */
2007 if (!ic->parmPush) {
2009 /* and the item is spilt then do nothing */
2010 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2013 aopOp(IC_LEFT(ic),ic,FALSE);
2014 size = AOP_SIZE(IC_LEFT(ic));
2015 /* push it on the stack */
2017 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2022 pic14_emitcode("push","%s",l);
2027 /* this is a paramter push: in this case we call
2028 the routine to find the call and save those
2029 registers that need to be saved */
2032 /* then do the push */
2033 aopOp(IC_LEFT(ic),ic,FALSE);
2036 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2037 size = AOP_SIZE(IC_LEFT(ic));
2040 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2041 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2042 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2044 pic14_emitcode("mov","a,%s",l);
2045 pic14_emitcode("push","acc");
2047 pic14_emitcode("push","%s",l);
2050 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2054 /*-----------------------------------------------------------------*/
2055 /* genIpop - recover the registers: can happen only for spilling */
2056 /*-----------------------------------------------------------------*/
2057 static void genIpop (iCode *ic)
2059 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2064 /* if the temp was not pushed then */
2065 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2068 aopOp(IC_LEFT(ic),ic,FALSE);
2069 size = AOP_SIZE(IC_LEFT(ic));
2072 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2075 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2079 /*-----------------------------------------------------------------*/
2080 /* unsaverbank - restores the resgister bank from stack */
2081 /*-----------------------------------------------------------------*/
2082 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2084 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 if (options.useXstack) {
2094 r = getFreePtr(ic,&aop,FALSE);
2097 pic14_emitcode("mov","%s,_spx",r->name);
2098 pic14_emitcode("movx","a,@%s",r->name);
2099 pic14_emitcode("mov","psw,a");
2100 pic14_emitcode("dec","%s",r->name);
2103 pic14_emitcode ("pop","psw");
2106 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2107 if (options.useXstack) {
2108 pic14_emitcode("movx","a,@%s",r->name);
2109 //pic14_emitcode("mov","(%s+%d),a",
2110 // regspic14[i].base,8*bank+regspic14[i].offset);
2111 pic14_emitcode("dec","%s",r->name);
2114 pic14_emitcode("pop",""); //"(%s+%d)",
2115 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2118 if (options.useXstack) {
2120 pic14_emitcode("mov","_spx,%s",r->name);
2121 freeAsmop(NULL,aop,ic,TRUE);
2127 /*-----------------------------------------------------------------*/
2128 /* saverbank - saves an entire register bank on the stack */
2129 /*-----------------------------------------------------------------*/
2130 static void saverbank (int bank, iCode *ic, bool pushPsw)
2132 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2139 if (options.useXstack) {
2142 r = getFreePtr(ic,&aop,FALSE);
2143 pic14_emitcode("mov","%s,_spx",r->name);
2147 for (i = 0 ; i < pic14_nRegs ;i++) {
2148 if (options.useXstack) {
2149 pic14_emitcode("inc","%s",r->name);
2150 //pic14_emitcode("mov","a,(%s+%d)",
2151 // regspic14[i].base,8*bank+regspic14[i].offset);
2152 pic14_emitcode("movx","@%s,a",r->name);
2154 pic14_emitcode("push","");// "(%s+%d)",
2155 //regspic14[i].base,8*bank+regspic14[i].offset);
2159 if (options.useXstack) {
2160 pic14_emitcode("mov","a,psw");
2161 pic14_emitcode("movx","@%s,a",r->name);
2162 pic14_emitcode("inc","%s",r->name);
2163 pic14_emitcode("mov","_spx,%s",r->name);
2164 freeAsmop (NULL,aop,ic,TRUE);
2167 pic14_emitcode("push","psw");
2169 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2175 /*-----------------------------------------------------------------*/
2176 /* genCall - generates a call statement */
2177 /*-----------------------------------------------------------------*/
2178 static void genCall (iCode *ic)
2182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2184 /* if caller saves & we have not saved then */
2188 /* if we are calling a function that is not using
2189 the same register bank then we need to save the
2190 destination registers on the stack */
2191 dtype = operandType(IC_LEFT(ic));
2192 if (currFunc && dtype &&
2193 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2194 IFFUNC_ISISR(currFunc->type) &&
2197 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2199 /* if send set is not empty the assign */
2202 /* For the Pic port, there is no data stack.
2203 * So parameters passed to functions are stored
2204 * in registers. (The pCode optimizer will get
2205 * rid of most of these :).
2207 int psuedoStkPtr=-1;
2208 int firstTimeThruLoop = 1;
2210 _G.sendSet = reverseSet(_G.sendSet);
2212 /* First figure how many parameters are getting passed */
2213 for (sic = setFirstItem(_G.sendSet) ; sic ;
2214 sic = setNextItem(_G.sendSet)) {
2216 aopOp(IC_LEFT(sic),sic,FALSE);
2217 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2218 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2221 for (sic = setFirstItem(_G.sendSet) ; sic ;
2222 sic = setNextItem(_G.sendSet)) {
2223 int size, offset = 0;
2225 aopOp(IC_LEFT(sic),sic,FALSE);
2226 size = AOP_SIZE(IC_LEFT(sic));
2230 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2231 AopType(AOP_TYPE(IC_LEFT(sic))));
2233 if(!firstTimeThruLoop) {
2234 /* If this is not the first time we've been through the loop
2235 * then we need to save the parameter in a temporary
2236 * register. The last byte of the last parameter is
2238 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2241 firstTimeThruLoop=0;
2243 //if (strcmp(l,fReturn[offset])) {
2245 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2246 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2247 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2249 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2254 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2259 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2260 OP_SYMBOL(IC_LEFT(ic))->rname :
2261 OP_SYMBOL(IC_LEFT(ic))->name));
2264 /* if we need assign a result value */
2265 if ((IS_ITEMP(IC_RESULT(ic)) &&
2266 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2267 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2268 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2271 aopOp(IC_RESULT(ic),ic,FALSE);
2274 assignResultValue(IC_RESULT(ic));
2276 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2277 AopType(AOP_TYPE(IC_RESULT(ic))));
2279 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2282 /* adjust the stack for parameters if
2284 if (ic->parmBytes) {
2286 if (ic->parmBytes > 3) {
2287 pic14_emitcode("mov","a,%s",spname);
2288 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2289 pic14_emitcode("mov","%s,a",spname);
2291 for ( i = 0 ; i < ic->parmBytes ;i++)
2292 pic14_emitcode("dec","%s",spname);
2296 /* if register bank was saved then pop them */
2298 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2300 /* if we hade saved some registers then unsave them */
2301 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2302 unsaveRegisters (ic);
2307 /*-----------------------------------------------------------------*/
2308 /* genPcall - generates a call by pointer statement */
2309 /*-----------------------------------------------------------------*/
2310 static void genPcall (iCode *ic)
2313 symbol *rlbl = newiTempLabel(NULL);
2316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 /* if caller saves & we have not saved then */
2321 /* if we are calling a function that is not using
2322 the same register bank then we need to save the
2323 destination registers on the stack */
2324 dtype = operandType(IC_LEFT(ic));
2325 if (currFunc && dtype &&
2326 IFFUNC_ISISR(currFunc->type) &&
2327 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2328 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2331 /* push the return address on to the stack */
2332 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2333 pic14_emitcode("push","acc");
2334 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2335 pic14_emitcode("push","acc");
2337 if (options.model == MODEL_FLAT24)
2339 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2340 pic14_emitcode("push","acc");
2343 /* now push the calling address */
2344 aopOp(IC_LEFT(ic),ic,FALSE);
2346 pushSide(IC_LEFT(ic), FPTRSIZE);
2348 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2350 /* if send set is not empty the assign */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2356 int size, offset = 0;
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 size = AOP_SIZE(IC_LEFT(sic));
2360 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2362 if (strcmp(l,fReturn[offset]))
2363 pic14_emitcode("mov","%s,%s",
2368 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2373 pic14_emitcode("ret","");
2374 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2377 /* if we need assign a result value */
2378 if ((IS_ITEMP(IC_RESULT(ic)) &&
2379 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2380 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2381 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2384 aopOp(IC_RESULT(ic),ic,FALSE);
2387 assignResultValue(IC_RESULT(ic));
2389 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2392 /* adjust the stack for parameters if
2394 if (ic->parmBytes) {
2396 if (ic->parmBytes > 3) {
2397 pic14_emitcode("mov","a,%s",spname);
2398 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2399 pic14_emitcode("mov","%s,a",spname);
2401 for ( i = 0 ; i < ic->parmBytes ;i++)
2402 pic14_emitcode("dec","%s",spname);
2406 /* if register bank was saved then unsave them */
2407 if (currFunc && dtype &&
2408 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2409 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2411 /* if we hade saved some registers then
2414 unsaveRegisters (ic);
2418 /*-----------------------------------------------------------------*/
2419 /* resultRemat - result is rematerializable */
2420 /*-----------------------------------------------------------------*/
2421 static int resultRemat (iCode *ic)
2423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2424 if (SKIP_IC(ic) || ic->op == IFX)
2427 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2428 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2429 if (sym->remat && !POINTER_SET(ic))
2436 #if defined(__BORLANDC__) || defined(_MSC_VER)
2437 #define STRCASECMP stricmp
2439 #define STRCASECMP strcasecmp
2442 /*-----------------------------------------------------------------*/
2443 /* inExcludeList - return 1 if the string is in exclude Reg list */
2444 /*-----------------------------------------------------------------*/
2445 static bool inExcludeList(char *s)
2447 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2452 if (options.excludeRegs[i] &&
2453 STRCASECMP(options.excludeRegs[i],"none") == 0)
2456 for ( i = 0 ; options.excludeRegs[i]; i++) {
2457 if (options.excludeRegs[i] &&
2458 STRCASECMP(s,options.excludeRegs[i]) == 0)
2465 /*-----------------------------------------------------------------*/
2466 /* genFunction - generated code for function entry */
2467 /*-----------------------------------------------------------------*/
2468 static void genFunction (iCode *ic)
2473 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2475 labelOffset += (max_key+4);
2479 /* create the function header */
2480 pic14_emitcode(";","-----------------------------------------");
2481 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2482 pic14_emitcode(";","-----------------------------------------");
2484 pic14_emitcode("","%s:",sym->rname);
2485 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2487 ftype = operandType(IC_LEFT(ic));
2489 /* if critical function then turn interrupts off */
2490 if (IFFUNC_ISCRITICAL(ftype))
2491 pic14_emitcode("clr","ea");
2493 /* here we need to generate the equates for the
2494 register bank if required */
2496 if (FUNC_REGBANK(ftype) != rbank) {
2499 rbank = FUNC_REGBANK(ftype);
2500 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2501 if (strcmp(regspic14[i].base,"0") == 0)
2502 pic14_emitcode("","%s = 0x%02x",
2504 8*rbank+regspic14[i].offset);
2506 pic14_emitcode ("","%s = %s + 0x%02x",
2509 8*rbank+regspic14[i].offset);
2514 /* if this is an interrupt service routine then
2515 save acc, b, dpl, dph */
2516 if (IFFUNC_ISISR(sym->type)) {
2518 if (!inExcludeList("acc"))
2519 pic14_emitcode ("push","acc");
2520 if (!inExcludeList("b"))
2521 pic14_emitcode ("push","b");
2522 if (!inExcludeList("dpl"))
2523 pic14_emitcode ("push","dpl");
2524 if (!inExcludeList("dph"))
2525 pic14_emitcode ("push","dph");
2526 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2528 pic14_emitcode ("push", "dpx");
2529 /* Make sure we're using standard DPTR */
2530 pic14_emitcode ("push", "dps");
2531 pic14_emitcode ("mov", "dps, #0x00");
2532 if (options.stack10bit)
2534 /* This ISR could conceivably use DPTR2. Better save it. */
2535 pic14_emitcode ("push", "dpl1");
2536 pic14_emitcode ("push", "dph1");
2537 pic14_emitcode ("push", "dpx1");
2540 /* if this isr has no bank i.e. is going to
2541 run with bank 0 , then we need to save more
2543 if (!FUNC_REGBANK(sym->type)) {
2545 /* if this function does not call any other
2546 function then we can be economical and
2547 save only those registers that are used */
2548 if (! IFFUNC_HASFCALL(sym->type)) {
2551 /* if any registers used */
2552 if (sym->regsUsed) {
2553 /* save the registers used */
2554 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2555 if (bitVectBitValue(sym->regsUsed,i) ||
2556 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2557 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2562 /* this function has a function call cannot
2563 determines register usage so we will have the
2565 saverbank(0,ic,FALSE);
2569 /* if callee-save to be used for this function
2570 then save the registers being used in this function */
2571 if (IFFUNC_CALLEESAVES(sym->type)) {
2574 /* if any registers used */
2575 if (sym->regsUsed) {
2576 /* save the registers used */
2577 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2578 if (bitVectBitValue(sym->regsUsed,i) ||
2579 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2580 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2588 /* set the register bank to the desired value */
2589 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2590 pic14_emitcode("push","psw");
2591 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2594 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2596 if (options.useXstack) {
2597 pic14_emitcode("mov","r0,%s",spname);
2598 pic14_emitcode("mov","a,_bp");
2599 pic14_emitcode("movx","@r0,a");
2600 pic14_emitcode("inc","%s",spname);
2604 /* set up the stack */
2605 pic14_emitcode ("push","_bp"); /* save the callers stack */
2607 pic14_emitcode ("mov","_bp,%s",spname);
2610 /* adjust the stack for the function */
2615 werror(W_STACK_OVERFLOW,sym->name);
2617 if (i > 3 && sym->recvSize < 4) {
2619 pic14_emitcode ("mov","a,sp");
2620 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2621 pic14_emitcode ("mov","sp,a");
2626 pic14_emitcode("inc","sp");
2631 pic14_emitcode ("mov","a,_spx");
2632 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2633 pic14_emitcode ("mov","_spx,a");
2638 /*-----------------------------------------------------------------*/
2639 /* genEndFunction - generates epilogue for functions */
2640 /*-----------------------------------------------------------------*/
2641 static void genEndFunction (iCode *ic)
2643 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2649 pic14_emitcode ("mov","%s,_bp",spname);
2652 /* if use external stack but some variables were
2653 added to the local stack then decrement the
2655 if (options.useXstack && sym->stack) {
2656 pic14_emitcode("mov","a,sp");
2657 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2658 pic14_emitcode("mov","sp,a");
2662 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2663 if (options.useXstack) {
2664 pic14_emitcode("mov","r0,%s",spname);
2665 pic14_emitcode("movx","a,@r0");
2666 pic14_emitcode("mov","_bp,a");
2667 pic14_emitcode("dec","%s",spname);
2671 pic14_emitcode ("pop","_bp");
2675 /* restore the register bank */
2676 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2677 pic14_emitcode ("pop","psw");
2679 if (IFFUNC_ISISR(sym->type)) {
2681 /* now we need to restore the registers */
2682 /* if this isr has no bank i.e. is going to
2683 run with bank 0 , then we need to save more
2685 if (!FUNC_REGBANK(sym->type)) {
2687 /* if this function does not call any other
2688 function then we can be economical and
2689 save only those registers that are used */
2690 if (! IFFUNC_HASFCALL(sym->type)) {
2693 /* if any registers used */
2694 if (sym->regsUsed) {
2695 /* save the registers used */
2696 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2697 if (bitVectBitValue(sym->regsUsed,i) ||
2698 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2699 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2704 /* this function has a function call cannot
2705 determines register usage so we will have the
2707 unsaverbank(0,ic,FALSE);
2711 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2713 if (options.stack10bit)
2715 pic14_emitcode ("pop", "dpx1");
2716 pic14_emitcode ("pop", "dph1");
2717 pic14_emitcode ("pop", "dpl1");
2719 pic14_emitcode ("pop", "dps");
2720 pic14_emitcode ("pop", "dpx");
2722 if (!inExcludeList("dph"))
2723 pic14_emitcode ("pop","dph");
2724 if (!inExcludeList("dpl"))
2725 pic14_emitcode ("pop","dpl");
2726 if (!inExcludeList("b"))
2727 pic14_emitcode ("pop","b");
2728 if (!inExcludeList("acc"))
2729 pic14_emitcode ("pop","acc");
2731 if (IFFUNC_ISCRITICAL(sym->type))
2732 pic14_emitcode("setb","ea");
2734 /* if debug then send end of function */
2735 /* if (options.debug && currFunc) { */
2738 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2739 FileBaseName(ic->filename),currFunc->lastLine,
2740 ic->level,ic->block);
2741 if (IS_STATIC(currFunc->etype))
2742 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2744 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2748 pic14_emitcode ("reti","");
2751 if (IFFUNC_ISCRITICAL(sym->type))
2752 pic14_emitcode("setb","ea");
2754 if (IFFUNC_CALLEESAVES(sym->type)) {
2757 /* if any registers used */
2758 if (sym->regsUsed) {
2759 /* save the registers used */
2760 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2761 if (bitVectBitValue(sym->regsUsed,i) ||
2762 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2763 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2769 /* if debug then send end of function */
2772 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2773 FileBaseName(ic->filename),currFunc->lastLine,
2774 ic->level,ic->block);
2775 if (IS_STATIC(currFunc->etype))
2776 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2778 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2782 pic14_emitcode ("return","");
2783 emitpcodeNULLop(POC_RETURN);
2785 /* Mark the end of a function */
2786 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2791 /*-----------------------------------------------------------------*/
2792 /* genRet - generate code for return statement */
2793 /*-----------------------------------------------------------------*/
2794 static void genRet (iCode *ic)
2796 int size,offset = 0 , pushed = 0;
2798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2799 /* if we have no return value then
2800 just generate the "ret" */
2804 /* we have something to return then
2805 move the return value into place */
2806 aopOp(IC_LEFT(ic),ic,FALSE);
2807 size = AOP_SIZE(IC_LEFT(ic));
2811 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2813 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2815 pic14_emitcode("push","%s",l);
2818 l = aopGet(AOP(IC_LEFT(ic)),offset,
2820 if (strcmp(fReturn[offset],l)) {
2821 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2822 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2823 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2825 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2828 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2829 pic14_emitcode("movwf","%s",fReturn[offset]);
2839 if (strcmp(fReturn[pushed],"a"))
2840 pic14_emitcode("pop",fReturn[pushed]);
2842 pic14_emitcode("pop","acc");
2845 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2848 /* generate a jump to the return label
2849 if the next is not the return statement */
2850 if (!(ic->next && ic->next->op == LABEL &&
2851 IC_LABEL(ic->next) == returnLabel)) {
2853 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2854 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2859 /*-----------------------------------------------------------------*/
2860 /* genLabel - generates a label */
2861 /*-----------------------------------------------------------------*/
2862 static void genLabel (iCode *ic)
2864 /* special case never generate */
2865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2866 if (IC_LABEL(ic) == entryLabel)
2869 emitpLabel(IC_LABEL(ic)->key);
2870 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2873 /*-----------------------------------------------------------------*/
2874 /* genGoto - generates a goto */
2875 /*-----------------------------------------------------------------*/
2877 static void genGoto (iCode *ic)
2879 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2880 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2884 /*-----------------------------------------------------------------*/
2885 /* genMultbits :- multiplication of bits */
2886 /*-----------------------------------------------------------------*/
2887 static void genMultbits (operand *left,
2891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2893 if(!pic14_sameRegs(AOP(result),AOP(right)))
2894 emitpcode(POC_BSF, popGet(AOP(result),0));
2896 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2897 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2898 emitpcode(POC_BCF, popGet(AOP(result),0));
2903 /*-----------------------------------------------------------------*/
2904 /* genMultOneByte : 8 bit multiplication & division */
2905 /*-----------------------------------------------------------------*/
2906 static void genMultOneByte (operand *left,
2910 sym_link *opetype = operandType(result);
2915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2916 DEBUGpic14_AopType(__LINE__,left,right,result);
2918 /* (if two literals, the value is computed before) */
2919 /* if one literal, literal on the right */
2920 if (AOP_TYPE(left) == AOP_LIT){
2926 size = AOP_SIZE(result);
2927 /* signed or unsigned */
2928 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2929 l = aopGet(AOP(left),0,FALSE,FALSE);
2931 pic14_emitcode("mul","ab");
2932 /* if result size = 1, mul signed = mul unsigned */
2933 aopPut(AOP(result),"a",0);
2935 if (SPEC_USIGN(opetype)){
2936 aopPut(AOP(result),"b",1);
2938 /* for filling the MSBs */
2939 pic14_emitcode("clr","a");
2942 pic14_emitcode("mov","a,b");
2944 /* adjust the MSB if left or right neg */
2946 /* if one literal */
2947 if (AOP_TYPE(right) == AOP_LIT){
2948 /* AND literal negative */
2949 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2950 /* adjust MSB (c==0 after mul) */
2951 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2955 lbl = newiTempLabel(NULL);
2956 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2957 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2958 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2959 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2960 lbl = newiTempLabel(NULL);
2961 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2962 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2963 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2966 lbl = newiTempLabel(NULL);
2967 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2968 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2969 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2970 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2971 lbl = newiTempLabel(NULL);
2972 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2973 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2974 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2976 aopPut(AOP(result),"a",1);
2979 pic14_emitcode("rlc","a");
2980 pic14_emitcode("subb","a,acc");
2987 aopPut(AOP(result),"a",offset++);
2991 /*-----------------------------------------------------------------*/
2992 /* genMult - generates code for multiplication */
2993 /*-----------------------------------------------------------------*/
2994 static void genMult (iCode *ic)
2996 operand *left = IC_LEFT(ic);
2997 operand *right = IC_RIGHT(ic);
2998 operand *result= IC_RESULT(ic);
3000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3001 /* assign the amsops */
3002 aopOp (left,ic,FALSE);
3003 aopOp (right,ic,FALSE);
3004 aopOp (result,ic,TRUE);
3006 DEBUGpic14_AopType(__LINE__,left,right,result);
3008 /* special cases first */
3010 if (AOP_TYPE(left) == AOP_CRY &&
3011 AOP_TYPE(right)== AOP_CRY) {
3012 genMultbits(left,right,result);
3016 /* if both are of size == 1 */
3017 if (AOP_SIZE(left) == 1 &&
3018 AOP_SIZE(right) == 1 ) {
3019 genMultOneByte(left,right,result);
3023 /* should have been converted to function call */
3027 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3028 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3029 freeAsmop(result,NULL,ic,TRUE);
3032 /*-----------------------------------------------------------------*/
3033 /* genDivbits :- division of bits */
3034 /*-----------------------------------------------------------------*/
3035 static void genDivbits (operand *left,
3042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3043 /* the result must be bit */
3044 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3045 l = aopGet(AOP(left),0,FALSE,FALSE);
3049 pic14_emitcode("div","ab");
3050 pic14_emitcode("rrc","a");
3051 aopPut(AOP(result),"c",0);
3054 /*-----------------------------------------------------------------*/
3055 /* genDivOneByte : 8 bit division */
3056 /*-----------------------------------------------------------------*/
3057 static void genDivOneByte (operand *left,
3061 sym_link *opetype = operandType(result);
3066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3067 size = AOP_SIZE(result) - 1;
3069 /* signed or unsigned */
3070 if (SPEC_USIGN(opetype)) {
3071 /* unsigned is easy */
3072 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3073 l = aopGet(AOP(left),0,FALSE,FALSE);
3075 pic14_emitcode("div","ab");
3076 aopPut(AOP(result),"a",0);
3078 aopPut(AOP(result),zero,offset++);
3082 /* signed is a little bit more difficult */
3084 /* save the signs of the operands */
3085 l = aopGet(AOP(left),0,FALSE,FALSE);
3087 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3088 pic14_emitcode("push","acc"); /* save it on the stack */
3090 /* now sign adjust for both left & right */
3091 l = aopGet(AOP(right),0,FALSE,FALSE);
3093 lbl = newiTempLabel(NULL);
3094 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3095 pic14_emitcode("cpl","a");
3096 pic14_emitcode("inc","a");
3097 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3098 pic14_emitcode("mov","b,a");
3100 /* sign adjust left side */
3101 l = aopGet(AOP(left),0,FALSE,FALSE);
3104 lbl = newiTempLabel(NULL);
3105 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3106 pic14_emitcode("cpl","a");
3107 pic14_emitcode("inc","a");
3108 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3110 /* now the division */
3111 pic14_emitcode("div","ab");
3112 /* we are interested in the lower order
3114 pic14_emitcode("mov","b,a");
3115 lbl = newiTempLabel(NULL);
3116 pic14_emitcode("pop","acc");
3117 /* if there was an over flow we don't
3118 adjust the sign of the result */
3119 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3120 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3122 pic14_emitcode("clr","a");
3123 pic14_emitcode("subb","a,b");
3124 pic14_emitcode("mov","b,a");
3125 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3127 /* now we are done */
3128 aopPut(AOP(result),"b",0);
3130 pic14_emitcode("mov","c,b.7");
3131 pic14_emitcode("subb","a,acc");
3134 aopPut(AOP(result),"a",offset++);
3138 /*-----------------------------------------------------------------*/
3139 /* genDiv - generates code for division */
3140 /*-----------------------------------------------------------------*/
3141 static void genDiv (iCode *ic)
3143 operand *left = IC_LEFT(ic);
3144 operand *right = IC_RIGHT(ic);
3145 operand *result= IC_RESULT(ic);
3147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3148 /* assign the amsops */
3149 aopOp (left,ic,FALSE);
3150 aopOp (right,ic,FALSE);
3151 aopOp (result,ic,TRUE);
3153 /* special cases first */
3155 if (AOP_TYPE(left) == AOP_CRY &&
3156 AOP_TYPE(right)== AOP_CRY) {
3157 genDivbits(left,right,result);
3161 /* if both are of size == 1 */
3162 if (AOP_SIZE(left) == 1 &&
3163 AOP_SIZE(right) == 1 ) {
3164 genDivOneByte(left,right,result);
3168 /* should have been converted to function call */
3171 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3172 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3173 freeAsmop(result,NULL,ic,TRUE);
3176 /*-----------------------------------------------------------------*/
3177 /* genModbits :- modulus of bits */
3178 /*-----------------------------------------------------------------*/
3179 static void genModbits (operand *left,
3186 /* the result must be bit */
3187 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3188 l = aopGet(AOP(left),0,FALSE,FALSE);
3192 pic14_emitcode("div","ab");
3193 pic14_emitcode("mov","a,b");
3194 pic14_emitcode("rrc","a");
3195 aopPut(AOP(result),"c",0);
3198 /*-----------------------------------------------------------------*/
3199 /* genModOneByte : 8 bit modulus */
3200 /*-----------------------------------------------------------------*/
3201 static void genModOneByte (operand *left,
3205 sym_link *opetype = operandType(result);
3209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3210 /* signed or unsigned */
3211 if (SPEC_USIGN(opetype)) {
3212 /* unsigned is easy */
3213 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3214 l = aopGet(AOP(left),0,FALSE,FALSE);
3216 pic14_emitcode("div","ab");
3217 aopPut(AOP(result),"b",0);
3221 /* signed is a little bit more difficult */
3223 /* save the signs of the operands */
3224 l = aopGet(AOP(left),0,FALSE,FALSE);
3227 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3228 pic14_emitcode("push","acc"); /* save it on the stack */
3230 /* now sign adjust for both left & right */
3231 l = aopGet(AOP(right),0,FALSE,FALSE);
3234 lbl = newiTempLabel(NULL);
3235 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3236 pic14_emitcode("cpl","a");
3237 pic14_emitcode("inc","a");
3238 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3239 pic14_emitcode("mov","b,a");
3241 /* sign adjust left side */
3242 l = aopGet(AOP(left),0,FALSE,FALSE);
3245 lbl = newiTempLabel(NULL);
3246 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3247 pic14_emitcode("cpl","a");
3248 pic14_emitcode("inc","a");
3249 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251 /* now the multiplication */
3252 pic14_emitcode("div","ab");
3253 /* we are interested in the lower order
3255 lbl = newiTempLabel(NULL);
3256 pic14_emitcode("pop","acc");
3257 /* if there was an over flow we don't
3258 adjust the sign of the result */
3259 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3262 pic14_emitcode("clr","a");
3263 pic14_emitcode("subb","a,b");
3264 pic14_emitcode("mov","b,a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3267 /* now we are done */
3268 aopPut(AOP(result),"b",0);
3272 /*-----------------------------------------------------------------*/
3273 /* genMod - generates code for division */
3274 /*-----------------------------------------------------------------*/
3275 static void genMod (iCode *ic)
3277 operand *left = IC_LEFT(ic);
3278 operand *right = IC_RIGHT(ic);
3279 operand *result= IC_RESULT(ic);
3281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3282 /* assign the amsops */
3283 aopOp (left,ic,FALSE);
3284 aopOp (right,ic,FALSE);
3285 aopOp (result,ic,TRUE);
3287 /* special cases first */
3289 if (AOP_TYPE(left) == AOP_CRY &&
3290 AOP_TYPE(right)== AOP_CRY) {
3291 genModbits(left,right,result);
3295 /* if both are of size == 1 */
3296 if (AOP_SIZE(left) == 1 &&
3297 AOP_SIZE(right) == 1 ) {
3298 genModOneByte(left,right,result);
3302 /* should have been converted to function call */
3306 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3307 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3308 freeAsmop(result,NULL,ic,TRUE);
3311 /*-----------------------------------------------------------------*/
3312 /* genIfxJump :- will create a jump depending on the ifx */
3313 /*-----------------------------------------------------------------*/
3315 note: May need to add parameter to indicate when a variable is in bit space.
3317 static void genIfxJump (iCode *ic, char *jval)
3320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3321 /* if true label then we jump if condition
3323 if ( IC_TRUE(ic) ) {
3325 if(strcmp(jval,"a") == 0)
3327 else if (strcmp(jval,"c") == 0)
3330 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3331 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3334 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3335 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3339 /* false label is present */
3340 if(strcmp(jval,"a") == 0)
3342 else if (strcmp(jval,"c") == 0)
3345 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3346 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3349 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3350 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3355 /* mark the icode as generated */
3359 /*-----------------------------------------------------------------*/
3361 /*-----------------------------------------------------------------*/
3362 static void genSkip(iCode *ifx,int status_bit)
3367 if ( IC_TRUE(ifx) ) {
3368 switch(status_bit) {
3383 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3384 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3388 switch(status_bit) {
3402 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3403 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3409 /*-----------------------------------------------------------------*/
3411 /*-----------------------------------------------------------------*/
3412 static void genSkipc(resolvedIfx *rifx)
3422 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3423 rifx->generated = 1;
3426 /*-----------------------------------------------------------------*/
3428 /*-----------------------------------------------------------------*/
3429 static void genSkipz2(resolvedIfx *rifx)
3439 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3440 rifx->generated = 1;
3443 /*-----------------------------------------------------------------*/
3445 /*-----------------------------------------------------------------*/
3446 static void genSkipz(iCode *ifx, int condition)
3457 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3459 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3462 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3464 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3467 /*-----------------------------------------------------------------*/
3469 /*-----------------------------------------------------------------*/
3470 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3476 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3478 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3481 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3482 rifx->generated = 1;
3485 /*-----------------------------------------------------------------*/
3486 /* genChkZeroes :- greater or less than comparison */
3487 /* For each byte in a literal that is zero, inclusive or the */
3488 /* the corresponding byte in the operand with W */
3489 /* returns true if any of the bytes are zero */
3490 /*-----------------------------------------------------------------*/
3491 static int genChkZeroes(operand *op, int lit, int size)
3498 i = (lit >> (size*8)) & 0xff;
3502 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3504 emitpcode(POC_IORFW, popGet(AOP(op),size));
3512 /*-----------------------------------------------------------------*/
3513 /* genCmp :- greater or less than comparison */
3514 /*-----------------------------------------------------------------*/
3515 static void genCmp (operand *left,operand *right,
3516 operand *result, iCode *ifx, int sign)
3518 int size, offset = 0 ;
3519 unsigned long lit = 0L,i = 0;
3522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3524 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3525 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3528 resolveIfx(&rIfx,ifx);
3530 /* if left & right are bit variables */
3531 if (AOP_TYPE(left) == AOP_CRY &&
3532 AOP_TYPE(right) == AOP_CRY ) {
3533 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3534 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3536 /* subtract right from left if at the
3537 end the carry flag is set then we know that
3538 left is greater than right */
3539 size = max(AOP_SIZE(left),AOP_SIZE(right));
3541 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3542 if((size == 1) && !sign &&
3543 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3544 symbol *lbl = newiTempLabel(NULL);
3545 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3546 aopGet(AOP(left),offset,FALSE,FALSE),
3547 aopGet(AOP(right),offset,FALSE,FALSE),
3549 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3552 symbol *lbl = newiTempLabel(NULL);
3554 int emitFinalCheck=1;
3555 symbol *truelbl = newiTempLabel(NULL);
3558 if(AOP_TYPE(right) == AOP_LIT) {
3560 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3562 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3569 genSkipCond(&rIfx,left,size-1,7);
3571 /* no need to compare to 0...*/
3572 /* NOTE: this is a de-generate compare that most certainly
3573 * creates some dead code. */
3574 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3576 if(ifx) ifx->generated = 1;
3583 //i = (lit >> (size*8)) & 0xff;
3584 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3586 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3588 i = ((0-lit) & 0xff);
3591 /* lit is 0x7f, all signed chars are less than
3592 * this except for 0x7f itself */
3593 emitpcode(POC_XORLW, popGetLit(0x7f));
3596 emitpcode(POC_ADDLW, popGetLit(0x80));
3597 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3602 emitpcode(POC_ADDLW, popGetLit(i));
3607 if(ifx) ifx->generated = 1;
3611 /* chars are out of the way. now do ints and longs */
3614 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3619 unsigned int mlit = -lit;
3622 genSkipCond(&rIfx,left,size,7);
3623 if(ifx) ifx->generated = 1;
3628 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3630 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3631 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3632 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3633 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3634 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3637 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3642 emitpLabel(truelbl->key);
3643 if(ifx) ifx->generated = 1;
3650 if( (lit & 0xff) == 0) {
3651 /* lower byte is zero */
3652 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3653 i = ((lit >> 8) & 0xff) ^0x80;
3654 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3655 emitpcode(POC_ADDLW, popGetLit( 0x80));
3656 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3660 if(ifx) ifx->generated = 1;
3665 /* Special cases for signed longs */
3666 if( (lit & 0xffffff) == 0) {
3667 /* lower byte is zero */
3668 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3669 i = ((lit >> 8*3) & 0xff) ^0x80;
3670 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3671 emitpcode(POC_ADDLW, popGetLit( 0x80));
3672 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3676 if(ifx) ifx->generated = 1;
3682 if( lit < 0x10000) {
3683 /* upper word is zero */
3684 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3686 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3687 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3689 emitpcode(POC_MOVLW, popGetLit((lit >> (1*8)) & 0xff));
3690 emitpcode(POC_SUBFW, popGet(AOP(left),1));
3691 emitpcode(POC_MOVLW, popGetLit((lit & 0xff));
3693 emitpcode(POC_SUBFW, popGet(AOP(left),0));
3695 emitpcode(POC_IORFW, popGet(AOP(left),2));
3696 emitpcode(POC_IORFW, popGet(AOP(left),3));
3701 emitpLabel(truelbl->key);
3702 if(ifx) ifx->generated = 1;
3711 if(lit & (0x80 << (size*8))) {
3712 /* lit is negative */
3713 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3715 genSkipCond(&rIfx,left,size,7);
3717 /* lit is positive */
3718 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3719 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3720 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3725 This works, but is only good for ints.
3726 It also requires a "known zero" register.
3727 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3728 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3729 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3730 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3731 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3734 emitpLabel(truelbl->key);
3735 if(ifx) ifx->generated = 1;
3739 /* There are no more special cases, so perform a general compare */
3741 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3742 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3746 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3748 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3753 emitpLabel(truelbl->key);
3755 if(ifx) ifx->generated = 1;
3762 /* sign is out of the way. So now do an unsigned compare */
3763 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3766 //genChkZeroes(left)
3768 /* General case - compare to an unsigned literal on the right.*/
3770 i = (lit >> (size*8)) & 0xff;
3771 emitpcode(POC_MOVLW, popGetLit(i));
3772 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3774 i = (lit >> (size*8)) & 0xff;
3777 emitpcode(POC_MOVLW, popGetLit(i));
3779 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3781 /* this byte of the lit is zero,
3782 *if it's not the last then OR in the variable */
3784 emitpcode(POC_IORFW, popGet(AOP(left),size));
3789 emitpLabel(lbl->key);
3793 emitpLabel(truelbl->key);
3795 if(ifx) ifx->generated = 1;
3801 if(AOP_TYPE(left) == AOP_LIT) {
3802 //symbol *lbl = newiTempLabel(NULL);
3804 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3807 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3810 if((lit == 0) && (sign == 0)){
3813 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3815 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3817 //rIfx.condition ^= 1;
3819 if(ifx) ifx->generated = 1;
3826 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3827 /* degenerate compare can never be true */
3828 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3829 if(ifx) ifx->generated = 1;
3835 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3836 emitpcode(POC_ADDLW, popGetLit(0x80));
3837 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3838 rIfx.condition ^= 1;
3841 rIfx.condition ^= 1;
3842 genSkipCond(&rIfx,right,0,7);
3847 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3848 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3850 rIfx.condition ^= 1;
3853 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3858 if(ifx) ifx->generated = 1;
3863 /* Size is greater than 1 */
3874 /* this means lit = 0xffffffff, or -1 */
3877 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
3878 rIfx.condition ^= 1;
3879 genSkipCond(&rIfx,right,size,7);
3880 if(ifx) ifx->generated = 1;
3886 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3888 emitpcode(POC_IORFW, popGet(AOP(right),size));
3891 rIfx.condition ^= 1;
3892 genSkipCond(&rIfx,right,s,7);
3893 if(ifx) ifx->generated = 1;
3898 if(lit & (0x80 << (size*8))) {
3899 /* Lit is less than zero */
3900 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
3901 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3902 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3905 /* Lit is greater than or equal to zero */
3906 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
3907 rIfx.condition ^= 1;
3908 genSkipCond(&rIfx,right,size,7);
3909 rIfx.condition ^= 1;
3912 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3913 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3917 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3919 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3921 rIfx.condition ^= 1;
3924 emitpLabel(truelbl->key);
3926 if(ifx) ifx->generated = 1;
3930 /* Unsigned compare for sizes greater than 1 */
3933 i = (lit >> (size*8)) & 0xff;
3937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3938 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3939 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3941 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3943 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3944 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3945 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3950 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3952 emitpLabel(lbl->key);
3954 rIfx.condition ^= 1;
3959 emitpLabel(truelbl->key);
3960 if(ifx) ifx->generated = 1;
3964 /* Compare two variables */
3966 DEBUGpic14_emitcode(";sign","%d",sign);
3970 /* Sigh. thus sucks... */
3972 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3973 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
3974 emitpcode(POC_MOVLW, popGetLit(0x80));
3975 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
3976 emitpcode(POC_XORFW, popGet(AOP(right),size));
3977 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
3979 /* Signed char comparison */
3980 /* Special thanks to Nikolai Golovchenko for this snippet */
3981 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3982 emitpcode(POC_SUBFW, popGet(AOP(left),0));
3983 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
3984 emitpcode(POC_XORFW, popGet(AOP(left),0));
3985 emitpcode(POC_XORFW, popGet(AOP(right),0));
3986 emitpcode(POC_ADDLW, popGetLit(0x80));
3988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3991 if(ifx) ifx->generated = 1;
3997 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3998 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4002 /* The rest of the bytes of a multi-byte compare */
4006 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4009 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4010 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4015 emitpLabel(lbl->key);
4017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4019 if(ifx) ifx->generated = 1;
4026 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4027 pic14_outBitC(result);
4029 /* if the result is used in the next
4030 ifx conditional branch then generate
4031 code a little differently */
4033 genIfxJump (ifx,"c");
4035 pic14_outBitC(result);
4036 /* leave the result in acc */
4041 /*-----------------------------------------------------------------*/
4042 /* genCmpGt :- greater than comparison */
4043 /*-----------------------------------------------------------------*/
4044 static void genCmpGt (iCode *ic, iCode *ifx)
4046 operand *left, *right, *result;
4047 sym_link *letype , *retype;
4050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4052 right= IC_RIGHT(ic);
4053 result = IC_RESULT(ic);
4055 letype = getSpec(operandType(left));
4056 retype =getSpec(operandType(right));
4057 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4058 /* assign the amsops */
4059 aopOp (left,ic,FALSE);
4060 aopOp (right,ic,FALSE);
4061 aopOp (result,ic,TRUE);
4063 genCmp(right, left, result, ifx, sign);
4065 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4066 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4067 freeAsmop(result,NULL,ic,TRUE);
4070 /*-----------------------------------------------------------------*/
4071 /* genCmpLt - less than comparisons */
4072 /*-----------------------------------------------------------------*/
4073 static void genCmpLt (iCode *ic, iCode *ifx)
4075 operand *left, *right, *result;
4076 sym_link *letype , *retype;
4079 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4081 right= IC_RIGHT(ic);
4082 result = IC_RESULT(ic);
4084 letype = getSpec(operandType(left));
4085 retype =getSpec(operandType(right));
4086 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4088 /* assign the amsops */
4089 aopOp (left,ic,FALSE);
4090 aopOp (right,ic,FALSE);
4091 aopOp (result,ic,TRUE);
4093 genCmp(left, right, result, ifx, sign);
4095 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4096 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4097 freeAsmop(result,NULL,ic,TRUE);
4100 /*-----------------------------------------------------------------*/
4101 /* genc16bit2lit - compare a 16 bit value to a literal */
4102 /*-----------------------------------------------------------------*/
4103 static void genc16bit2lit(operand *op, int lit, int offset)
4107 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4108 if( (lit&0xff) == 0)
4113 switch( BYTEofLONG(lit,i)) {
4115 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4118 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4121 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4124 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4125 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4130 switch( BYTEofLONG(lit,i)) {
4132 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4136 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4140 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4143 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4145 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4151 /*-----------------------------------------------------------------*/
4152 /* gencjneshort - compare and jump if not equal */
4153 /*-----------------------------------------------------------------*/
4154 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4156 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4161 unsigned long lit = 0L;
4162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4163 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4165 resolveIfx(&rIfx,ifx);
4166 lbl = newiTempLabel(NULL);
4169 /* if the left side is a literal or
4170 if the right is in a pointer register and left
4172 if ((AOP_TYPE(left) == AOP_LIT) ||
4173 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4178 if(AOP_TYPE(right) == AOP_LIT)
4179 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4181 /* if the right side is a literal then anything goes */
4182 if (AOP_TYPE(right) == AOP_LIT &&
4183 AOP_TYPE(left) != AOP_DIR ) {
4186 genc16bit2lit(left, lit, 0);
4188 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4193 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4194 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4196 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4200 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4208 /* if the right side is in a register or in direct space or
4209 if the left is a pointer register & right is not */
4210 else if (AOP_TYPE(right) == AOP_REG ||
4211 AOP_TYPE(right) == AOP_DIR ||
4212 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4213 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4216 genc16bit2lit(left, lit, 0);
4218 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4223 if((AOP_TYPE(left) == AOP_DIR) &&
4224 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4226 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4227 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4229 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4231 switch (lit & 0xff) {
4233 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4236 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4237 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4241 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4242 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4246 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4247 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4252 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4255 if(AOP_TYPE(result) == AOP_CRY) {
4256 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4261 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4263 /* fix me. probably need to check result size too */
4264 emitpcode(POC_CLRF,popGet(AOP(result),0));
4269 emitpcode(POC_INCF,popGet(AOP(result),0));
4279 } else if(AOP_TYPE(right) == AOP_REG &&
4280 AOP_TYPE(left) != AOP_DIR){
4283 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4284 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4285 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4290 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4295 /* right is a pointer reg need both a & b */
4297 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4299 pic14_emitcode("mov","b,%s",l);
4300 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4301 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4305 emitpLabel(lbl->key);
4312 /*-----------------------------------------------------------------*/
4313 /* gencjne - compare and jump if not equal */
4314 /*-----------------------------------------------------------------*/
4315 static void gencjne(operand *left, operand *right, iCode *ifx)
4317 symbol *tlbl = newiTempLabel(NULL);
4319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4320 gencjneshort(left, right, lbl);
4322 pic14_emitcode("mov","a,%s",one);
4323 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4324 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4325 pic14_emitcode("clr","a");
4326 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4328 emitpLabel(lbl->key);
4329 emitpLabel(tlbl->key);
4334 /*-----------------------------------------------------------------*/
4335 /* genCmpEq - generates code for equal to */
4336 /*-----------------------------------------------------------------*/
4337 static void genCmpEq (iCode *ic, iCode *ifx)
4339 operand *left, *right, *result;
4340 unsigned long lit = 0L;
4343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4346 DEBUGpic14_emitcode ("; ifx is non-null","");
4348 DEBUGpic14_emitcode ("; ifx is null","");
4350 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4351 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4352 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4354 size = max(AOP_SIZE(left),AOP_SIZE(right));
4356 DEBUGpic14_AopType(__LINE__,left,right,result);
4358 /* if literal, literal on the right or
4359 if the right is in a pointer register and left
4361 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4362 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4363 operand *tmp = right ;
4369 if(ifx && !AOP_SIZE(result)){
4371 /* if they are both bit variables */
4372 if (AOP_TYPE(left) == AOP_CRY &&
4373 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4374 if(AOP_TYPE(right) == AOP_LIT){
4375 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4377 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4378 pic14_emitcode("cpl","c");
4379 } else if(lit == 1L) {
4380 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4382 pic14_emitcode("clr","c");
4384 /* AOP_TYPE(right) == AOP_CRY */
4386 symbol *lbl = newiTempLabel(NULL);
4387 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4388 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4389 pic14_emitcode("cpl","c");
4390 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4392 /* if true label then we jump if condition
4394 tlbl = newiTempLabel(NULL);
4395 if ( IC_TRUE(ifx) ) {
4396 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4397 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4399 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4400 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4402 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4405 /* They're not both bit variables. Is the right a literal? */
4406 if(AOP_TYPE(right) == AOP_LIT) {
4407 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4412 switch(lit & 0xff) {
4414 if ( IC_TRUE(ifx) ) {
4415 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4417 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4419 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4420 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4424 if ( IC_TRUE(ifx) ) {
4425 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4427 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4429 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4430 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4434 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4436 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4441 /* end of size == 1 */
4445 genc16bit2lit(left,lit,offset);
4448 /* end of size == 2 */
4453 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4454 emitpcode(POC_IORFW,popGet(AOP(left),1));
4455 emitpcode(POC_IORFW,popGet(AOP(left),2));
4456 emitpcode(POC_IORFW,popGet(AOP(left),3));
4460 /* search for patterns that can be optimized */
4462 genc16bit2lit(left,lit,0);
4465 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4467 genc16bit2lit(left,lit,2);
4469 emitpcode(POC_IORFW,popGet(AOP(left),2));
4470 emitpcode(POC_IORFW,popGet(AOP(left),3));
4483 } else if(AOP_TYPE(right) == AOP_CRY ) {
4484 /* we know the left is not a bit, but that the right is */
4485 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4486 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4487 popGet(AOP(right),offset));
4488 emitpcode(POC_XORLW,popGetLit(1));
4490 /* if the two are equal, then W will be 0 and the Z bit is set
4491 * we could test Z now, or go ahead and check the high order bytes if
4492 * the variable we're comparing is larger than a byte. */
4495 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4497 if ( IC_TRUE(ifx) ) {
4499 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4500 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4503 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4504 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4508 /* They're both variables that are larger than bits */
4511 tlbl = newiTempLabel(NULL);
4514 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4515 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4517 if ( IC_TRUE(ifx) ) {
4520 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4521 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4524 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4525 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4529 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4530 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4534 if(s>1 && IC_TRUE(ifx)) {
4535 emitpLabel(tlbl->key);
4536 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4540 /* mark the icode as generated */
4545 /* if they are both bit variables */
4546 if (AOP_TYPE(left) == AOP_CRY &&
4547 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4548 if(AOP_TYPE(right) == AOP_LIT){
4549 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4551 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4552 pic14_emitcode("cpl","c");
4553 } else if(lit == 1L) {
4554 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4556 pic14_emitcode("clr","c");
4558 /* AOP_TYPE(right) == AOP_CRY */
4560 symbol *lbl = newiTempLabel(NULL);
4561 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4562 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4563 pic14_emitcode("cpl","c");
4564 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4567 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4568 pic14_outBitC(result);
4572 genIfxJump (ifx,"c");
4575 /* if the result is used in an arithmetic operation
4576 then put the result in place */
4577 pic14_outBitC(result);
4580 gencjne(left,right,result,ifx);
4583 gencjne(left,right,newiTempLabel(NULL));
4585 if(IC_TRUE(ifx)->key)
4586 gencjne(left,right,IC_TRUE(ifx)->key);
4588 gencjne(left,right,IC_FALSE(ifx)->key);
4592 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4593 aopPut(AOP(result),"a",0);
4598 genIfxJump (ifx,"a");
4602 /* if the result is used in an arithmetic operation
4603 then put the result in place */
4605 if (AOP_TYPE(result) != AOP_CRY)
4606 pic14_outAcc(result);
4608 /* leave the result in acc */
4612 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4613 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4614 freeAsmop(result,NULL,ic,TRUE);
4617 /*-----------------------------------------------------------------*/
4618 /* ifxForOp - returns the icode containing the ifx for operand */
4619 /*-----------------------------------------------------------------*/
4620 static iCode *ifxForOp ( operand *op, iCode *ic )
4622 /* if true symbol then needs to be assigned */
4623 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4624 if (IS_TRUE_SYMOP(op))
4627 /* if this has register type condition and
4628 the next instruction is ifx with the same operand
4629 and live to of the operand is upto the ifx only then */
4631 ic->next->op == IFX &&
4632 IC_COND(ic->next)->key == op->key &&
4633 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4637 ic->next->op == IFX &&
4638 IC_COND(ic->next)->key == op->key) {
4639 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4643 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4645 ic->next->op == IFX)
4646 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4649 ic->next->op == IFX &&
4650 IC_COND(ic->next)->key == op->key) {
4651 DEBUGpic14_emitcode ("; "," key is okay");
4652 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4653 OP_SYMBOL(op)->liveTo,
4660 /*-----------------------------------------------------------------*/
4661 /* genAndOp - for && operation */
4662 /*-----------------------------------------------------------------*/
4663 static void genAndOp (iCode *ic)
4665 operand *left,*right, *result;
4668 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4669 /* note here that && operations that are in an
4670 if statement are taken away by backPatchLabels
4671 only those used in arthmetic operations remain */
4672 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4673 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4674 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4676 /* if both are bit variables */
4677 if (AOP_TYPE(left) == AOP_CRY &&
4678 AOP_TYPE(right) == AOP_CRY ) {
4679 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4680 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4681 pic14_outBitC(result);
4683 tlbl = newiTempLabel(NULL);
4684 pic14_toBoolean(left);
4685 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4686 pic14_toBoolean(right);
4687 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4688 pic14_outBitAcc(result);
4691 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4692 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4693 freeAsmop(result,NULL,ic,TRUE);
4697 /*-----------------------------------------------------------------*/
4698 /* genOrOp - for || operation */
4699 /*-----------------------------------------------------------------*/
4702 modified this code, but it doesn't appear to ever get called
4705 static void genOrOp (iCode *ic)
4707 operand *left,*right, *result;
4710 /* note here that || operations that are in an
4711 if statement are taken away by backPatchLabels
4712 only those used in arthmetic operations remain */
4713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4714 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4715 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4716 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4718 DEBUGpic14_AopType(__LINE__,left,right,result);
4720 /* if both are bit variables */
4721 if (AOP_TYPE(left) == AOP_CRY &&
4722 AOP_TYPE(right) == AOP_CRY ) {
4723 pic14_emitcode("clrc","");
4724 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4725 AOP(left)->aopu.aop_dir,
4726 AOP(left)->aopu.aop_dir);
4727 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4728 AOP(right)->aopu.aop_dir,
4729 AOP(right)->aopu.aop_dir);
4730 pic14_emitcode("setc","");
4733 tlbl = newiTempLabel(NULL);
4734 pic14_toBoolean(left);
4736 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4737 pic14_toBoolean(right);
4738 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4740 pic14_outBitAcc(result);
4743 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4744 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4745 freeAsmop(result,NULL,ic,TRUE);
4748 /*-----------------------------------------------------------------*/
4749 /* isLiteralBit - test if lit == 2^n */
4750 /*-----------------------------------------------------------------*/
4751 static int isLiteralBit(unsigned long lit)
4753 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4754 0x100L,0x200L,0x400L,0x800L,
4755 0x1000L,0x2000L,0x4000L,0x8000L,
4756 0x10000L,0x20000L,0x40000L,0x80000L,
4757 0x100000L,0x200000L,0x400000L,0x800000L,
4758 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4759 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4763 for(idx = 0; idx < 32; idx++)
4769 /*-----------------------------------------------------------------*/
4770 /* continueIfTrue - */
4771 /*-----------------------------------------------------------------*/
4772 static void continueIfTrue (iCode *ic)
4774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4776 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4780 /*-----------------------------------------------------------------*/
4782 /*-----------------------------------------------------------------*/
4783 static void jumpIfTrue (iCode *ic)
4785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4787 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4791 /*-----------------------------------------------------------------*/
4792 /* jmpTrueOrFalse - */
4793 /*-----------------------------------------------------------------*/
4794 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4796 // ugly but optimized by peephole
4797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4799 symbol *nlbl = newiTempLabel(NULL);
4800 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4801 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4802 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4803 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4806 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4807 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4812 /*-----------------------------------------------------------------*/
4813 /* genAnd - code for and */
4814 /*-----------------------------------------------------------------*/
4815 static void genAnd (iCode *ic, iCode *ifx)
4817 operand *left, *right, *result;
4819 unsigned long lit = 0L;
4824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4825 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4826 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4827 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4829 resolveIfx(&rIfx,ifx);
4831 /* if left is a literal & right is not then exchange them */
4832 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4833 AOP_NEEDSACC(left)) {
4834 operand *tmp = right ;
4839 /* if result = right then exchange them */
4840 if(pic14_sameRegs(AOP(result),AOP(right))){
4841 operand *tmp = right ;
4846 /* if right is bit then exchange them */
4847 if (AOP_TYPE(right) == AOP_CRY &&
4848 AOP_TYPE(left) != AOP_CRY){
4849 operand *tmp = right ;
4853 if(AOP_TYPE(right) == AOP_LIT)
4854 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4856 size = AOP_SIZE(result);
4858 DEBUGpic14_AopType(__LINE__,left,right,result);
4861 // result = bit & yy;
4862 if (AOP_TYPE(left) == AOP_CRY){
4863 // c = bit & literal;
4864 if(AOP_TYPE(right) == AOP_LIT){
4866 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4869 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4872 if(size && (AOP_TYPE(result) == AOP_CRY)){
4873 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4876 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4880 pic14_emitcode("clr","c");
4883 if (AOP_TYPE(right) == AOP_CRY){
4885 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4886 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4889 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4891 pic14_emitcode("rrc","a");
4892 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4898 pic14_outBitC(result);
4900 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4901 genIfxJump(ifx, "c");
4905 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4906 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4907 if((AOP_TYPE(right) == AOP_LIT) &&
4908 (AOP_TYPE(result) == AOP_CRY) &&
4909 (AOP_TYPE(left) != AOP_CRY)){
4910 int posbit = isLiteralBit(lit);
4914 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4917 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4923 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4924 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4926 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4927 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4930 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4931 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4932 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4939 symbol *tlbl = newiTempLabel(NULL);
4940 int sizel = AOP_SIZE(left);
4942 pic14_emitcode("setb","c");
4944 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4945 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4947 if((posbit = isLiteralBit(bytelit)) != 0)
4948 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4950 if(bytelit != 0x0FFL)
4951 pic14_emitcode("anl","a,%s",
4952 aopGet(AOP(right),offset,FALSE,TRUE));
4953 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4958 // bit = left & literal
4960 pic14_emitcode("clr","c");
4961 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4963 // if(left & literal)
4966 jmpTrueOrFalse(ifx, tlbl);
4970 pic14_outBitC(result);
4974 /* if left is same as result */
4975 if(pic14_sameRegs(AOP(result),AOP(left))){
4977 for(;size--; offset++,lit>>=8) {
4978 if(AOP_TYPE(right) == AOP_LIT){
4979 switch(lit & 0xff) {
4981 /* and'ing with 0 has clears the result */
4982 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4983 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4986 /* and'ing with 0xff is a nop when the result and left are the same */
4991 int p = my_powof2( (~lit) & 0xff );
4993 /* only one bit is set in the literal, so use a bcf instruction */
4994 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4995 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4998 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4999 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5000 if(know_W != (lit&0xff))
5001 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5003 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5008 if (AOP_TYPE(left) == AOP_ACC) {
5009 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5011 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5012 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5019 // left & result in different registers
5020 if(AOP_TYPE(result) == AOP_CRY){
5022 // if(size), result in bit
5023 // if(!size && ifx), conditional oper: if(left & right)
5024 symbol *tlbl = newiTempLabel(NULL);
5025 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5027 pic14_emitcode("setb","c");
5029 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5030 pic14_emitcode("anl","a,%s",
5031 aopGet(AOP(left),offset,FALSE,FALSE));
5032 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5037 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5038 pic14_outBitC(result);
5040 jmpTrueOrFalse(ifx, tlbl);
5042 for(;(size--);offset++) {
5044 // result = left & right
5045 if(AOP_TYPE(right) == AOP_LIT){
5046 int t = (lit >> (offset*8)) & 0x0FFL;
5049 pic14_emitcode("clrf","%s",
5050 aopGet(AOP(result),offset,FALSE,FALSE));
5051 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5054 pic14_emitcode("movf","%s,w",
5055 aopGet(AOP(left),offset,FALSE,FALSE));
5056 pic14_emitcode("movwf","%s",
5057 aopGet(AOP(result),offset,FALSE,FALSE));
5058 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5059 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5062 pic14_emitcode("movlw","0x%x",t);
5063 pic14_emitcode("andwf","%s,w",
5064 aopGet(AOP(left),offset,FALSE,FALSE));
5065 pic14_emitcode("movwf","%s",
5066 aopGet(AOP(result),offset,FALSE,FALSE));
5068 emitpcode(POC_MOVLW, popGetLit(t));
5069 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5070 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5075 if (AOP_TYPE(left) == AOP_ACC) {
5076 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5077 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5079 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5080 pic14_emitcode("andwf","%s,w",
5081 aopGet(AOP(left),offset,FALSE,FALSE));
5082 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5083 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5085 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5086 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5092 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5093 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5094 freeAsmop(result,NULL,ic,TRUE);
5097 /*-----------------------------------------------------------------*/
5098 /* genOr - code for or */
5099 /*-----------------------------------------------------------------*/
5100 static void genOr (iCode *ic, iCode *ifx)
5102 operand *left, *right, *result;
5104 unsigned long lit = 0L;
5106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5108 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5109 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5110 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5112 DEBUGpic14_AopType(__LINE__,left,right,result);
5114 /* if left is a literal & right is not then exchange them */
5115 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5116 AOP_NEEDSACC(left)) {
5117 operand *tmp = right ;
5122 /* if result = right then exchange them */
5123 if(pic14_sameRegs(AOP(result),AOP(right))){
5124 operand *tmp = right ;
5129 /* if right is bit then exchange them */
5130 if (AOP_TYPE(right) == AOP_CRY &&
5131 AOP_TYPE(left) != AOP_CRY){
5132 operand *tmp = right ;
5137 DEBUGpic14_AopType(__LINE__,left,right,result);
5139 if(AOP_TYPE(right) == AOP_LIT)
5140 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5142 size = AOP_SIZE(result);
5146 if (AOP_TYPE(left) == AOP_CRY){
5147 if(AOP_TYPE(right) == AOP_LIT){
5148 // c = bit & literal;
5150 // lit != 0 => result = 1
5151 if(AOP_TYPE(result) == AOP_CRY){
5153 emitpcode(POC_BSF, popGet(AOP(result),0));
5154 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5155 // AOP(result)->aopu.aop_dir,
5156 // AOP(result)->aopu.aop_dir);
5158 continueIfTrue(ifx);
5162 // lit == 0 => result = left
5163 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5165 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5168 if (AOP_TYPE(right) == AOP_CRY){
5169 if(pic14_sameRegs(AOP(result),AOP(left))){
5171 emitpcode(POC_BCF, popGet(AOP(result),0));
5172 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5173 emitpcode(POC_BSF, popGet(AOP(result),0));
5175 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5176 AOP(result)->aopu.aop_dir,
5177 AOP(result)->aopu.aop_dir);
5178 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5179 AOP(right)->aopu.aop_dir,
5180 AOP(right)->aopu.aop_dir);
5181 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5182 AOP(result)->aopu.aop_dir,
5183 AOP(result)->aopu.aop_dir);
5185 if( AOP_TYPE(result) == AOP_ACC) {
5186 emitpcode(POC_MOVLW, popGetLit(0));
5187 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5188 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5189 emitpcode(POC_MOVLW, popGetLit(1));
5193 emitpcode(POC_BCF, popGet(AOP(result),0));
5194 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5195 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5196 emitpcode(POC_BSF, popGet(AOP(result),0));
5198 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5199 AOP(result)->aopu.aop_dir,
5200 AOP(result)->aopu.aop_dir);
5201 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5202 AOP(right)->aopu.aop_dir,
5203 AOP(right)->aopu.aop_dir);
5204 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5205 AOP(left)->aopu.aop_dir,
5206 AOP(left)->aopu.aop_dir);
5207 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5208 AOP(result)->aopu.aop_dir,
5209 AOP(result)->aopu.aop_dir);
5214 symbol *tlbl = newiTempLabel(NULL);
5215 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5218 emitpcode(POC_BCF, popGet(AOP(result),0));
5219 if( AOP_TYPE(right) == AOP_ACC) {
5220 emitpcode(POC_IORLW, popGetLit(0));
5222 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5223 emitpcode(POC_BSF, popGet(AOP(result),0));
5228 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5229 pic14_emitcode(";XXX setb","c");
5230 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5231 AOP(left)->aopu.aop_dir,tlbl->key+100);
5232 pic14_toBoolean(right);
5233 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5234 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5235 jmpTrueOrFalse(ifx, tlbl);
5239 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5246 pic14_outBitC(result);
5248 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5249 genIfxJump(ifx, "c");
5253 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5254 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5255 if((AOP_TYPE(right) == AOP_LIT) &&
5256 (AOP_TYPE(result) == AOP_CRY) &&
5257 (AOP_TYPE(left) != AOP_CRY)){
5259 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5262 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5264 continueIfTrue(ifx);
5267 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5268 // lit = 0, result = boolean(left)
5270 pic14_emitcode(";XXX setb","c");
5271 pic14_toBoolean(right);
5273 symbol *tlbl = newiTempLabel(NULL);
5274 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5276 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5278 genIfxJump (ifx,"a");
5282 pic14_outBitC(result);
5286 /* if left is same as result */
5287 if(pic14_sameRegs(AOP(result),AOP(left))){
5289 for(;size--; offset++,lit>>=8) {
5290 if(AOP_TYPE(right) == AOP_LIT){
5291 if((lit & 0xff) == 0)
5292 /* or'ing with 0 has no effect */
5295 int p = my_powof2(lit & 0xff);
5297 /* only one bit is set in the literal, so use a bsf instruction */
5299 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5301 if(know_W != (lit & 0xff))
5302 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5303 know_W = lit & 0xff;
5304 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5309 if (AOP_TYPE(left) == AOP_ACC) {
5310 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5311 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5313 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5314 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5316 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5317 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5323 // left & result in different registers
5324 if(AOP_TYPE(result) == AOP_CRY){
5326 // if(size), result in bit
5327 // if(!size && ifx), conditional oper: if(left | right)
5328 symbol *tlbl = newiTempLabel(NULL);
5329 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5330 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5334 pic14_emitcode(";XXX setb","c");
5336 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5337 pic14_emitcode(";XXX orl","a,%s",
5338 aopGet(AOP(left),offset,FALSE,FALSE));
5339 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5344 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5345 pic14_outBitC(result);
5347 jmpTrueOrFalse(ifx, tlbl);
5348 } else for(;(size--);offset++){
5350 // result = left & right
5351 if(AOP_TYPE(right) == AOP_LIT){
5352 int t = (lit >> (offset*8)) & 0x0FFL;
5355 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5356 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5358 pic14_emitcode("movf","%s,w",
5359 aopGet(AOP(left),offset,FALSE,FALSE));
5360 pic14_emitcode("movwf","%s",
5361 aopGet(AOP(result),offset,FALSE,FALSE));
5364 emitpcode(POC_MOVLW, popGetLit(t));
5365 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5366 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5368 pic14_emitcode("movlw","0x%x",t);
5369 pic14_emitcode("iorwf","%s,w",
5370 aopGet(AOP(left),offset,FALSE,FALSE));
5371 pic14_emitcode("movwf","%s",
5372 aopGet(AOP(result),offset,FALSE,FALSE));
5378 // faster than result <- left, anl result,right
5379 // and better if result is SFR
5380 if (AOP_TYPE(left) == AOP_ACC) {
5381 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5382 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5384 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5385 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5387 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5388 pic14_emitcode("iorwf","%s,w",
5389 aopGet(AOP(left),offset,FALSE,FALSE));
5391 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5392 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5397 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5398 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5399 freeAsmop(result,NULL,ic,TRUE);
5402 /*-----------------------------------------------------------------*/
5403 /* genXor - code for xclusive or */
5404 /*-----------------------------------------------------------------*/
5405 static void genXor (iCode *ic, iCode *ifx)
5407 operand *left, *right, *result;
5409 unsigned long lit = 0L;
5411 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5413 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5414 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5415 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5417 /* if left is a literal & right is not ||
5418 if left needs acc & right does not */
5419 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5420 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5421 operand *tmp = right ;
5426 /* if result = right then exchange them */
5427 if(pic14_sameRegs(AOP(result),AOP(right))){
5428 operand *tmp = right ;
5433 /* if right is bit then exchange them */
5434 if (AOP_TYPE(right) == AOP_CRY &&
5435 AOP_TYPE(left) != AOP_CRY){
5436 operand *tmp = right ;
5440 if(AOP_TYPE(right) == AOP_LIT)
5441 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5443 size = AOP_SIZE(result);
5447 if (AOP_TYPE(left) == AOP_CRY){
5448 if(AOP_TYPE(right) == AOP_LIT){
5449 // c = bit & literal;
5451 // lit>>1 != 0 => result = 1
5452 if(AOP_TYPE(result) == AOP_CRY){
5454 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5456 continueIfTrue(ifx);
5459 pic14_emitcode("setb","c");
5463 // lit == 0, result = left
5464 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5466 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5468 // lit == 1, result = not(left)
5469 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5470 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5473 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5474 pic14_emitcode("cpl","c");
5481 symbol *tlbl = newiTempLabel(NULL);
5482 if (AOP_TYPE(right) == AOP_CRY){
5484 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5487 int sizer = AOP_SIZE(right);
5489 // if val>>1 != 0, result = 1
5490 pic14_emitcode("setb","c");
5492 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5494 // test the msb of the lsb
5495 pic14_emitcode("anl","a,#0xfe");
5496 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5500 pic14_emitcode("rrc","a");
5502 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5503 pic14_emitcode("cpl","c");
5504 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5509 pic14_outBitC(result);
5511 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5512 genIfxJump(ifx, "c");
5516 if(pic14_sameRegs(AOP(result),AOP(left))){
5517 /* if left is same as result */
5518 for(;size--; offset++) {
5519 if(AOP_TYPE(right) == AOP_LIT){
5520 int t = (lit >> (offset*8)) & 0x0FFL;
5524 if (IS_AOP_PREG(left)) {
5525 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5526 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5527 aopPut(AOP(result),"a",offset);
5529 emitpcode(POC_MOVLW, popGetLit(t));
5530 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5531 pic14_emitcode("xrl","%s,%s",
5532 aopGet(AOP(left),offset,FALSE,TRUE),
5533 aopGet(AOP(right),offset,FALSE,FALSE));
5536 if (AOP_TYPE(left) == AOP_ACC)
5537 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5539 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5540 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5542 if (IS_AOP_PREG(left)) {
5543 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5544 aopPut(AOP(result),"a",offset);
5546 pic14_emitcode("xrl","%s,a",
5547 aopGet(AOP(left),offset,FALSE,TRUE));
5553 // left & result in different registers
5554 if(AOP_TYPE(result) == AOP_CRY){
5556 // if(size), result in bit
5557 // if(!size && ifx), conditional oper: if(left ^ right)
5558 symbol *tlbl = newiTempLabel(NULL);
5559 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5561 pic14_emitcode("setb","c");
5563 if((AOP_TYPE(right) == AOP_LIT) &&
5564 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5565 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5567 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5568 pic14_emitcode("xrl","a,%s",
5569 aopGet(AOP(left),offset,FALSE,FALSE));
5571 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5576 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5577 pic14_outBitC(result);
5579 jmpTrueOrFalse(ifx, tlbl);
5580 } else for(;(size--);offset++){
5582 // result = left & right
5583 if(AOP_TYPE(right) == AOP_LIT){
5584 int t = (lit >> (offset*8)) & 0x0FFL;
5587 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5588 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5589 pic14_emitcode("movf","%s,w",
5590 aopGet(AOP(left),offset,FALSE,FALSE));
5591 pic14_emitcode("movwf","%s",
5592 aopGet(AOP(result),offset,FALSE,FALSE));
5595 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5596 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5597 pic14_emitcode("comf","%s,w",
5598 aopGet(AOP(left),offset,FALSE,FALSE));
5599 pic14_emitcode("movwf","%s",
5600 aopGet(AOP(result),offset,FALSE,FALSE));
5603 emitpcode(POC_MOVLW, popGetLit(t));
5604 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5605 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5606 pic14_emitcode("movlw","0x%x",t);
5607 pic14_emitcode("xorwf","%s,w",
5608 aopGet(AOP(left),offset,FALSE,FALSE));
5609 pic14_emitcode("movwf","%s",
5610 aopGet(AOP(result),offset,FALSE,FALSE));
5616 // faster than result <- left, anl result,right
5617 // and better if result is SFR
5618 if (AOP_TYPE(left) == AOP_ACC) {
5619 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5620 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5622 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5623 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5624 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5625 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5627 if ( AOP_TYPE(result) != AOP_ACC){
5628 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5629 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5635 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5636 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5637 freeAsmop(result,NULL,ic,TRUE);
5640 /*-----------------------------------------------------------------*/
5641 /* genInline - write the inline code out */
5642 /*-----------------------------------------------------------------*/
5643 static void genInline (iCode *ic)
5645 char *buffer, *bp, *bp1;
5647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5649 _G.inLine += (!options.asmpeep);
5651 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5652 strcpy(buffer,IC_INLINE(ic));
5654 /* emit each line as a code */
5658 pic14_emitcode(bp1,"");
5665 pic14_emitcode(bp1,"");
5672 pic14_emitcode(bp1,"");
5673 /* pic14_emitcode("",buffer); */
5674 _G.inLine -= (!options.asmpeep);
5677 /*-----------------------------------------------------------------*/
5678 /* genRRC - rotate right with carry */
5679 /*-----------------------------------------------------------------*/
5680 static void genRRC (iCode *ic)
5682 operand *left , *result ;
5683 int size, offset = 0, same;
5685 /* rotate right with carry */
5687 result=IC_RESULT(ic);
5688 aopOp (left,ic,FALSE);
5689 aopOp (result,ic,FALSE);
5691 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5693 same = pic14_sameRegs(AOP(result),AOP(left));
5695 size = AOP_SIZE(result);
5697 /* get the lsb and put it into the carry */
5698 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5705 emitpcode(POC_RRF, popGet(AOP(left),offset));
5707 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5708 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5714 freeAsmop(left,NULL,ic,TRUE);
5715 freeAsmop(result,NULL,ic,TRUE);
5718 /*-----------------------------------------------------------------*/
5719 /* genRLC - generate code for rotate left with carry */
5720 /*-----------------------------------------------------------------*/
5721 static void genRLC (iCode *ic)
5723 operand *left , *result ;
5724 int size, offset = 0;
5727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5728 /* rotate right with carry */
5730 result=IC_RESULT(ic);
5731 aopOp (left,ic,FALSE);
5732 aopOp (result,ic,FALSE);
5734 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5736 same = pic14_sameRegs(AOP(result),AOP(left));
5738 /* move it to the result */
5739 size = AOP_SIZE(result);
5741 /* get the msb and put it into the carry */
5742 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5749 emitpcode(POC_RLF, popGet(AOP(left),offset));
5751 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5752 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5759 freeAsmop(left,NULL,ic,TRUE);
5760 freeAsmop(result,NULL,ic,TRUE);
5763 /*-----------------------------------------------------------------*/
5764 /* genGetHbit - generates code get highest order bit */
5765 /*-----------------------------------------------------------------*/
5766 static void genGetHbit (iCode *ic)
5768 operand *left, *result;
5770 result=IC_RESULT(ic);
5771 aopOp (left,ic,FALSE);
5772 aopOp (result,ic,FALSE);
5774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5775 /* get the highest order byte into a */
5776 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5777 if(AOP_TYPE(result) == AOP_CRY){
5778 pic14_emitcode("rlc","a");
5779 pic14_outBitC(result);
5782 pic14_emitcode("rl","a");
5783 pic14_emitcode("anl","a,#0x01");
5784 pic14_outAcc(result);
5788 freeAsmop(left,NULL,ic,TRUE);
5789 freeAsmop(result,NULL,ic,TRUE);
5792 /*-----------------------------------------------------------------*/
5793 /* AccRol - rotate left accumulator by known count */
5794 /*-----------------------------------------------------------------*/
5795 static void AccRol (int shCount)
5797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5798 shCount &= 0x0007; // shCount : 0..7
5803 pic14_emitcode("rl","a");
5806 pic14_emitcode("rl","a");
5807 pic14_emitcode("rl","a");
5810 pic14_emitcode("swap","a");
5811 pic14_emitcode("rr","a");
5814 pic14_emitcode("swap","a");
5817 pic14_emitcode("swap","a");
5818 pic14_emitcode("rl","a");
5821 pic14_emitcode("rr","a");
5822 pic14_emitcode("rr","a");
5825 pic14_emitcode("rr","a");
5830 /*-----------------------------------------------------------------*/
5831 /* AccLsh - left shift accumulator by known count */
5832 /*-----------------------------------------------------------------*/
5833 static void AccLsh (int shCount)
5835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5838 pic14_emitcode("add","a,acc");
5841 pic14_emitcode("add","a,acc");
5842 pic14_emitcode("add","a,acc");
5844 /* rotate left accumulator */
5846 /* and kill the lower order bits */
5847 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5852 /*-----------------------------------------------------------------*/
5853 /* AccRsh - right shift accumulator by known count */
5854 /*-----------------------------------------------------------------*/
5855 static void AccRsh (int shCount)
5857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5861 pic14_emitcode("rrc","a");
5863 /* rotate right accumulator */
5864 AccRol(8 - shCount);
5865 /* and kill the higher order bits */
5866 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5872 /*-----------------------------------------------------------------*/
5873 /* AccSRsh - signed right shift accumulator by known count */
5874 /*-----------------------------------------------------------------*/
5875 static void AccSRsh (int shCount)
5878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5881 pic14_emitcode("mov","c,acc.7");
5882 pic14_emitcode("rrc","a");
5883 } else if(shCount == 2){
5884 pic14_emitcode("mov","c,acc.7");
5885 pic14_emitcode("rrc","a");
5886 pic14_emitcode("mov","c,acc.7");
5887 pic14_emitcode("rrc","a");
5889 tlbl = newiTempLabel(NULL);
5890 /* rotate right accumulator */
5891 AccRol(8 - shCount);
5892 /* and kill the higher order bits */
5893 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5894 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5895 pic14_emitcode("orl","a,#0x%02x",
5896 (unsigned char)~SRMask[shCount]);
5897 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5902 /*-----------------------------------------------------------------*/
5903 /* shiftR1Left2Result - shift right one byte from left to result */
5904 /*-----------------------------------------------------------------*/
5905 static void shiftR1Left2ResultSigned (operand *left, int offl,
5906 operand *result, int offr,
5911 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5913 same = (left == result) || (AOP(left) == AOP(result));
5917 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5919 emitpcode(POC_RRF, popGet(AOP(result),offr));
5921 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5922 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5932 /*-----------------------------------------------------------------*/
5933 /* shiftR1Left2Result - shift right one byte from left to result */
5934 /*-----------------------------------------------------------------*/
5935 static void shiftR1Left2Result (operand *left, int offl,
5936 operand *result, int offr,
5937 int shCount, int sign)
5941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5943 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5945 /* Copy the msb into the carry if signed. */
5947 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5957 emitpcode(POC_RRF, popGet(AOP(result),offr));
5959 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5960 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5966 emitpcode(POC_RRF, popGet(AOP(result),offr));
5968 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5969 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5972 emitpcode(POC_RRF, popGet(AOP(result),offr));
5977 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5979 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5980 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5983 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5984 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5985 emitpcode(POC_ANDLW, popGetLit(0x1f));
5986 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5990 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5991 emitpcode(POC_ANDLW, popGetLit(0x0f));
5992 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5996 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5997 emitpcode(POC_ANDLW, popGetLit(0x0f));
5998 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6000 emitpcode(POC_RRF, popGet(AOP(result),offr));
6005 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6006 emitpcode(POC_ANDLW, popGetLit(0x80));
6007 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6008 emitpcode(POC_RLF, popGet(AOP(result),offr));
6009 emitpcode(POC_RLF, popGet(AOP(result),offr));
6014 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6015 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6016 emitpcode(POC_RLF, popGet(AOP(result),offr));
6027 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6029 /* shift right accumulator */
6034 aopPut(AOP(result),"a",offr);
6038 /*-----------------------------------------------------------------*/
6039 /* shiftL1Left2Result - shift left one byte from left to result */
6040 /*-----------------------------------------------------------------*/
6041 static void shiftL1Left2Result (operand *left, int offl,
6042 operand *result, int offr, int shCount)
6047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6049 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6050 DEBUGpic14_emitcode ("; ***","same = %d",same);
6051 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6053 /* shift left accumulator */
6054 //AccLsh(shCount); // don't comment out just yet...
6055 // aopPut(AOP(result),"a",offr);
6059 /* Shift left 1 bit position */
6060 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6062 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6064 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6065 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6069 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6070 emitpcode(POC_ANDLW,popGetLit(0x7e));
6071 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6072 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6075 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6076 emitpcode(POC_ANDLW,popGetLit(0x3e));
6077 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6078 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6079 emitpcode(POC_RLF, popGet(AOP(result),offr));
6082 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6083 emitpcode(POC_ANDLW, popGetLit(0xf0));
6084 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6087 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6088 emitpcode(POC_ANDLW, popGetLit(0xf0));
6089 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6090 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6093 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6094 emitpcode(POC_ANDLW, popGetLit(0x30));
6095 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6096 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6097 emitpcode(POC_RLF, popGet(AOP(result),offr));
6100 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6101 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6102 emitpcode(POC_RRF, popGet(AOP(result),offr));
6106 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6111 /*-----------------------------------------------------------------*/
6112 /* movLeft2Result - move byte from left to result */
6113 /*-----------------------------------------------------------------*/
6114 static void movLeft2Result (operand *left, int offl,
6115 operand *result, int offr, int sign)
6118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6119 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6120 l = aopGet(AOP(left),offl,FALSE,FALSE);
6122 if (*l == '@' && (IS_AOP_PREG(result))) {
6123 pic14_emitcode("mov","a,%s",l);
6124 aopPut(AOP(result),"a",offr);
6127 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6128 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6130 //aopPut(AOP(result),l,offr);
6132 /* MSB sign in acc.7 ! */
6133 if(pic14_getDataSize(left) == offl+1){
6134 pic14_emitcode("mov","a,%s",l);
6135 aopPut(AOP(result),"a",offr);
6142 /*-----------------------------------------------------------------*/
6143 /* shiftL2Left2Result - shift left two bytes from left to result */
6144 /*-----------------------------------------------------------------*/
6145 static void shiftL2Left2Result (operand *left, int offl,
6146 operand *result, int offr, int shCount)
6150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6152 if(pic14_sameRegs(AOP(result), AOP(left))) {
6160 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6161 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6162 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6166 emitpcode(POC_RLF, popGet(AOP(result),offr));
6167 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6173 emitpcode(POC_MOVLW, popGetLit(0x0f));
6174 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6175 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6176 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6177 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6178 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6179 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6181 emitpcode(POC_RLF, popGet(AOP(result),offr));
6182 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6186 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6187 emitpcode(POC_RRF, popGet(AOP(result),offr));
6188 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6189 emitpcode(POC_RRF, popGet(AOP(result),offr));
6190 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6191 emitpcode(POC_ANDLW,popGetLit(0xc0));
6192 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6193 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6194 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6195 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6198 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6199 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6200 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6201 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6202 emitpcode(POC_RRF, popGet(AOP(result),offr));
6212 /* note, use a mov/add for the shift since the mov has a
6213 chance of getting optimized out */
6214 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6215 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6216 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6217 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6218 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6222 emitpcode(POC_RLF, popGet(AOP(result),offr));
6223 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6229 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6230 emitpcode(POC_ANDLW, popGetLit(0xF0));
6231 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6232 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6233 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6234 emitpcode(POC_ANDLW, popGetLit(0xF0));
6235 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6236 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6240 emitpcode(POC_RLF, popGet(AOP(result),offr));
6241 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6245 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6246 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6247 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6248 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6250 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6251 emitpcode(POC_RRF, popGet(AOP(result),offr));
6252 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6253 emitpcode(POC_ANDLW,popGetLit(0xc0));
6254 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6255 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6256 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6257 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6260 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6261 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6262 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6263 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6264 emitpcode(POC_RRF, popGet(AOP(result),offr));
6269 /*-----------------------------------------------------------------*/
6270 /* shiftR2Left2Result - shift right two bytes from left to result */
6271 /*-----------------------------------------------------------------*/
6272 static void shiftR2Left2Result (operand *left, int offl,
6273 operand *result, int offr,
6274 int shCount, int sign)
6278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6279 same = pic14_sameRegs(AOP(result), AOP(left));
6281 if(same && ((offl + MSB16) == offr)){
6283 /* don't crash result[offr] */
6284 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6285 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6287 movLeft2Result(left,offl, result, offr, 0);
6288 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6290 /* a:x >> shCount (x = lsb(result))*/
6293 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6295 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6305 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6306 emitpcode(POC_RRF,popGet(AOP(result),offr));
6309 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6310 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6311 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6312 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6317 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6318 emitpcode(POC_RRF,popGet(AOP(result),offr));
6325 emitpcode(POC_MOVLW, popGetLit(0xf0));
6326 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6327 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6329 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6330 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6331 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6332 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6334 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6335 emitpcode(POC_ANDLW, popGetLit(0x0f));
6336 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6338 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6339 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6340 emitpcode(POC_ANDLW, popGetLit(0xf0));
6341 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6342 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6346 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6347 emitpcode(POC_RRF, popGet(AOP(result),offr));
6355 emitpcode(POC_RLF, popGet(AOP(result),offr));
6356 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6358 emitpcode(POC_RLF, popGet(AOP(result),offr));
6359 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6360 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6361 emitpcode(POC_ANDLW,popGetLit(0x03));
6362 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6363 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6364 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6365 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6367 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6368 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6369 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6370 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6371 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6372 emitpcode(POC_RLF, popGet(AOP(result),offr));
6373 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6374 emitpcode(POC_ANDLW,popGetLit(0x03));
6375 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6380 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6381 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6382 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6383 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6384 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6389 /*-----------------------------------------------------------------*/
6390 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6391 /*-----------------------------------------------------------------*/
6392 static void shiftLLeftOrResult (operand *left, int offl,
6393 operand *result, int offr, int shCount)
6395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6396 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6397 /* shift left accumulator */
6399 /* or with result */
6400 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6401 /* back to result */
6402 aopPut(AOP(result),"a",offr);
6405 /*-----------------------------------------------------------------*/
6406 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6407 /*-----------------------------------------------------------------*/
6408 static void shiftRLeftOrResult (operand *left, int offl,
6409 operand *result, int offr, int shCount)
6411 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6412 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6413 /* shift right accumulator */
6415 /* or with result */
6416 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6417 /* back to result */
6418 aopPut(AOP(result),"a",offr);
6421 /*-----------------------------------------------------------------*/
6422 /* genlshOne - left shift a one byte quantity by known count */
6423 /*-----------------------------------------------------------------*/
6424 static void genlshOne (operand *result, operand *left, int shCount)
6426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6427 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6430 /*-----------------------------------------------------------------*/
6431 /* genlshTwo - left shift two bytes by known amount != 0 */
6432 /*-----------------------------------------------------------------*/
6433 static void genlshTwo (operand *result,operand *left, int shCount)
6437 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6438 size = pic14_getDataSize(result);
6440 /* if shCount >= 8 */
6446 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6448 movLeft2Result(left, LSB, result, MSB16, 0);
6450 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6453 /* 1 <= shCount <= 7 */
6456 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6458 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6462 /*-----------------------------------------------------------------*/
6463 /* shiftLLong - shift left one long from left to result */
6464 /* offl = LSB or MSB16 */
6465 /*-----------------------------------------------------------------*/
6466 static void shiftLLong (operand *left, operand *result, int offr )
6469 int size = AOP_SIZE(result);
6471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6472 if(size >= LSB+offr){
6473 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6475 pic14_emitcode("add","a,acc");
6476 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6477 size >= MSB16+offr && offr != LSB )
6478 pic14_emitcode("xch","a,%s",
6479 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6481 aopPut(AOP(result),"a",LSB+offr);
6484 if(size >= MSB16+offr){
6485 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6486 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6489 pic14_emitcode("rlc","a");
6490 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6491 size >= MSB24+offr && offr != LSB)
6492 pic14_emitcode("xch","a,%s",
6493 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6495 aopPut(AOP(result),"a",MSB16+offr);
6498 if(size >= MSB24+offr){
6499 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6500 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6503 pic14_emitcode("rlc","a");
6504 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6505 size >= MSB32+offr && offr != LSB )
6506 pic14_emitcode("xch","a,%s",
6507 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6509 aopPut(AOP(result),"a",MSB24+offr);
6512 if(size > MSB32+offr){
6513 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6514 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6517 pic14_emitcode("rlc","a");
6518 aopPut(AOP(result),"a",MSB32+offr);
6521 aopPut(AOP(result),zero,LSB);
6524 /*-----------------------------------------------------------------*/
6525 /* genlshFour - shift four byte by a known amount != 0 */
6526 /*-----------------------------------------------------------------*/
6527 static void genlshFour (operand *result, operand *left, int shCount)
6531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6532 size = AOP_SIZE(result);
6534 /* if shifting more that 3 bytes */
6535 if (shCount >= 24 ) {
6538 /* lowest order of left goes to the highest
6539 order of the destination */
6540 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6542 movLeft2Result(left, LSB, result, MSB32, 0);
6543 aopPut(AOP(result),zero,LSB);
6544 aopPut(AOP(result),zero,MSB16);
6545 aopPut(AOP(result),zero,MSB32);
6549 /* more than two bytes */
6550 else if ( shCount >= 16 ) {
6551 /* lower order two bytes goes to higher order two bytes */
6553 /* if some more remaining */
6555 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6557 movLeft2Result(left, MSB16, result, MSB32, 0);
6558 movLeft2Result(left, LSB, result, MSB24, 0);
6560 aopPut(AOP(result),zero,MSB16);
6561 aopPut(AOP(result),zero,LSB);
6565 /* if more than 1 byte */
6566 else if ( shCount >= 8 ) {
6567 /* lower order three bytes goes to higher order three bytes */
6571 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6573 movLeft2Result(left, LSB, result, MSB16, 0);
6575 else{ /* size = 4 */
6577 movLeft2Result(left, MSB24, result, MSB32, 0);
6578 movLeft2Result(left, MSB16, result, MSB24, 0);
6579 movLeft2Result(left, LSB, result, MSB16, 0);
6580 aopPut(AOP(result),zero,LSB);
6582 else if(shCount == 1)
6583 shiftLLong(left, result, MSB16);
6585 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6586 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6587 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6588 aopPut(AOP(result),zero,LSB);
6593 /* 1 <= shCount <= 7 */
6594 else if(shCount <= 2){
6595 shiftLLong(left, result, LSB);
6597 shiftLLong(result, result, LSB);
6599 /* 3 <= shCount <= 7, optimize */
6601 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6602 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6603 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6607 /*-----------------------------------------------------------------*/
6608 /* genLeftShiftLiteral - left shifting by known count */
6609 /*-----------------------------------------------------------------*/
6610 static void genLeftShiftLiteral (operand *left,
6615 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6618 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6619 freeAsmop(right,NULL,ic,TRUE);
6621 aopOp(left,ic,FALSE);
6622 aopOp(result,ic,FALSE);
6624 size = getSize(operandType(result));
6627 pic14_emitcode("; shift left ","result %d, left %d",size,
6631 /* I suppose that the left size >= result size */
6634 movLeft2Result(left, size, result, size, 0);
6638 else if(shCount >= (size * 8))
6640 aopPut(AOP(result),zero,size);
6644 genlshOne (result,left,shCount);
6649 genlshTwo (result,left,shCount);
6653 genlshFour (result,left,shCount);
6657 freeAsmop(left,NULL,ic,TRUE);
6658 freeAsmop(result,NULL,ic,TRUE);
6661 /*-----------------------------------------------------------------*/
6662 /* genLeftShift - generates code for left shifting */
6663 /*-----------------------------------------------------------------*/
6664 static void genLeftShift (iCode *ic)
6666 operand *left,*right, *result;
6669 symbol *tlbl , *tlbl1;
6671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6673 right = IC_RIGHT(ic);
6675 result = IC_RESULT(ic);
6677 aopOp(right,ic,FALSE);
6679 /* if the shift count is known then do it
6680 as efficiently as possible */
6681 if (AOP_TYPE(right) == AOP_LIT) {
6682 genLeftShiftLiteral (left,right,result,ic);
6686 /* shift count is unknown then we have to form
6687 a loop get the loop count in B : Note: we take
6688 only the lower order byte since shifting
6689 more that 32 bits make no sense anyway, ( the
6690 largest size of an object can be only 32 bits ) */
6693 aopOp(left,ic,FALSE);
6694 aopOp(result,ic,FALSE);
6696 /* now move the left to the result if they are not the
6698 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6699 AOP_SIZE(result) > 1) {
6701 size = AOP_SIZE(result);
6704 l = aopGet(AOP(left),offset,FALSE,TRUE);
6705 if (*l == '@' && (IS_AOP_PREG(result))) {
6707 pic14_emitcode("mov","a,%s",l);
6708 aopPut(AOP(result),"a",offset);
6710 aopPut(AOP(result),l,offset);
6715 size = AOP_SIZE(result);
6717 /* if it is only one byte then */
6719 if(optimized_for_speed) {
6720 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6721 emitpcode(POC_ANDLW, popGetLit(0xf0));
6722 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6723 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6724 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6725 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6726 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6727 emitpcode(POC_RLFW, popGet(AOP(result),0));
6728 emitpcode(POC_ANDLW, popGetLit(0xfe));
6729 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6730 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6731 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6734 tlbl = newiTempLabel(NULL);
6735 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6736 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6737 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6740 emitpcode(POC_COMFW, popGet(AOP(right),0));
6741 emitpcode(POC_RRF, popGet(AOP(result),0));
6742 emitpLabel(tlbl->key);
6743 emitpcode(POC_RLF, popGet(AOP(result),0));
6744 emitpcode(POC_ADDLW, popGetLit(1));
6746 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6752 tlbl = newiTempLabel(NULL);
6754 tlbl1 = newiTempLabel(NULL);
6756 reAdjustPreg(AOP(result));
6758 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6759 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6760 l = aopGet(AOP(result),offset,FALSE,FALSE);
6762 pic14_emitcode("add","a,acc");
6763 aopPut(AOP(result),"a",offset++);
6765 l = aopGet(AOP(result),offset,FALSE,FALSE);
6767 pic14_emitcode("rlc","a");
6768 aopPut(AOP(result),"a",offset++);
6770 reAdjustPreg(AOP(result));
6772 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6773 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6775 freeAsmop (right,NULL,ic,TRUE);
6776 freeAsmop(left,NULL,ic,TRUE);
6777 freeAsmop(result,NULL,ic,TRUE);
6780 /*-----------------------------------------------------------------*/
6781 /* genrshOne - right shift a one byte quantity by known count */
6782 /*-----------------------------------------------------------------*/
6783 static void genrshOne (operand *result, operand *left,
6784 int shCount, int sign)
6786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6787 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6790 /*-----------------------------------------------------------------*/
6791 /* genrshTwo - right shift two bytes by known amount != 0 */
6792 /*-----------------------------------------------------------------*/
6793 static void genrshTwo (operand *result,operand *left,
6794 int shCount, int sign)
6796 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6797 /* if shCount >= 8 */
6801 shiftR1Left2Result(left, MSB16, result, LSB,
6804 movLeft2Result(left, MSB16, result, LSB, sign);
6806 addSign(result, MSB16, sign);
6808 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6812 /* 1 <= shCount <= 7 */
6814 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6817 /*-----------------------------------------------------------------*/
6818 /* shiftRLong - shift right one long from left to result */
6819 /* offl = LSB or MSB16 */
6820 /*-----------------------------------------------------------------*/
6821 static void shiftRLong (operand *left, int offl,
6822 operand *result, int sign)
6824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6826 pic14_emitcode("clr","c");
6827 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6829 pic14_emitcode("mov","c,acc.7");
6830 pic14_emitcode("rrc","a");
6831 aopPut(AOP(result),"a",MSB32-offl);
6833 /* add sign of "a" */
6834 addSign(result, MSB32, sign);
6836 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6837 pic14_emitcode("rrc","a");
6838 aopPut(AOP(result),"a",MSB24-offl);
6840 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6841 pic14_emitcode("rrc","a");
6842 aopPut(AOP(result),"a",MSB16-offl);
6845 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6846 pic14_emitcode("rrc","a");
6847 aopPut(AOP(result),"a",LSB);
6851 /*-----------------------------------------------------------------*/
6852 /* genrshFour - shift four byte by a known amount != 0 */
6853 /*-----------------------------------------------------------------*/
6854 static void genrshFour (operand *result, operand *left,
6855 int shCount, int sign)
6857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6858 /* if shifting more that 3 bytes */
6859 if(shCount >= 24 ) {
6862 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6864 movLeft2Result(left, MSB32, result, LSB, sign);
6865 addSign(result, MSB16, sign);
6867 else if(shCount >= 16){
6870 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6872 movLeft2Result(left, MSB24, result, LSB, 0);
6873 movLeft2Result(left, MSB32, result, MSB16, sign);
6875 addSign(result, MSB24, sign);
6877 else if(shCount >= 8){
6880 shiftRLong(left, MSB16, result, sign);
6881 else if(shCount == 0){
6882 movLeft2Result(left, MSB16, result, LSB, 0);
6883 movLeft2Result(left, MSB24, result, MSB16, 0);
6884 movLeft2Result(left, MSB32, result, MSB24, sign);
6885 addSign(result, MSB32, sign);
6888 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6889 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6890 /* the last shift is signed */
6891 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6892 addSign(result, MSB32, sign);
6895 else{ /* 1 <= shCount <= 7 */
6897 shiftRLong(left, LSB, result, sign);
6899 shiftRLong(result, LSB, result, sign);
6902 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6903 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6904 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6909 /*-----------------------------------------------------------------*/
6910 /* genRightShiftLiteral - right shifting by known count */
6911 /*-----------------------------------------------------------------*/
6912 static void genRightShiftLiteral (operand *left,
6918 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6922 freeAsmop(right,NULL,ic,TRUE);
6924 aopOp(left,ic,FALSE);
6925 aopOp(result,ic,FALSE);
6928 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6932 size = pic14_getDataSize(left);
6933 /* test the LEFT size !!! */
6935 /* I suppose that the left size >= result size */
6937 size = pic14_getDataSize(result);
6939 movLeft2Result(left, size, result, size, 0);
6942 else if(shCount >= (size * 8)){
6944 /* get sign in acc.7 */
6945 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6946 addSign(result, LSB, sign);
6950 genrshOne (result,left,shCount,sign);
6954 genrshTwo (result,left,shCount,sign);
6958 genrshFour (result,left,shCount,sign);
6964 freeAsmop(left,NULL,ic,TRUE);
6965 freeAsmop(result,NULL,ic,TRUE);
6969 /*-----------------------------------------------------------------*/
6970 /* genSignedRightShift - right shift of signed number */
6971 /*-----------------------------------------------------------------*/
6972 static void genSignedRightShift (iCode *ic)
6974 operand *right, *left, *result;
6977 symbol *tlbl, *tlbl1 ;
6979 /* we do it the hard way put the shift count in b
6980 and loop thru preserving the sign */
6981 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6983 right = IC_RIGHT(ic);
6985 result = IC_RESULT(ic);
6987 aopOp(right,ic,FALSE);
6990 if ( AOP_TYPE(right) == AOP_LIT) {
6991 genRightShiftLiteral (left,right,result,ic,1);
6994 /* shift count is unknown then we have to form
6995 a loop get the loop count in B : Note: we take
6996 only the lower order byte since shifting
6997 more that 32 bits make no sense anyway, ( the
6998 largest size of an object can be only 32 bits ) */
7000 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7001 pic14_emitcode("inc","b");
7002 freeAsmop (right,NULL,ic,TRUE);
7003 aopOp(left,ic,FALSE);
7004 aopOp(result,ic,FALSE);
7006 /* now move the left to the result if they are not the
7008 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7009 AOP_SIZE(result) > 1) {
7011 size = AOP_SIZE(result);
7014 l = aopGet(AOP(left),offset,FALSE,TRUE);
7015 if (*l == '@' && IS_AOP_PREG(result)) {
7017 pic14_emitcode("mov","a,%s",l);
7018 aopPut(AOP(result),"a",offset);
7020 aopPut(AOP(result),l,offset);
7025 /* mov the highest order bit to OVR */
7026 tlbl = newiTempLabel(NULL);
7027 tlbl1= newiTempLabel(NULL);
7029 size = AOP_SIZE(result);
7031 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7032 pic14_emitcode("rlc","a");
7033 pic14_emitcode("mov","ov,c");
7034 /* if it is only one byte then */
7036 l = aopGet(AOP(left),0,FALSE,FALSE);
7038 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7039 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7040 pic14_emitcode("mov","c,ov");
7041 pic14_emitcode("rrc","a");
7042 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7043 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7044 aopPut(AOP(result),"a",0);
7048 reAdjustPreg(AOP(result));
7049 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7050 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7051 pic14_emitcode("mov","c,ov");
7053 l = aopGet(AOP(result),offset,FALSE,FALSE);
7055 pic14_emitcode("rrc","a");
7056 aopPut(AOP(result),"a",offset--);
7058 reAdjustPreg(AOP(result));
7059 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7060 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7063 freeAsmop(left,NULL,ic,TRUE);
7064 freeAsmop(result,NULL,ic,TRUE);
7067 /*-----------------------------------------------------------------*/
7068 /* genRightShift - generate code for right shifting */
7069 /*-----------------------------------------------------------------*/
7070 static void genRightShift (iCode *ic)
7072 operand *right, *left, *result;
7076 symbol *tlbl, *tlbl1 ;
7078 /* if signed then we do it the hard way preserve the
7079 sign bit moving it inwards */
7080 retype = getSpec(operandType(IC_RESULT(ic)));
7081 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7083 if (!SPEC_USIGN(retype)) {
7084 genSignedRightShift (ic);
7088 /* signed & unsigned types are treated the same : i.e. the
7089 signed is NOT propagated inwards : quoting from the
7090 ANSI - standard : "for E1 >> E2, is equivalent to division
7091 by 2**E2 if unsigned or if it has a non-negative value,
7092 otherwise the result is implementation defined ", MY definition
7093 is that the sign does not get propagated */
7095 right = IC_RIGHT(ic);
7097 result = IC_RESULT(ic);
7099 aopOp(right,ic,FALSE);
7101 /* if the shift count is known then do it
7102 as efficiently as possible */
7103 if (AOP_TYPE(right) == AOP_LIT) {
7104 genRightShiftLiteral (left,right,result,ic, 0);
7108 /* shift count is unknown then we have to form
7109 a loop get the loop count in B : Note: we take
7110 only the lower order byte since shifting
7111 more that 32 bits make no sense anyway, ( the
7112 largest size of an object can be only 32 bits ) */
7114 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7115 pic14_emitcode("inc","b");
7116 aopOp(left,ic,FALSE);
7117 aopOp(result,ic,FALSE);
7119 /* now move the left to the result if they are not the
7121 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7122 AOP_SIZE(result) > 1) {
7124 size = AOP_SIZE(result);
7127 l = aopGet(AOP(left),offset,FALSE,TRUE);
7128 if (*l == '@' && IS_AOP_PREG(result)) {
7130 pic14_emitcode("mov","a,%s",l);
7131 aopPut(AOP(result),"a",offset);
7133 aopPut(AOP(result),l,offset);
7138 tlbl = newiTempLabel(NULL);
7139 tlbl1= newiTempLabel(NULL);
7140 size = AOP_SIZE(result);
7143 /* if it is only one byte then */
7146 l = aopGet(AOP(left),0,FALSE,FALSE);
7148 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7149 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7151 pic14_emitcode("rrc","a");
7152 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7153 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7154 aopPut(AOP(result),"a",0);
7156 tlbl = newiTempLabel(NULL);
7157 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7158 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7159 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7162 emitpcode(POC_COMFW, popGet(AOP(right),0));
7163 emitpcode(POC_RLF, popGet(AOP(result),0));
7164 emitpLabel(tlbl->key);
7165 emitpcode(POC_RRF, popGet(AOP(result),0));
7166 emitpcode(POC_ADDLW, popGetLit(1));
7168 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7173 reAdjustPreg(AOP(result));
7174 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7175 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7178 l = aopGet(AOP(result),offset,FALSE,FALSE);
7180 pic14_emitcode("rrc","a");
7181 aopPut(AOP(result),"a",offset--);
7183 reAdjustPreg(AOP(result));
7185 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7186 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7189 freeAsmop(left,NULL,ic,TRUE);
7190 freeAsmop (right,NULL,ic,TRUE);
7191 freeAsmop(result,NULL,ic,TRUE);
7194 /*-----------------------------------------------------------------*/
7195 /* genUnpackBits - generates code for unpacking bits */
7196 /*-----------------------------------------------------------------*/
7197 static void genUnpackBits (operand *result, char *rname, int ptype)
7204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7205 etype = getSpec(operandType(result));
7207 /* read the first byte */
7212 pic14_emitcode("mov","a,@%s",rname);
7216 pic14_emitcode("movx","a,@%s",rname);
7220 pic14_emitcode("movx","a,@dptr");
7224 pic14_emitcode("clr","a");
7225 pic14_emitcode("movc","a","@a+dptr");
7229 pic14_emitcode("lcall","__gptrget");
7233 /* if we have bitdisplacement then it fits */
7234 /* into this byte completely or if length is */
7235 /* less than a byte */
7236 if ((shCnt = SPEC_BSTR(etype)) ||
7237 (SPEC_BLEN(etype) <= 8)) {
7239 /* shift right acc */
7242 pic14_emitcode("anl","a,#0x%02x",
7243 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7244 aopPut(AOP(result),"a",offset);
7248 /* bit field did not fit in a byte */
7249 rlen = SPEC_BLEN(etype) - 8;
7250 aopPut(AOP(result),"a",offset++);
7257 pic14_emitcode("inc","%s",rname);
7258 pic14_emitcode("mov","a,@%s",rname);
7262 pic14_emitcode("inc","%s",rname);
7263 pic14_emitcode("movx","a,@%s",rname);
7267 pic14_emitcode("inc","dptr");
7268 pic14_emitcode("movx","a,@dptr");
7272 pic14_emitcode("clr","a");
7273 pic14_emitcode("inc","dptr");
7274 pic14_emitcode("movc","a","@a+dptr");
7278 pic14_emitcode("inc","dptr");
7279 pic14_emitcode("lcall","__gptrget");
7284 /* if we are done */
7288 aopPut(AOP(result),"a",offset++);
7293 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7294 aopPut(AOP(result),"a",offset);
7301 /*-----------------------------------------------------------------*/
7302 /* genDataPointerGet - generates code when ptr offset is known */
7303 /*-----------------------------------------------------------------*/
7304 static void genDataPointerGet (operand *left,
7308 int size , offset = 0;
7311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7314 /* optimization - most of the time, left and result are the same
7315 * address, but different types. for the pic code, we could omit
7319 aopOp(result,ic,TRUE);
7321 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7323 size = AOP_SIZE(result);
7326 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7330 freeAsmop(left,NULL,ic,TRUE);
7331 freeAsmop(result,NULL,ic,TRUE);
7334 /*-----------------------------------------------------------------*/
7335 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7336 /*-----------------------------------------------------------------*/
7337 static void genNearPointerGet (operand *left,
7344 sym_link *rtype, *retype;
7345 sym_link *ltype = operandType(left);
7348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7350 rtype = operandType(result);
7351 retype= getSpec(rtype);
7353 aopOp(left,ic,FALSE);
7355 /* if left is rematerialisable and
7356 result is not bit variable type and
7357 the left is pointer to data space i.e
7358 lower 128 bytes of space */
7359 if (AOP_TYPE(left) == AOP_IMMD &&
7360 !IS_BITVAR(retype) &&
7361 DCL_TYPE(ltype) == POINTER) {
7362 genDataPointerGet (left,result,ic);
7366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7368 /* if the value is already in a pointer register
7369 then don't need anything more */
7370 if (!AOP_INPREG(AOP(left))) {
7371 /* otherwise get a free pointer register */
7372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7374 preg = getFreePtr(ic,&aop,FALSE);
7375 pic14_emitcode("mov","%s,%s",
7377 aopGet(AOP(left),0,FALSE,TRUE));
7378 rname = preg->name ;
7380 rname = aopGet(AOP(left),0,FALSE,FALSE);
7382 freeAsmop(left,NULL,ic,TRUE);
7383 aopOp (result,ic,FALSE);
7385 /* if bitfield then unpack the bits */
7386 if (IS_BITVAR(retype))
7387 genUnpackBits (result,rname,POINTER);
7389 /* we have can just get the values */
7390 int size = AOP_SIZE(result);
7393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7395 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7397 pic14_emitcode("mov","a,@%s",rname);
7398 aopPut(AOP(result),"a",offset);
7400 sprintf(buffer,"@%s",rname);
7401 aopPut(AOP(result),buffer,offset);
7405 pic14_emitcode("inc","%s",rname);
7409 /* now some housekeeping stuff */
7411 /* we had to allocate for this iCode */
7412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7413 freeAsmop(NULL,aop,ic,TRUE);
7415 /* we did not allocate which means left
7416 already in a pointer register, then
7417 if size > 0 && this could be used again
7418 we have to point it back to where it
7420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7421 if (AOP_SIZE(result) > 1 &&
7422 !OP_SYMBOL(left)->remat &&
7423 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7425 int size = AOP_SIZE(result) - 1;
7427 pic14_emitcode("dec","%s",rname);
7432 freeAsmop(result,NULL,ic,TRUE);
7436 /*-----------------------------------------------------------------*/
7437 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7438 /*-----------------------------------------------------------------*/
7439 static void genPagedPointerGet (operand *left,
7446 sym_link *rtype, *retype;
7448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7450 rtype = operandType(result);
7451 retype= getSpec(rtype);
7453 aopOp(left,ic,FALSE);
7455 /* if the value is already in a pointer register
7456 then don't need anything more */
7457 if (!AOP_INPREG(AOP(left))) {
7458 /* otherwise get a free pointer register */
7460 preg = getFreePtr(ic,&aop,FALSE);
7461 pic14_emitcode("mov","%s,%s",
7463 aopGet(AOP(left),0,FALSE,TRUE));
7464 rname = preg->name ;
7466 rname = aopGet(AOP(left),0,FALSE,FALSE);
7468 freeAsmop(left,NULL,ic,TRUE);
7469 aopOp (result,ic,FALSE);
7471 /* if bitfield then unpack the bits */
7472 if (IS_BITVAR(retype))
7473 genUnpackBits (result,rname,PPOINTER);
7475 /* we have can just get the values */
7476 int size = AOP_SIZE(result);
7481 pic14_emitcode("movx","a,@%s",rname);
7482 aopPut(AOP(result),"a",offset);
7487 pic14_emitcode("inc","%s",rname);
7491 /* now some housekeeping stuff */
7493 /* we had to allocate for this iCode */
7494 freeAsmop(NULL,aop,ic,TRUE);
7496 /* we did not allocate which means left
7497 already in a pointer register, then
7498 if size > 0 && this could be used again
7499 we have to point it back to where it
7501 if (AOP_SIZE(result) > 1 &&
7502 !OP_SYMBOL(left)->remat &&
7503 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7505 int size = AOP_SIZE(result) - 1;
7507 pic14_emitcode("dec","%s",rname);
7512 freeAsmop(result,NULL,ic,TRUE);
7517 /*-----------------------------------------------------------------*/
7518 /* genFarPointerGet - gget value from far space */
7519 /*-----------------------------------------------------------------*/
7520 static void genFarPointerGet (operand *left,
7521 operand *result, iCode *ic)
7524 sym_link *retype = getSpec(operandType(result));
7526 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7528 aopOp(left,ic,FALSE);
7530 /* if the operand is already in dptr
7531 then we do nothing else we move the value to dptr */
7532 if (AOP_TYPE(left) != AOP_STR) {
7533 /* if this is remateriazable */
7534 if (AOP_TYPE(left) == AOP_IMMD)
7535 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7536 else { /* we need to get it byte by byte */
7537 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7538 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7539 if (options.model == MODEL_FLAT24)
7541 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7545 /* so dptr know contains the address */
7546 freeAsmop(left,NULL,ic,TRUE);
7547 aopOp(result,ic,FALSE);
7549 /* if bit then unpack */
7550 if (IS_BITVAR(retype))
7551 genUnpackBits(result,"dptr",FPOINTER);
7553 size = AOP_SIZE(result);
7557 pic14_emitcode("movx","a,@dptr");
7558 aopPut(AOP(result),"a",offset++);
7560 pic14_emitcode("inc","dptr");
7564 freeAsmop(result,NULL,ic,TRUE);
7567 /*-----------------------------------------------------------------*/
7568 /* pic14_emitcodePointerGet - gget value from code space */
7569 /*-----------------------------------------------------------------*/
7570 static void pic14_emitcodePointerGet (operand *left,
7571 operand *result, iCode *ic)
7574 sym_link *retype = getSpec(operandType(result));
7576 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7578 aopOp(left,ic,FALSE);
7580 /* if the operand is already in dptr
7581 then we do nothing else we move the value to dptr */
7582 if (AOP_TYPE(left) != AOP_STR) {
7583 /* if this is remateriazable */
7584 if (AOP_TYPE(left) == AOP_IMMD)
7585 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7586 else { /* we need to get it byte by byte */
7587 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7588 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7589 if (options.model == MODEL_FLAT24)
7591 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7595 /* so dptr know contains the address */
7596 freeAsmop(left,NULL,ic,TRUE);
7597 aopOp(result,ic,FALSE);
7599 /* if bit then unpack */
7600 if (IS_BITVAR(retype))
7601 genUnpackBits(result,"dptr",CPOINTER);
7603 size = AOP_SIZE(result);
7607 pic14_emitcode("clr","a");
7608 pic14_emitcode("movc","a,@a+dptr");
7609 aopPut(AOP(result),"a",offset++);
7611 pic14_emitcode("inc","dptr");
7615 freeAsmop(result,NULL,ic,TRUE);
7618 /*-----------------------------------------------------------------*/
7619 /* genGenPointerGet - gget value from generic pointer space */
7620 /*-----------------------------------------------------------------*/
7621 static void genGenPointerGet (operand *left,
7622 operand *result, iCode *ic)
7625 sym_link *retype = getSpec(operandType(result));
7627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7628 aopOp(left,ic,FALSE);
7629 aopOp(result,ic,FALSE);
7632 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7634 /* if the operand is already in dptr
7635 then we do nothing else we move the value to dptr */
7636 if (AOP_TYPE(left) != AOP_STR) {
7637 /* if this is remateriazable */
7638 if (AOP_TYPE(left) == AOP_IMMD) {
7639 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7640 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7642 else { /* we need to get it byte by byte */
7644 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7645 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7647 size = AOP_SIZE(result);
7651 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7652 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7654 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7659 /* so dptr know contains the address */
7661 /* if bit then unpack */
7662 if (IS_BITVAR(retype))
7663 genUnpackBits(result,"dptr",GPOINTER);
7666 freeAsmop(left,NULL,ic,TRUE);
7667 freeAsmop(result,NULL,ic,TRUE);
7671 /*-----------------------------------------------------------------*/
7672 /* genPointerGet - generate code for pointer get */
7673 /*-----------------------------------------------------------------*/
7674 static void genPointerGet (iCode *ic)
7676 operand *left, *result ;
7677 sym_link *type, *etype;
7680 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7683 result = IC_RESULT(ic) ;
7685 /* depending on the type of pointer we need to
7686 move it to the correct pointer register */
7687 type = operandType(left);
7688 etype = getSpec(type);
7689 /* if left is of type of pointer then it is simple */
7690 if (IS_PTR(type) && !IS_FUNC(type->next))
7691 p_type = DCL_TYPE(type);
7693 /* we have to go by the storage class */
7694 p_type = PTR_TYPE(SPEC_OCLS(etype));
7696 /* if (SPEC_OCLS(etype)->codesp ) { */
7697 /* p_type = CPOINTER ; */
7700 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7701 /* p_type = FPOINTER ; */
7703 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7704 /* p_type = PPOINTER; */
7706 /* if (SPEC_OCLS(etype) == idata ) */
7707 /* p_type = IPOINTER; */
7709 /* p_type = POINTER ; */
7712 /* now that we have the pointer type we assign
7713 the pointer values */
7718 genNearPointerGet (left,result,ic);
7722 genPagedPointerGet(left,result,ic);
7726 genFarPointerGet (left,result,ic);
7730 pic14_emitcodePointerGet (left,result,ic);
7734 genGenPointerGet (left,result,ic);
7740 /*-----------------------------------------------------------------*/
7741 /* genPackBits - generates code for packed bit storage */
7742 /*-----------------------------------------------------------------*/
7743 static void genPackBits (sym_link *etype ,
7745 char *rname, int p_type)
7753 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7754 blen = SPEC_BLEN(etype);
7755 bstr = SPEC_BSTR(etype);
7757 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7760 /* if the bit lenth is less than or */
7761 /* it exactly fits a byte then */
7762 if (SPEC_BLEN(etype) <= 8 ) {
7763 shCount = SPEC_BSTR(etype) ;
7765 /* shift left acc */
7768 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7773 pic14_emitcode ("mov","b,a");
7774 pic14_emitcode("mov","a,@%s",rname);
7778 pic14_emitcode ("mov","b,a");
7779 pic14_emitcode("movx","a,@dptr");
7783 pic14_emitcode ("push","b");
7784 pic14_emitcode ("push","acc");
7785 pic14_emitcode ("lcall","__gptrget");
7786 pic14_emitcode ("pop","b");
7790 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7791 ((unsigned char)(0xFF << (blen+bstr)) |
7792 (unsigned char)(0xFF >> (8-bstr)) ) );
7793 pic14_emitcode ("orl","a,b");
7794 if (p_type == GPOINTER)
7795 pic14_emitcode("pop","b");
7801 pic14_emitcode("mov","@%s,a",rname);
7805 pic14_emitcode("movx","@dptr,a");
7809 DEBUGpic14_emitcode(";lcall","__gptrput");
7814 if ( SPEC_BLEN(etype) <= 8 )
7817 pic14_emitcode("inc","%s",rname);
7818 rLen = SPEC_BLEN(etype) ;
7820 /* now generate for lengths greater than one byte */
7823 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7833 pic14_emitcode("mov","@%s,a",rname);
7835 pic14_emitcode("mov","@%s,%s",rname,l);
7840 pic14_emitcode("movx","@dptr,a");
7845 DEBUGpic14_emitcode(";lcall","__gptrput");
7848 pic14_emitcode ("inc","%s",rname);
7853 /* last last was not complete */
7855 /* save the byte & read byte */
7858 pic14_emitcode ("mov","b,a");
7859 pic14_emitcode("mov","a,@%s",rname);
7863 pic14_emitcode ("mov","b,a");
7864 pic14_emitcode("movx","a,@dptr");
7868 pic14_emitcode ("push","b");
7869 pic14_emitcode ("push","acc");
7870 pic14_emitcode ("lcall","__gptrget");
7871 pic14_emitcode ("pop","b");
7875 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7876 pic14_emitcode ("orl","a,b");
7879 if (p_type == GPOINTER)
7880 pic14_emitcode("pop","b");
7885 pic14_emitcode("mov","@%s,a",rname);
7889 pic14_emitcode("movx","@dptr,a");
7893 DEBUGpic14_emitcode(";lcall","__gptrput");
7897 /*-----------------------------------------------------------------*/
7898 /* genDataPointerSet - remat pointer to data space */
7899 /*-----------------------------------------------------------------*/
7900 static void genDataPointerSet(operand *right,
7904 int size, offset = 0 ;
7905 char *l, buffer[256];
7907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7908 aopOp(right,ic,FALSE);
7910 l = aopGet(AOP(result),0,FALSE,TRUE);
7911 size = AOP_SIZE(right);
7912 // tsd, was l+1 - the underline `_' prefix was being stripped
7915 sprintf(buffer,"(%s + %d)",l,offset);
7917 sprintf(buffer,"%s",l);
7919 if (AOP_TYPE(right) == AOP_LIT) {
7920 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7921 lit = lit >> (8*offset);
7923 pic14_emitcode("movlw","%d",lit);
7924 pic14_emitcode("movwf","%s",buffer);
7926 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7927 emitpcode(POC_MOVWF, popRegFromString(buffer));
7930 pic14_emitcode("clrf","%s",buffer);
7931 emitpcode(POC_CLRF, popRegFromString(buffer));
7934 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7935 pic14_emitcode("movwf","%s",buffer);
7937 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7938 emitpcode(POC_MOVWF, popRegFromString(buffer));
7945 freeAsmop(right,NULL,ic,TRUE);
7946 freeAsmop(result,NULL,ic,TRUE);
7949 /*-----------------------------------------------------------------*/
7950 /* genNearPointerSet - pic14_emitcode for near pointer put */
7951 /*-----------------------------------------------------------------*/
7952 static void genNearPointerSet (operand *right,
7959 sym_link *ptype = operandType(result);
7962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 retype= getSpec(operandType(right));
7965 aopOp(result,ic,FALSE);
7967 /* if the result is rematerializable &
7968 in data space & not a bit variable */
7969 if (AOP_TYPE(result) == AOP_IMMD &&
7970 DCL_TYPE(ptype) == POINTER &&
7971 !IS_BITVAR(retype)) {
7972 genDataPointerSet (right,result,ic);
7976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7978 /* if the value is already in a pointer register
7979 then don't need anything more */
7980 if (!AOP_INPREG(AOP(result))) {
7981 /* otherwise get a free pointer register */
7982 //aop = newAsmop(0);
7983 //preg = getFreePtr(ic,&aop,FALSE);
7984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7985 //pic14_emitcode("mov","%s,%s",
7987 // aopGet(AOP(result),0,FALSE,TRUE));
7988 //rname = preg->name ;
7989 pic14_emitcode("movwf","fsr");
7991 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7993 freeAsmop(result,NULL,ic,TRUE);
7994 aopOp (right,ic,FALSE);
7995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7997 /* if bitfield then unpack the bits */
7998 if (IS_BITVAR(retype)) {
7999 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8000 "The programmer is obviously confused");
8001 //genPackBits (retype,right,rname,POINTER);
8005 /* we have can just get the values */
8006 int size = AOP_SIZE(right);
8009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8011 l = aopGet(AOP(right),offset,FALSE,TRUE);
8014 //pic14_emitcode("mov","@%s,a",rname);
8015 pic14_emitcode("movf","indf,w ;1");
8018 if (AOP_TYPE(right) == AOP_LIT) {
8019 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8021 pic14_emitcode("movlw","%s",l);
8022 pic14_emitcode("movwf","indf ;2");
8024 pic14_emitcode("clrf","indf");
8026 pic14_emitcode("movf","%s,w",l);
8027 pic14_emitcode("movwf","indf ;2");
8029 //pic14_emitcode("mov","@%s,%s",rname,l);
8032 pic14_emitcode("incf","fsr,f ;3");
8033 //pic14_emitcode("inc","%s",rname);
8038 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8039 /* now some housekeeping stuff */
8041 /* we had to allocate for this iCode */
8042 freeAsmop(NULL,aop,ic,TRUE);
8044 /* we did not allocate which means left
8045 already in a pointer register, then
8046 if size > 0 && this could be used again
8047 we have to point it back to where it
8049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8050 if (AOP_SIZE(right) > 1 &&
8051 !OP_SYMBOL(result)->remat &&
8052 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8054 int size = AOP_SIZE(right) - 1;
8056 pic14_emitcode("decf","fsr,f");
8057 //pic14_emitcode("dec","%s",rname);
8061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8063 freeAsmop(right,NULL,ic,TRUE);
8068 /*-----------------------------------------------------------------*/
8069 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8070 /*-----------------------------------------------------------------*/
8071 static void genPagedPointerSet (operand *right,
8080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8082 retype= getSpec(operandType(right));
8084 aopOp(result,ic,FALSE);
8086 /* if the value is already in a pointer register
8087 then don't need anything more */
8088 if (!AOP_INPREG(AOP(result))) {
8089 /* otherwise get a free pointer register */
8091 preg = getFreePtr(ic,&aop,FALSE);
8092 pic14_emitcode("mov","%s,%s",
8094 aopGet(AOP(result),0,FALSE,TRUE));
8095 rname = preg->name ;
8097 rname = aopGet(AOP(result),0,FALSE,FALSE);
8099 freeAsmop(result,NULL,ic,TRUE);
8100 aopOp (right,ic,FALSE);
8102 /* if bitfield then unpack the bits */
8103 if (IS_BITVAR(retype))
8104 genPackBits (retype,right,rname,PPOINTER);
8106 /* we have can just get the values */
8107 int size = AOP_SIZE(right);
8111 l = aopGet(AOP(right),offset,FALSE,TRUE);
8114 pic14_emitcode("movx","@%s,a",rname);
8117 pic14_emitcode("inc","%s",rname);
8123 /* now some housekeeping stuff */
8125 /* we had to allocate for this iCode */
8126 freeAsmop(NULL,aop,ic,TRUE);
8128 /* we did not allocate which means left
8129 already in a pointer register, then
8130 if size > 0 && this could be used again
8131 we have to point it back to where it
8133 if (AOP_SIZE(right) > 1 &&
8134 !OP_SYMBOL(result)->remat &&
8135 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8137 int size = AOP_SIZE(right) - 1;
8139 pic14_emitcode("dec","%s",rname);
8144 freeAsmop(right,NULL,ic,TRUE);
8149 /*-----------------------------------------------------------------*/
8150 /* genFarPointerSet - set value from far space */
8151 /*-----------------------------------------------------------------*/
8152 static void genFarPointerSet (operand *right,
8153 operand *result, iCode *ic)
8156 sym_link *retype = getSpec(operandType(right));
8158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 aopOp(result,ic,FALSE);
8161 /* if the operand is already in dptr
8162 then we do nothing else we move the value to dptr */
8163 if (AOP_TYPE(result) != AOP_STR) {
8164 /* if this is remateriazable */
8165 if (AOP_TYPE(result) == AOP_IMMD)
8166 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8167 else { /* we need to get it byte by byte */
8168 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8169 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8170 if (options.model == MODEL_FLAT24)
8172 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8176 /* so dptr know contains the address */
8177 freeAsmop(result,NULL,ic,TRUE);
8178 aopOp(right,ic,FALSE);
8180 /* if bit then unpack */
8181 if (IS_BITVAR(retype))
8182 genPackBits(retype,right,"dptr",FPOINTER);
8184 size = AOP_SIZE(right);
8188 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8190 pic14_emitcode("movx","@dptr,a");
8192 pic14_emitcode("inc","dptr");
8196 freeAsmop(right,NULL,ic,TRUE);
8199 /*-----------------------------------------------------------------*/
8200 /* genGenPointerSet - set value from generic pointer space */
8201 /*-----------------------------------------------------------------*/
8202 static void genGenPointerSet (operand *right,
8203 operand *result, iCode *ic)
8206 sym_link *retype = getSpec(operandType(right));
8208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8210 aopOp(result,ic,FALSE);
8211 aopOp(right,ic,FALSE);
8212 size = AOP_SIZE(right);
8214 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8216 /* if the operand is already in dptr
8217 then we do nothing else we move the value to dptr */
8218 if (AOP_TYPE(result) != AOP_STR) {
8219 /* if this is remateriazable */
8220 if (AOP_TYPE(result) == AOP_IMMD) {
8221 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8222 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8224 else { /* we need to get it byte by byte */
8225 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8226 size = AOP_SIZE(right);
8229 /* hack hack! see if this the FSR. If so don't load W */
8230 if(AOP_TYPE(right) != AOP_ACC) {
8232 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8233 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8236 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8238 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8239 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8243 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8244 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8247 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8254 if(aopIdx(AOP(result),0) != 4) {
8256 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8260 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8265 /* so dptr know contains the address */
8268 /* if bit then unpack */
8269 if (IS_BITVAR(retype))
8270 genPackBits(retype,right,"dptr",GPOINTER);
8272 size = AOP_SIZE(right);
8276 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8278 pic14_emitcode("incf","fsr,f");
8279 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8280 pic14_emitcode("movwf","indf");
8282 //DEBUGpic14_emitcode(";lcall","__gptrput");
8284 // pic14_emitcode("inc","dptr");
8289 freeAsmop(right,NULL,ic,TRUE);
8290 freeAsmop(result,NULL,ic,TRUE);
8293 /*-----------------------------------------------------------------*/
8294 /* genPointerSet - stores the value into a pointer location */
8295 /*-----------------------------------------------------------------*/
8296 static void genPointerSet (iCode *ic)
8298 operand *right, *result ;
8299 sym_link *type, *etype;
8302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8304 right = IC_RIGHT(ic);
8305 result = IC_RESULT(ic) ;
8307 /* depending on the type of pointer we need to
8308 move it to the correct pointer register */
8309 type = operandType(result);
8310 etype = getSpec(type);
8311 /* if left is of type of pointer then it is simple */
8312 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8313 p_type = DCL_TYPE(type);
8316 /* we have to go by the storage class */
8317 p_type = PTR_TYPE(SPEC_OCLS(etype));
8319 /* if (SPEC_OCLS(etype)->codesp ) { */
8320 /* p_type = CPOINTER ; */
8323 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8324 /* p_type = FPOINTER ; */
8326 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8327 /* p_type = PPOINTER ; */
8329 /* if (SPEC_OCLS(etype) == idata ) */
8330 /* p_type = IPOINTER ; */
8332 /* p_type = POINTER ; */
8335 /* now that we have the pointer type we assign
8336 the pointer values */
8341 genNearPointerSet (right,result,ic);
8345 genPagedPointerSet (right,result,ic);
8349 genFarPointerSet (right,result,ic);
8353 genGenPointerSet (right,result,ic);
8359 /*-----------------------------------------------------------------*/
8360 /* genIfx - generate code for Ifx statement */
8361 /*-----------------------------------------------------------------*/
8362 static void genIfx (iCode *ic, iCode *popIc)
8364 operand *cond = IC_COND(ic);
8367 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8369 aopOp(cond,ic,FALSE);
8371 /* get the value into acc */
8372 if (AOP_TYPE(cond) != AOP_CRY)
8373 pic14_toBoolean(cond);
8376 /* the result is now in the accumulator */
8377 freeAsmop(cond,NULL,ic,TRUE);
8379 /* if there was something to be popped then do it */
8383 /* if the condition is a bit variable */
8384 if (isbit && IS_ITEMP(cond) &&
8386 genIfxJump(ic,SPIL_LOC(cond)->rname);
8387 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8390 if (isbit && !IS_ITEMP(cond))
8391 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8399 /*-----------------------------------------------------------------*/
8400 /* genAddrOf - generates code for address of */
8401 /*-----------------------------------------------------------------*/
8402 static void genAddrOf (iCode *ic)
8404 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8405 operand *right, *result, *left;
8406 //int size, offset ;
8408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8411 //aopOp(IC_RESULT(ic),ic,FALSE);
8413 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8414 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8415 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8417 DEBUGpic14_AopType(__LINE__,left,right,result);
8419 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8420 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8423 /* object not on stack then we need the name */
8424 size = AOP_SIZE(IC_RESULT(ic));
8428 char s[SDCC_NAME_MAX];
8430 sprintf(s,"#(%s >> %d)",
8434 sprintf(s,"#%s",sym->rname);
8435 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8440 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8441 freeAsmop(left,NULL,ic,FALSE);
8442 freeAsmop(result,NULL,ic,TRUE);
8447 /*-----------------------------------------------------------------*/
8448 /* genFarFarAssign - assignment when both are in far space */
8449 /*-----------------------------------------------------------------*/
8450 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8452 int size = AOP_SIZE(right);
8455 /* first push the right side on to the stack */
8457 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8459 pic14_emitcode ("push","acc");
8462 freeAsmop(right,NULL,ic,FALSE);
8463 /* now assign DPTR to result */
8464 aopOp(result,ic,FALSE);
8465 size = AOP_SIZE(result);
8467 pic14_emitcode ("pop","acc");
8468 aopPut(AOP(result),"a",--offset);
8470 freeAsmop(result,NULL,ic,FALSE);
8475 /*-----------------------------------------------------------------*/
8476 /* genAssign - generate code for assignment */
8477 /*-----------------------------------------------------------------*/
8478 static void genAssign (iCode *ic)
8480 operand *result, *right;
8481 int size, offset,know_W;
8482 unsigned long lit = 0L;
8484 result = IC_RESULT(ic);
8485 right = IC_RIGHT(ic) ;
8487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8489 /* if they are the same */
8490 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8493 aopOp(right,ic,FALSE);
8494 aopOp(result,ic,TRUE);
8496 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8498 /* if they are the same registers */
8499 if (pic14_sameRegs(AOP(right),AOP(result)))
8502 /* if the result is a bit */
8503 if (AOP_TYPE(result) == AOP_CRY) {
8505 /* if the right size is a literal then
8506 we know what the value is */
8507 if (AOP_TYPE(right) == AOP_LIT) {
8509 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8510 popGet(AOP(result),0));
8512 if (((int) operandLitValue(right)))
8513 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8514 AOP(result)->aopu.aop_dir,
8515 AOP(result)->aopu.aop_dir);
8517 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8518 AOP(result)->aopu.aop_dir,
8519 AOP(result)->aopu.aop_dir);
8523 /* the right is also a bit variable */
8524 if (AOP_TYPE(right) == AOP_CRY) {
8525 emitpcode(POC_BCF, popGet(AOP(result),0));
8526 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8527 emitpcode(POC_BSF, popGet(AOP(result),0));
8529 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8530 AOP(result)->aopu.aop_dir,
8531 AOP(result)->aopu.aop_dir);
8532 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8533 AOP(right)->aopu.aop_dir,
8534 AOP(right)->aopu.aop_dir);
8535 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8536 AOP(result)->aopu.aop_dir,
8537 AOP(result)->aopu.aop_dir);
8542 emitpcode(POC_BCF, popGet(AOP(result),0));
8543 pic14_toBoolean(right);
8545 emitpcode(POC_BSF, popGet(AOP(result),0));
8546 //aopPut(AOP(result),"a",0);
8550 /* bit variables done */
8552 size = AOP_SIZE(result);
8554 if(AOP_TYPE(right) == AOP_LIT)
8555 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8557 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8558 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8559 if(aopIdx(AOP(result),0) == 4) {
8560 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8561 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8562 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8565 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8571 if(AOP_TYPE(right) == AOP_LIT) {
8573 if(know_W != (lit&0xff))
8574 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8576 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8578 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8582 } else if (AOP_TYPE(right) == AOP_CRY) {
8583 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8585 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8586 emitpcode(POC_INCF, popGet(AOP(result),0));
8589 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8590 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8591 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8599 freeAsmop (right,NULL,ic,FALSE);
8600 freeAsmop (result,NULL,ic,TRUE);
8603 /*-----------------------------------------------------------------*/
8604 /* genJumpTab - genrates code for jump table */
8605 /*-----------------------------------------------------------------*/
8606 static void genJumpTab (iCode *ic)
8611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8613 aopOp(IC_JTCOND(ic),ic,FALSE);
8614 /* get the condition into accumulator */
8615 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8617 /* multiply by three */
8618 pic14_emitcode("add","a,acc");
8619 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8621 jtab = newiTempLabel(NULL);
8622 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8623 pic14_emitcode("jmp","@a+dptr");
8624 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8626 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8627 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8629 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8630 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8631 emitpLabel(jtab->key);
8633 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8635 /* now generate the jump labels */
8636 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8637 jtab = setNextItem(IC_JTLABELS(ic))) {
8638 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8639 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8645 /*-----------------------------------------------------------------*/
8646 /* genMixedOperation - gen code for operators between mixed types */
8647 /*-----------------------------------------------------------------*/
8649 TSD - Written for the PIC port - but this unfortunately is buggy.
8650 This routine is good in that it is able to efficiently promote
8651 types to different (larger) sizes. Unfortunately, the temporary
8652 variables that are optimized out by this routine are sometimes
8653 used in other places. So until I know how to really parse the
8654 iCode tree, I'm going to not be using this routine :(.
8656 static int genMixedOperation (iCode *ic)
8659 operand *result = IC_RESULT(ic);
8660 sym_link *ctype = operandType(IC_LEFT(ic));
8661 operand *right = IC_RIGHT(ic);
8667 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8669 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8675 nextright = IC_RIGHT(nextic);
8676 nextleft = IC_LEFT(nextic);
8677 nextresult = IC_RESULT(nextic);
8679 aopOp(right,ic,FALSE);
8680 aopOp(result,ic,FALSE);
8681 aopOp(nextright, nextic, FALSE);
8682 aopOp(nextleft, nextic, FALSE);
8683 aopOp(nextresult, nextic, FALSE);
8685 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8691 pic14_emitcode(";remove right +","");
8693 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8699 pic14_emitcode(";remove left +","");
8703 big = AOP_SIZE(nextleft);
8704 small = AOP_SIZE(nextright);
8706 switch(nextic->op) {
8709 pic14_emitcode(";optimize a +","");
8710 /* if unsigned or not an integral type */
8711 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8712 pic14_emitcode(";add a bit to something","");
8715 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8717 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8718 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8719 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8721 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8729 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8730 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8731 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8734 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8736 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8737 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8738 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8739 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8740 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8743 pic14_emitcode("rlf","known_zero,w");
8750 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8751 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8752 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8754 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8764 freeAsmop(right,NULL,ic,TRUE);
8765 freeAsmop(result,NULL,ic,TRUE);
8766 freeAsmop(nextright,NULL,ic,TRUE);
8767 freeAsmop(nextleft,NULL,ic,TRUE);
8769 nextic->generated = 1;
8776 /*-----------------------------------------------------------------*/
8777 /* genCast - gen code for casting */
8778 /*-----------------------------------------------------------------*/
8779 static void genCast (iCode *ic)
8781 operand *result = IC_RESULT(ic);
8782 sym_link *ctype = operandType(IC_LEFT(ic));
8783 operand *right = IC_RIGHT(ic);
8786 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8787 /* if they are equivalent then do nothing */
8788 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8791 aopOp(right,ic,FALSE) ;
8792 aopOp(result,ic,FALSE);
8794 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8796 /* if the result is a bit */
8797 if (AOP_TYPE(result) == AOP_CRY) {
8798 /* if the right size is a literal then
8799 we know what the value is */
8800 if (AOP_TYPE(right) == AOP_LIT) {
8802 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8803 popGet(AOP(result),0));
8805 if (((int) operandLitValue(right)))
8806 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8807 AOP(result)->aopu.aop_dir,
8808 AOP(result)->aopu.aop_dir);
8810 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8811 AOP(result)->aopu.aop_dir,
8812 AOP(result)->aopu.aop_dir);
8817 /* the right is also a bit variable */
8818 if (AOP_TYPE(right) == AOP_CRY) {
8821 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8823 pic14_emitcode("clrc","");
8824 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8825 AOP(right)->aopu.aop_dir,
8826 AOP(right)->aopu.aop_dir);
8827 aopPut(AOP(result),"c",0);
8832 if (AOP_TYPE(right) == AOP_REG) {
8833 emitpcode(POC_BCF, popGet(AOP(result),0));
8834 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8835 emitpcode(POC_BSF, popGet(AOP(result),0));
8837 pic14_toBoolean(right);
8838 aopPut(AOP(result),"a",0);
8842 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8844 size = AOP_SIZE(result);
8846 emitpcode(POC_CLRF, popGet(AOP(result),0));
8847 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8848 emitpcode(POC_INCF, popGet(AOP(result),0));
8851 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8856 /* if they are the same size : or less */
8857 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8859 /* if they are in the same place */
8860 if (pic14_sameRegs(AOP(right),AOP(result)))
8863 /* if they in different places then copy */
8864 size = AOP_SIZE(result);
8868 aopGet(AOP(right),offset,FALSE,FALSE),
8876 /* if the result is of type pointer */
8877 if (IS_PTR(ctype)) {
8880 sym_link *type = operandType(right);
8881 sym_link *etype = getSpec(type);
8883 /* pointer to generic pointer */
8884 if (IS_GENPTR(ctype)) {
8888 p_type = DCL_TYPE(type);
8890 /* we have to go by the storage class */
8891 p_type = PTR_TYPE(SPEC_OCLS(etype));
8893 /* if (SPEC_OCLS(etype)->codesp ) */
8894 /* p_type = CPOINTER ; */
8896 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8897 /* p_type = FPOINTER ; */
8899 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8900 /* p_type = PPOINTER; */
8902 /* if (SPEC_OCLS(etype) == idata ) */
8903 /* p_type = IPOINTER ; */
8905 /* p_type = POINTER ; */
8908 /* the first two bytes are known */
8909 size = GPTRSIZE - 1;
8913 aopGet(AOP(right),offset,FALSE,FALSE),
8917 /* the last byte depending on type */
8934 /* this should never happen */
8935 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8936 "got unknown pointer type");
8939 aopPut(AOP(result),l, GPTRSIZE - 1);
8943 /* just copy the pointers */
8944 size = AOP_SIZE(result);
8948 aopGet(AOP(right),offset,FALSE,FALSE),
8957 /* so we now know that the size of destination is greater
8958 than the size of the source.
8959 Now, if the next iCode is an operator then we might be
8960 able to optimize the operation without performing a cast.
8962 if(genMixedOperation(ic))
8966 /* we move to result for the size of source */
8967 size = AOP_SIZE(right);
8970 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8971 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8975 /* now depending on the sign of the destination */
8976 size = AOP_SIZE(result) - AOP_SIZE(right);
8977 /* if unsigned or not an integral type */
8978 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8980 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8982 /* we need to extend the sign :{ */
8985 /* Save one instruction of casting char to int */
8986 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8987 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8988 emitpcode(POC_DECF, popGet(AOP(result),offset));
8990 emitpcodeNULLop(POC_CLRW);
8993 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8995 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8997 emitpcode(POC_MOVLW, popGetLit(0xff));
9000 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9005 freeAsmop(right,NULL,ic,TRUE);
9006 freeAsmop(result,NULL,ic,TRUE);
9010 /*-----------------------------------------------------------------*/
9011 /* genDjnz - generate decrement & jump if not zero instrucion */
9012 /*-----------------------------------------------------------------*/
9013 static int genDjnz (iCode *ic, iCode *ifx)
9016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9021 /* if the if condition has a false label
9022 then we cannot save */
9026 /* if the minus is not of the form
9028 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9029 !IS_OP_LITERAL(IC_RIGHT(ic)))
9032 if (operandLitValue(IC_RIGHT(ic)) != 1)
9035 /* if the size of this greater than one then no
9037 if (getSize(operandType(IC_RESULT(ic))) > 1)
9040 /* otherwise we can save BIG */
9041 lbl = newiTempLabel(NULL);
9042 lbl1= newiTempLabel(NULL);
9044 aopOp(IC_RESULT(ic),ic,FALSE);
9046 if (IS_AOP_PREG(IC_RESULT(ic))) {
9047 pic14_emitcode("dec","%s",
9048 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9049 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9050 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9054 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9055 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9057 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9058 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9061 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9062 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9063 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9064 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9067 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9072 /*-----------------------------------------------------------------*/
9073 /* genReceive - generate code for a receive iCode */
9074 /*-----------------------------------------------------------------*/
9075 static void genReceive (iCode *ic)
9077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9079 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9080 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9081 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9083 int size = getSize(operandType(IC_RESULT(ic)));
9084 int offset = fReturnSizePic - size;
9086 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9087 fReturn[fReturnSizePic - offset - 1] : "acc"));
9090 aopOp(IC_RESULT(ic),ic,FALSE);
9091 size = AOP_SIZE(IC_RESULT(ic));
9094 pic14_emitcode ("pop","acc");
9095 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9100 aopOp(IC_RESULT(ic),ic,FALSE);
9102 assignResultValue(IC_RESULT(ic));
9105 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9108 /*-----------------------------------------------------------------*/
9109 /* genpic14Code - generate code for pic14 based controllers */
9110 /*-----------------------------------------------------------------*/
9112 * At this point, ralloc.c has gone through the iCode and attempted
9113 * to optimize in a way suitable for a PIC. Now we've got to generate
9114 * PIC instructions that correspond to the iCode.
9116 * Once the instructions are generated, we'll pass through both the
9117 * peep hole optimizer and the pCode optimizer.
9118 *-----------------------------------------------------------------*/
9120 void genpic14Code (iCode *lic)
9125 lineHead = lineCurr = NULL;
9127 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9130 /* if debug information required */
9131 /* if (options.debug && currFunc) { */
9133 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9135 if (IS_STATIC(currFunc->etype)) {
9136 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9137 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9139 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9140 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9146 for (ic = lic ; ic ; ic = ic->next ) {
9148 DEBUGpic14_emitcode(";ic","");
9149 if ( cln != ic->lineno ) {
9150 if ( options.debug ) {
9152 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9153 FileBaseName(ic->filename),ic->lineno,
9154 ic->level,ic->block);
9157 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9160 /* if the result is marked as
9161 spilt and rematerializable or code for
9162 this has already been generated then
9164 if (resultRemat(ic) || ic->generated )
9167 /* depending on the operation */
9186 /* IPOP happens only when trying to restore a
9187 spilt live range, if there is an ifx statement
9188 following this pop then the if statement might
9189 be using some of the registers being popped which
9190 would destory the contents of the register so
9191 we need to check for this condition and handle it */
9193 ic->next->op == IFX &&
9194 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9195 genIfx (ic->next,ic);
9213 genEndFunction (ic);
9233 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9250 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9254 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9261 /* note these two are xlated by algebraic equivalence
9262 during parsing SDCC.y */
9263 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9264 "got '>=' or '<=' shouldn't have come here");
9268 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9280 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9284 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9288 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9315 case GET_VALUE_AT_ADDRESS:
9320 if (POINTER_SET(ic))
9347 addSet(&_G.sendSet,ic);
9356 /* now we are ready to call the
9357 peep hole optimizer */
9358 if (!options.nopeep) {
9359 printf("peep hole optimizing\n");
9360 peepHole (&lineHead);
9362 /* now do the actual printing */
9363 printLine (lineHead,codeOutFile);
9365 printf("printing pBlock\n\n");
9366 printpBlock(stdout,pb);