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(pCodeOp) );
1128 pcop->type = PO_DIR;
1130 DEBUGpic14_emitcode(";","%d",__LINE__);
1131 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1136 pCodeOp *popRegFromIdx(int rIdx)
1140 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1141 __FUNCTION__,__LINE__,rIdx);
1143 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1145 PCOR(pcop)->rIdx = rIdx;
1146 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1147 PCOR(pcop)->r->isFree = 0;
1148 PCOR(pcop)->r->wasUsed = 1;
1150 pcop->type = PCOR(pcop)->r->pc_type;
1155 /*-----------------------------------------------------------------*/
1156 /* popGet - asm operator to pcode operator conversion */
1157 /*-----------------------------------------------------------------*/
1158 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1165 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1166 /* offset is greater than
1169 if (offset > (aop->size - 1) &&
1170 aop->type != AOP_LIT)
1171 return NULL; //zero;
1173 /* depending on type */
1174 switch (aop->type) {
1181 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1182 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1183 //pcop->type = PO_SFR_REGISTER;
1185 //PCOR(pcop)->rIdx = -1;
1186 //PCOR(pcop)->r = NULL;
1187 // Really nasty hack to check for temporary registers
1189 //pcop->name = Safe_strdup("BAD_REGISTER");
1194 DEBUGpic14_emitcode(";","%d",__LINE__);
1195 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1196 pcop->type = PO_IMMEDIATE;
1198 // sprintf (s,"%s",aop->aopu.aop_immd);
1201 sprintf(s,"(%s >> %d)",
1206 aop->aopu.aop_immd);
1207 pcop->name = Safe_calloc(1,strlen(s)+1);
1208 strcpy(pcop->name,s);
1212 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1213 pcop->type = PO_DIR;
1215 sprintf(s,"(%s + %d)",
1219 sprintf(s,"%s",aop->aopu.aop_dir);
1220 pcop->name = Safe_calloc(1,strlen(s)+1);
1221 strcpy(pcop->name,s);
1226 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1228 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1229 PCOR(pcop)->rIdx = rIdx;
1230 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1231 pcop->type = PCOR(pcop)->r->pc_type;
1232 rs = aop->aopu.aop_reg[offset]->name;
1233 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1238 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1242 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1245 DEBUGpic14_emitcode(";","%d",__LINE__);
1247 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1248 pcop->type = PO_STR;
1250 //aop->coff = offset ;
1251 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1252 // sprintf(s,"%s","acc");
1254 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1255 pcop->name = Safe_calloc(1,strlen(s)+1);
1256 strcpy(pcop->name,s);
1261 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1262 "popGet got unsupported aop->type");
1265 /*-----------------------------------------------------------------*/
1266 /* aopPut - puts a string for a aop */
1267 /*-----------------------------------------------------------------*/
1268 void aopPut (asmop *aop, char *s, int offset)
1273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1275 if (aop->size && offset > ( aop->size - 1)) {
1276 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1277 "aopPut got offset > aop->size");
1281 /* will assign value to value */
1282 /* depending on where it is ofcourse */
1283 switch (aop->type) {
1286 sprintf(d,"(%s + %d)",
1287 aop->aopu.aop_dir,offset);
1289 sprintf(d,"%s",aop->aopu.aop_dir);
1292 DEBUGpic14_emitcode(";","%d",__LINE__);
1294 pic14_emitcode("movf","%s,w",s);
1295 pic14_emitcode("movwf","%s",d);
1298 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1299 emitpcode(POC_MOVWF,popGet(aop,offset));
1306 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1307 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1310 strcmp(s,"r0") == 0 ||
1311 strcmp(s,"r1") == 0 ||
1312 strcmp(s,"r2") == 0 ||
1313 strcmp(s,"r3") == 0 ||
1314 strcmp(s,"r4") == 0 ||
1315 strcmp(s,"r5") == 0 ||
1316 strcmp(s,"r6") == 0 ||
1317 strcmp(s,"r7") == 0 )
1318 pic14_emitcode("mov","%s,%s ; %d",
1319 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1324 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1326 pic14_emitcode("movwf","%s",
1327 aop->aopu.aop_reg[offset]->name);
1330 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1331 pcop->type = PO_GPR_REGISTER;
1333 PCOR(pcop)->rIdx = -1;
1334 PCOR(pcop)->r = NULL;
1336 DEBUGpic14_emitcode(";","%d",__LINE__);
1337 pcop->name = Safe_strdup(s);
1338 emitpcode(POC_MOVFW,pcop);
1340 emitpcode(POC_MOVWF,popGet(aop,offset));
1348 if (aop->type == AOP_DPTR2)
1354 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1355 "aopPut writting to code space");
1359 while (offset > aop->coff) {
1361 pic14_emitcode ("inc","dptr");
1364 while (offset < aop->coff) {
1366 pic14_emitcode("lcall","__decdptr");
1371 /* if not in accumulater */
1374 pic14_emitcode ("movx","@dptr,a");
1376 if (aop->type == AOP_DPTR2)
1384 while (offset > aop->coff) {
1386 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1388 while (offset < aop->coff) {
1390 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1396 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1401 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1403 if (strcmp(s,"r0") == 0 ||
1404 strcmp(s,"r1") == 0 ||
1405 strcmp(s,"r2") == 0 ||
1406 strcmp(s,"r3") == 0 ||
1407 strcmp(s,"r4") == 0 ||
1408 strcmp(s,"r5") == 0 ||
1409 strcmp(s,"r6") == 0 ||
1410 strcmp(s,"r7") == 0 ) {
1412 sprintf(buffer,"a%s",s);
1413 pic14_emitcode("mov","@%s,%s",
1414 aop->aopu.aop_ptr->name,buffer);
1416 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1421 if (strcmp(s,"a") == 0)
1422 pic14_emitcode("push","acc");
1424 pic14_emitcode("push","%s",s);
1429 /* if bit variable */
1430 if (!aop->aopu.aop_dir) {
1431 pic14_emitcode("clr","a");
1432 pic14_emitcode("rlc","a");
1435 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1438 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1441 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1443 lbl = newiTempLabel(NULL);
1445 if (strcmp(s,"a")) {
1448 pic14_emitcode("clr","c");
1449 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1450 pic14_emitcode("cpl","c");
1451 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1452 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1459 if (strcmp(aop->aopu.aop_str[offset],s))
1460 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1465 if (!offset && (strcmp(s,"acc") == 0))
1468 if (strcmp(aop->aopu.aop_str[offset],s))
1469 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1473 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1474 "aopPut got unsupported aop->type");
1480 /*-----------------------------------------------------------------*/
1481 /* reAdjustPreg - points a register back to where it should */
1482 /*-----------------------------------------------------------------*/
1483 static void reAdjustPreg (asmop *aop)
1487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1489 if ((size = aop->size) <= 1)
1492 switch (aop->type) {
1496 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1500 if (aop->type == AOP_DPTR2)
1506 pic14_emitcode("lcall","__decdptr");
1509 if (aop->type == AOP_DPTR2)
1519 /*-----------------------------------------------------------------*/
1520 /* genNotFloat - generates not for float operations */
1521 /*-----------------------------------------------------------------*/
1522 static void genNotFloat (operand *op, operand *res)
1528 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1529 /* we will put 127 in the first byte of
1531 aopPut(AOP(res),"#127",0);
1532 size = AOP_SIZE(op) - 1;
1535 l = aopGet(op->aop,offset++,FALSE,FALSE);
1539 pic14_emitcode("orl","a,%s",
1541 offset++,FALSE,FALSE));
1543 tlbl = newiTempLabel(NULL);
1545 tlbl = newiTempLabel(NULL);
1546 aopPut(res->aop,one,1);
1547 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1548 aopPut(res->aop,zero,1);
1549 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1551 size = res->aop->size - 2;
1553 /* put zeros in the rest */
1555 aopPut(res->aop,zero,offset++);
1559 /*-----------------------------------------------------------------*/
1560 /* opIsGptr: returns non-zero if the passed operand is */
1561 /* a generic pointer type. */
1562 /*-----------------------------------------------------------------*/
1563 static int opIsGptr(operand *op)
1565 sym_link *type = operandType(op);
1567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1568 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1576 /*-----------------------------------------------------------------*/
1577 /* pic14_getDataSize - get the operand data size */
1578 /*-----------------------------------------------------------------*/
1579 int pic14_getDataSize(operand *op)
1581 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1584 return AOP_SIZE(op);
1586 // tsd- in the pic port, the genptr size is 1, so this code here
1587 // fails. ( in the 8051 port, the size was 4).
1590 size = AOP_SIZE(op);
1591 if (size == GPTRSIZE)
1593 sym_link *type = operandType(op);
1594 if (IS_GENPTR(type))
1596 /* generic pointer; arithmetic operations
1597 * should ignore the high byte (pointer type).
1600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1607 /*-----------------------------------------------------------------*/
1608 /* pic14_outAcc - output Acc */
1609 /*-----------------------------------------------------------------*/
1610 void pic14_outAcc(operand *result)
1613 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1614 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1617 size = pic14_getDataSize(result);
1619 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1622 /* unsigned or positive */
1624 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1629 /*-----------------------------------------------------------------*/
1630 /* pic14_outBitC - output a bit C */
1631 /*-----------------------------------------------------------------*/
1632 void pic14_outBitC(operand *result)
1635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1636 /* if the result is bit */
1637 if (AOP_TYPE(result) == AOP_CRY)
1638 aopPut(AOP(result),"c",0);
1640 pic14_emitcode("clr","a ; %d", __LINE__);
1641 pic14_emitcode("rlc","a");
1642 pic14_outAcc(result);
1646 /*-----------------------------------------------------------------*/
1647 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1648 /*-----------------------------------------------------------------*/
1649 void pic14_toBoolean(operand *oper)
1651 int size = AOP_SIZE(oper) - 1;
1654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1656 if ( AOP_TYPE(oper) != AOP_ACC) {
1657 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1660 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1665 /*-----------------------------------------------------------------*/
1666 /* genNot - generate code for ! operation */
1667 /*-----------------------------------------------------------------*/
1668 static void genNot (iCode *ic)
1671 sym_link *optype = operandType(IC_LEFT(ic));
1674 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1675 /* assign asmOps to operand & result */
1676 aopOp (IC_LEFT(ic),ic,FALSE);
1677 aopOp (IC_RESULT(ic),ic,TRUE);
1679 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1680 /* if in bit space then a special case */
1681 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1682 pic14_emitcode("movlw","1<<%s");
1683 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1684 //pic14_emitcode("cpl","c");
1685 //pic14_outBitC(IC_RESULT(ic));
1689 /* if type float then do float */
1690 if (IS_FLOAT(optype)) {
1691 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1695 size = AOP_SIZE(IC_RESULT(ic));
1697 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1698 emitpcode(POC_ANDLW,popGetLit(1));
1699 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1702 pic14_toBoolean(IC_LEFT(ic));
1704 tlbl = newiTempLabel(NULL);
1705 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1706 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1707 pic14_outBitC(IC_RESULT(ic));
1710 /* release the aops */
1711 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1712 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1716 /*-----------------------------------------------------------------*/
1717 /* genCpl - generate code for complement */
1718 /*-----------------------------------------------------------------*/
1719 static void genCpl (iCode *ic)
1725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1726 /* assign asmOps to operand & result */
1727 aopOp (IC_LEFT(ic),ic,FALSE);
1728 aopOp (IC_RESULT(ic),ic,TRUE);
1730 /* if both are in bit space then
1732 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1733 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1735 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1736 pic14_emitcode("cpl","c");
1737 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1741 size = AOP_SIZE(IC_RESULT(ic));
1743 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1745 pic14_emitcode("cpl","a");
1746 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1751 /* release the aops */
1752 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1753 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1756 /*-----------------------------------------------------------------*/
1757 /* genUminusFloat - unary minus for floating points */
1758 /*-----------------------------------------------------------------*/
1759 static void genUminusFloat(operand *op,operand *result)
1761 int size ,offset =0 ;
1764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1765 /* for this we just need to flip the
1766 first it then copy the rest in place */
1767 size = AOP_SIZE(op) - 1;
1768 l = aopGet(AOP(op),3,FALSE,FALSE);
1772 pic14_emitcode("cpl","acc.7");
1773 aopPut(AOP(result),"a",3);
1777 aopGet(AOP(op),offset,FALSE,FALSE),
1783 /*-----------------------------------------------------------------*/
1784 /* genUminus - unary minus code generation */
1785 /*-----------------------------------------------------------------*/
1786 static void genUminus (iCode *ic)
1789 sym_link *optype, *rtype;
1792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1794 aopOp(IC_LEFT(ic),ic,FALSE);
1795 aopOp(IC_RESULT(ic),ic,TRUE);
1797 /* if both in bit space then special
1799 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1800 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1802 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1803 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1804 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1809 optype = operandType(IC_LEFT(ic));
1810 rtype = operandType(IC_RESULT(ic));
1812 /* if float then do float stuff */
1813 if (IS_FLOAT(optype)) {
1814 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1818 /* otherwise subtract from zero by taking the 2's complement */
1819 size = AOP_SIZE(IC_LEFT(ic));
1821 for(i=0; i<size; i++) {
1822 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1823 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1825 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1826 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1830 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1831 for(i=1; i<size; i++) {
1833 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1837 /* release the aops */
1838 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1839 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1842 /*-----------------------------------------------------------------*/
1843 /* saveRegisters - will look for a call and save the registers */
1844 /*-----------------------------------------------------------------*/
1845 static void saveRegisters(iCode *lic)
1852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1854 for (ic = lic ; ic ; ic = ic->next)
1855 if (ic->op == CALL || ic->op == PCALL)
1859 fprintf(stderr,"found parameter push with no function call\n");
1863 /* if the registers have been saved already then
1865 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1868 /* find the registers in use at this time
1869 and push them away to safety */
1870 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1874 if (options.useXstack) {
1875 if (bitVectBitValue(rsave,R0_IDX))
1876 pic14_emitcode("mov","b,r0");
1877 pic14_emitcode("mov","r0,%s",spname);
1878 for (i = 0 ; i < pic14_nRegs ; i++) {
1879 if (bitVectBitValue(rsave,i)) {
1881 pic14_emitcode("mov","a,b");
1883 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1884 pic14_emitcode("movx","@r0,a");
1885 pic14_emitcode("inc","r0");
1888 pic14_emitcode("mov","%s,r0",spname);
1889 if (bitVectBitValue(rsave,R0_IDX))
1890 pic14_emitcode("mov","r0,b");
1892 for (i = 0 ; i < pic14_nRegs ; i++) {
1893 if (bitVectBitValue(rsave,i))
1894 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1897 dtype = operandType(IC_LEFT(ic));
1898 if (currFunc && dtype &&
1899 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1900 IFFUNC_ISISR(currFunc->type) &&
1903 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1906 /*-----------------------------------------------------------------*/
1907 /* unsaveRegisters - pop the pushed registers */
1908 /*-----------------------------------------------------------------*/
1909 static void unsaveRegisters (iCode *ic)
1914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1915 /* find the registers in use at this time
1916 and push them away to safety */
1917 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1920 if (options.useXstack) {
1921 pic14_emitcode("mov","r0,%s",spname);
1922 for (i = pic14_nRegs ; i >= 0 ; i--) {
1923 if (bitVectBitValue(rsave,i)) {
1924 pic14_emitcode("dec","r0");
1925 pic14_emitcode("movx","a,@r0");
1927 pic14_emitcode("mov","b,a");
1929 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1933 pic14_emitcode("mov","%s,r0",spname);
1934 if (bitVectBitValue(rsave,R0_IDX))
1935 pic14_emitcode("mov","r0,b");
1937 for (i = pic14_nRegs ; i >= 0 ; i--) {
1938 if (bitVectBitValue(rsave,i))
1939 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1945 /*-----------------------------------------------------------------*/
1947 /*-----------------------------------------------------------------*/
1948 static void pushSide(operand * oper, int size)
1952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1955 if (AOP_TYPE(oper) != AOP_REG &&
1956 AOP_TYPE(oper) != AOP_DIR &&
1958 pic14_emitcode("mov","a,%s",l);
1959 pic14_emitcode("push","acc");
1961 pic14_emitcode("push","%s",l);
1966 /*-----------------------------------------------------------------*/
1967 /* assignResultValue - */
1968 /*-----------------------------------------------------------------*/
1969 static void assignResultValue(operand * oper)
1971 int size = AOP_SIZE(oper);
1973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1975 if(!GpsuedoStkPtr) {
1976 /* The last byte in the assignment is in W */
1978 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1983 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1985 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1990 /*-----------------------------------------------------------------*/
1991 /* genIpush - genrate code for pushing this gets a little complex */
1992 /*-----------------------------------------------------------------*/
1993 static void genIpush (iCode *ic)
1996 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
1998 int size, offset = 0 ;
2002 /* if this is not a parm push : ie. it is spill push
2003 and spill push is always done on the local stack */
2004 if (!ic->parmPush) {
2006 /* and the item is spilt then do nothing */
2007 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2010 aopOp(IC_LEFT(ic),ic,FALSE);
2011 size = AOP_SIZE(IC_LEFT(ic));
2012 /* push it on the stack */
2014 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2019 pic14_emitcode("push","%s",l);
2024 /* this is a paramter push: in this case we call
2025 the routine to find the call and save those
2026 registers that need to be saved */
2029 /* then do the push */
2030 aopOp(IC_LEFT(ic),ic,FALSE);
2033 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2034 size = AOP_SIZE(IC_LEFT(ic));
2037 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2038 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2039 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2041 pic14_emitcode("mov","a,%s",l);
2042 pic14_emitcode("push","acc");
2044 pic14_emitcode("push","%s",l);
2047 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2051 /*-----------------------------------------------------------------*/
2052 /* genIpop - recover the registers: can happen only for spilling */
2053 /*-----------------------------------------------------------------*/
2054 static void genIpop (iCode *ic)
2056 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2061 /* if the temp was not pushed then */
2062 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2065 aopOp(IC_LEFT(ic),ic,FALSE);
2066 size = AOP_SIZE(IC_LEFT(ic));
2069 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2072 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2076 /*-----------------------------------------------------------------*/
2077 /* unsaverbank - restores the resgister bank from stack */
2078 /*-----------------------------------------------------------------*/
2079 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2081 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2089 if (options.useXstack) {
2091 r = getFreePtr(ic,&aop,FALSE);
2094 pic14_emitcode("mov","%s,_spx",r->name);
2095 pic14_emitcode("movx","a,@%s",r->name);
2096 pic14_emitcode("mov","psw,a");
2097 pic14_emitcode("dec","%s",r->name);
2100 pic14_emitcode ("pop","psw");
2103 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2104 if (options.useXstack) {
2105 pic14_emitcode("movx","a,@%s",r->name);
2106 //pic14_emitcode("mov","(%s+%d),a",
2107 // regspic14[i].base,8*bank+regspic14[i].offset);
2108 pic14_emitcode("dec","%s",r->name);
2111 pic14_emitcode("pop",""); //"(%s+%d)",
2112 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2115 if (options.useXstack) {
2117 pic14_emitcode("mov","_spx,%s",r->name);
2118 freeAsmop(NULL,aop,ic,TRUE);
2124 /*-----------------------------------------------------------------*/
2125 /* saverbank - saves an entire register bank on the stack */
2126 /*-----------------------------------------------------------------*/
2127 static void saverbank (int bank, iCode *ic, bool pushPsw)
2129 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2135 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2136 if (options.useXstack) {
2139 r = getFreePtr(ic,&aop,FALSE);
2140 pic14_emitcode("mov","%s,_spx",r->name);
2144 for (i = 0 ; i < pic14_nRegs ;i++) {
2145 if (options.useXstack) {
2146 pic14_emitcode("inc","%s",r->name);
2147 //pic14_emitcode("mov","a,(%s+%d)",
2148 // regspic14[i].base,8*bank+regspic14[i].offset);
2149 pic14_emitcode("movx","@%s,a",r->name);
2151 pic14_emitcode("push","");// "(%s+%d)",
2152 //regspic14[i].base,8*bank+regspic14[i].offset);
2156 if (options.useXstack) {
2157 pic14_emitcode("mov","a,psw");
2158 pic14_emitcode("movx","@%s,a",r->name);
2159 pic14_emitcode("inc","%s",r->name);
2160 pic14_emitcode("mov","_spx,%s",r->name);
2161 freeAsmop (NULL,aop,ic,TRUE);
2164 pic14_emitcode("push","psw");
2166 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2172 /*-----------------------------------------------------------------*/
2173 /* genCall - generates a call statement */
2174 /*-----------------------------------------------------------------*/
2175 static void genCall (iCode *ic)
2179 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2181 /* if caller saves & we have not saved then */
2185 /* if we are calling a function that is not using
2186 the same register bank then we need to save the
2187 destination registers on the stack */
2188 dtype = operandType(IC_LEFT(ic));
2189 if (currFunc && dtype &&
2190 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2191 IFFUNC_ISISR(currFunc->type) &&
2194 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2196 /* if send set is not empty the assign */
2199 /* For the Pic port, there is no data stack.
2200 * So parameters passed to functions are stored
2201 * in registers. (The pCode optimizer will get
2202 * rid of most of these :).
2204 int psuedoStkPtr=-1;
2205 int firstTimeThruLoop = 1;
2207 _G.sendSet = reverseSet(_G.sendSet);
2209 /* First figure how many parameters are getting passed */
2210 for (sic = setFirstItem(_G.sendSet) ; sic ;
2211 sic = setNextItem(_G.sendSet)) {
2213 aopOp(IC_LEFT(sic),sic,FALSE);
2214 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2215 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2218 for (sic = setFirstItem(_G.sendSet) ; sic ;
2219 sic = setNextItem(_G.sendSet)) {
2220 int size, offset = 0;
2222 aopOp(IC_LEFT(sic),sic,FALSE);
2223 size = AOP_SIZE(IC_LEFT(sic));
2227 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2228 AopType(AOP_TYPE(IC_LEFT(sic))));
2230 if(!firstTimeThruLoop) {
2231 /* If this is not the first time we've been through the loop
2232 * then we need to save the parameter in a temporary
2233 * register. The last byte of the last parameter is
2235 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2238 firstTimeThruLoop=0;
2240 //if (strcmp(l,fReturn[offset])) {
2242 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2243 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2244 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2246 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2251 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2256 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2257 OP_SYMBOL(IC_LEFT(ic))->rname :
2258 OP_SYMBOL(IC_LEFT(ic))->name));
2261 /* if we need assign a result value */
2262 if ((IS_ITEMP(IC_RESULT(ic)) &&
2263 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2264 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2265 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2268 aopOp(IC_RESULT(ic),ic,FALSE);
2271 assignResultValue(IC_RESULT(ic));
2273 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2274 AopType(AOP_TYPE(IC_RESULT(ic))));
2276 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2279 /* adjust the stack for parameters if
2281 if (ic->parmBytes) {
2283 if (ic->parmBytes > 3) {
2284 pic14_emitcode("mov","a,%s",spname);
2285 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2286 pic14_emitcode("mov","%s,a",spname);
2288 for ( i = 0 ; i < ic->parmBytes ;i++)
2289 pic14_emitcode("dec","%s",spname);
2293 /* if register bank was saved then pop them */
2295 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2297 /* if we hade saved some registers then unsave them */
2298 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2299 unsaveRegisters (ic);
2304 /*-----------------------------------------------------------------*/
2305 /* genPcall - generates a call by pointer statement */
2306 /*-----------------------------------------------------------------*/
2307 static void genPcall (iCode *ic)
2310 symbol *rlbl = newiTempLabel(NULL);
2313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2314 /* if caller saves & we have not saved then */
2318 /* if we are calling a function that is not using
2319 the same register bank then we need to save the
2320 destination registers on the stack */
2321 dtype = operandType(IC_LEFT(ic));
2322 if (currFunc && dtype &&
2323 IFFUNC_ISISR(currFunc->type) &&
2324 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2325 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2328 /* push the return address on to the stack */
2329 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2330 pic14_emitcode("push","acc");
2331 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2332 pic14_emitcode("push","acc");
2334 if (options.model == MODEL_FLAT24)
2336 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2337 pic14_emitcode("push","acc");
2340 /* now push the calling address */
2341 aopOp(IC_LEFT(ic),ic,FALSE);
2343 pushSide(IC_LEFT(ic), FPTRSIZE);
2345 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2347 /* if send set is not empty the assign */
2351 for (sic = setFirstItem(_G.sendSet) ; sic ;
2352 sic = setNextItem(_G.sendSet)) {
2353 int size, offset = 0;
2354 aopOp(IC_LEFT(sic),sic,FALSE);
2355 size = AOP_SIZE(IC_LEFT(sic));
2357 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2359 if (strcmp(l,fReturn[offset]))
2360 pic14_emitcode("mov","%s,%s",
2365 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2370 pic14_emitcode("ret","");
2371 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2374 /* if we need assign a result value */
2375 if ((IS_ITEMP(IC_RESULT(ic)) &&
2376 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2377 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2378 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2381 aopOp(IC_RESULT(ic),ic,FALSE);
2384 assignResultValue(IC_RESULT(ic));
2386 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2389 /* adjust the stack for parameters if
2391 if (ic->parmBytes) {
2393 if (ic->parmBytes > 3) {
2394 pic14_emitcode("mov","a,%s",spname);
2395 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2396 pic14_emitcode("mov","%s,a",spname);
2398 for ( i = 0 ; i < ic->parmBytes ;i++)
2399 pic14_emitcode("dec","%s",spname);
2403 /* if register bank was saved then unsave them */
2404 if (currFunc && dtype &&
2405 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2406 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2408 /* if we hade saved some registers then
2411 unsaveRegisters (ic);
2415 /*-----------------------------------------------------------------*/
2416 /* resultRemat - result is rematerializable */
2417 /*-----------------------------------------------------------------*/
2418 static int resultRemat (iCode *ic)
2420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2421 if (SKIP_IC(ic) || ic->op == IFX)
2424 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2425 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2426 if (sym->remat && !POINTER_SET(ic))
2433 #if defined(__BORLANDC__) || defined(_MSC_VER)
2434 #define STRCASECMP stricmp
2436 #define STRCASECMP strcasecmp
2439 /*-----------------------------------------------------------------*/
2440 /* inExcludeList - return 1 if the string is in exclude Reg list */
2441 /*-----------------------------------------------------------------*/
2442 static bool inExcludeList(char *s)
2444 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2449 if (options.excludeRegs[i] &&
2450 STRCASECMP(options.excludeRegs[i],"none") == 0)
2453 for ( i = 0 ; options.excludeRegs[i]; i++) {
2454 if (options.excludeRegs[i] &&
2455 STRCASECMP(s,options.excludeRegs[i]) == 0)
2462 /*-----------------------------------------------------------------*/
2463 /* genFunction - generated code for function entry */
2464 /*-----------------------------------------------------------------*/
2465 static void genFunction (iCode *ic)
2470 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2472 labelOffset += (max_key+4);
2476 /* create the function header */
2477 pic14_emitcode(";","-----------------------------------------");
2478 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2479 pic14_emitcode(";","-----------------------------------------");
2481 pic14_emitcode("","%s:",sym->rname);
2482 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2484 ftype = operandType(IC_LEFT(ic));
2486 /* if critical function then turn interrupts off */
2487 if (IFFUNC_ISCRITICAL(ftype))
2488 pic14_emitcode("clr","ea");
2490 /* here we need to generate the equates for the
2491 register bank if required */
2493 if (FUNC_REGBANK(ftype) != rbank) {
2496 rbank = FUNC_REGBANK(ftype);
2497 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2498 if (strcmp(regspic14[i].base,"0") == 0)
2499 pic14_emitcode("","%s = 0x%02x",
2501 8*rbank+regspic14[i].offset);
2503 pic14_emitcode ("","%s = %s + 0x%02x",
2506 8*rbank+regspic14[i].offset);
2511 /* if this is an interrupt service routine then
2512 save acc, b, dpl, dph */
2513 if (IFFUNC_ISISR(sym->type)) {
2515 if (!inExcludeList("acc"))
2516 pic14_emitcode ("push","acc");
2517 if (!inExcludeList("b"))
2518 pic14_emitcode ("push","b");
2519 if (!inExcludeList("dpl"))
2520 pic14_emitcode ("push","dpl");
2521 if (!inExcludeList("dph"))
2522 pic14_emitcode ("push","dph");
2523 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2525 pic14_emitcode ("push", "dpx");
2526 /* Make sure we're using standard DPTR */
2527 pic14_emitcode ("push", "dps");
2528 pic14_emitcode ("mov", "dps, #0x00");
2529 if (options.stack10bit)
2531 /* This ISR could conceivably use DPTR2. Better save it. */
2532 pic14_emitcode ("push", "dpl1");
2533 pic14_emitcode ("push", "dph1");
2534 pic14_emitcode ("push", "dpx1");
2537 /* if this isr has no bank i.e. is going to
2538 run with bank 0 , then we need to save more
2540 if (!FUNC_REGBANK(sym->type)) {
2542 /* if this function does not call any other
2543 function then we can be economical and
2544 save only those registers that are used */
2545 if (! IFFUNC_HASFCALL(sym->type)) {
2548 /* if any registers used */
2549 if (sym->regsUsed) {
2550 /* save the registers used */
2551 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2552 if (bitVectBitValue(sym->regsUsed,i) ||
2553 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2554 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2559 /* this function has a function call cannot
2560 determines register usage so we will have the
2562 saverbank(0,ic,FALSE);
2566 /* if callee-save to be used for this function
2567 then save the registers being used in this function */
2568 if (IFFUNC_CALLEESAVES(sym->type)) {
2571 /* if any registers used */
2572 if (sym->regsUsed) {
2573 /* save the registers used */
2574 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2575 if (bitVectBitValue(sym->regsUsed,i) ||
2576 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2577 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2585 /* set the register bank to the desired value */
2586 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2587 pic14_emitcode("push","psw");
2588 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2591 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2593 if (options.useXstack) {
2594 pic14_emitcode("mov","r0,%s",spname);
2595 pic14_emitcode("mov","a,_bp");
2596 pic14_emitcode("movx","@r0,a");
2597 pic14_emitcode("inc","%s",spname);
2601 /* set up the stack */
2602 pic14_emitcode ("push","_bp"); /* save the callers stack */
2604 pic14_emitcode ("mov","_bp,%s",spname);
2607 /* adjust the stack for the function */
2612 werror(W_STACK_OVERFLOW,sym->name);
2614 if (i > 3 && sym->recvSize < 4) {
2616 pic14_emitcode ("mov","a,sp");
2617 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2618 pic14_emitcode ("mov","sp,a");
2623 pic14_emitcode("inc","sp");
2628 pic14_emitcode ("mov","a,_spx");
2629 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2630 pic14_emitcode ("mov","_spx,a");
2635 /*-----------------------------------------------------------------*/
2636 /* genEndFunction - generates epilogue for functions */
2637 /*-----------------------------------------------------------------*/
2638 static void genEndFunction (iCode *ic)
2640 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2644 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2646 pic14_emitcode ("mov","%s,_bp",spname);
2649 /* if use external stack but some variables were
2650 added to the local stack then decrement the
2652 if (options.useXstack && sym->stack) {
2653 pic14_emitcode("mov","a,sp");
2654 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2655 pic14_emitcode("mov","sp,a");
2659 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2660 if (options.useXstack) {
2661 pic14_emitcode("mov","r0,%s",spname);
2662 pic14_emitcode("movx","a,@r0");
2663 pic14_emitcode("mov","_bp,a");
2664 pic14_emitcode("dec","%s",spname);
2668 pic14_emitcode ("pop","_bp");
2672 /* restore the register bank */
2673 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2674 pic14_emitcode ("pop","psw");
2676 if (IFFUNC_ISISR(sym->type)) {
2678 /* now we need to restore the registers */
2679 /* if this isr has no bank i.e. is going to
2680 run with bank 0 , then we need to save more
2682 if (!FUNC_REGBANK(sym->type)) {
2684 /* if this function does not call any other
2685 function then we can be economical and
2686 save only those registers that are used */
2687 if (! IFFUNC_HASFCALL(sym->type)) {
2690 /* if any registers used */
2691 if (sym->regsUsed) {
2692 /* save the registers used */
2693 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2694 if (bitVectBitValue(sym->regsUsed,i) ||
2695 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2696 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2701 /* this function has a function call cannot
2702 determines register usage so we will have the
2704 unsaverbank(0,ic,FALSE);
2708 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2710 if (options.stack10bit)
2712 pic14_emitcode ("pop", "dpx1");
2713 pic14_emitcode ("pop", "dph1");
2714 pic14_emitcode ("pop", "dpl1");
2716 pic14_emitcode ("pop", "dps");
2717 pic14_emitcode ("pop", "dpx");
2719 if (!inExcludeList("dph"))
2720 pic14_emitcode ("pop","dph");
2721 if (!inExcludeList("dpl"))
2722 pic14_emitcode ("pop","dpl");
2723 if (!inExcludeList("b"))
2724 pic14_emitcode ("pop","b");
2725 if (!inExcludeList("acc"))
2726 pic14_emitcode ("pop","acc");
2728 if (IFFUNC_ISCRITICAL(sym->type))
2729 pic14_emitcode("setb","ea");
2731 /* if debug then send end of function */
2732 /* if (options.debug && currFunc) { */
2735 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2736 FileBaseName(ic->filename),currFunc->lastLine,
2737 ic->level,ic->block);
2738 if (IS_STATIC(currFunc->etype))
2739 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2741 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2745 pic14_emitcode ("reti","");
2748 if (IFFUNC_ISCRITICAL(sym->type))
2749 pic14_emitcode("setb","ea");
2751 if (IFFUNC_CALLEESAVES(sym->type)) {
2754 /* if any registers used */
2755 if (sym->regsUsed) {
2756 /* save the registers used */
2757 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2758 if (bitVectBitValue(sym->regsUsed,i) ||
2759 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2760 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2766 /* if debug then send end of function */
2769 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2770 FileBaseName(ic->filename),currFunc->lastLine,
2771 ic->level,ic->block);
2772 if (IS_STATIC(currFunc->etype))
2773 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2775 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2779 pic14_emitcode ("return","");
2780 emitpcodeNULLop(POC_RETURN);
2782 /* Mark the end of a function */
2783 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2788 /*-----------------------------------------------------------------*/
2789 /* genRet - generate code for return statement */
2790 /*-----------------------------------------------------------------*/
2791 static void genRet (iCode *ic)
2793 int size,offset = 0 , pushed = 0;
2795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2796 /* if we have no return value then
2797 just generate the "ret" */
2801 /* we have something to return then
2802 move the return value into place */
2803 aopOp(IC_LEFT(ic),ic,FALSE);
2804 size = AOP_SIZE(IC_LEFT(ic));
2808 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2810 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2812 pic14_emitcode("push","%s",l);
2815 l = aopGet(AOP(IC_LEFT(ic)),offset,
2817 if (strcmp(fReturn[offset],l)) {
2818 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2819 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2820 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2822 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2825 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2826 pic14_emitcode("movwf","%s",fReturn[offset]);
2836 if (strcmp(fReturn[pushed],"a"))
2837 pic14_emitcode("pop",fReturn[pushed]);
2839 pic14_emitcode("pop","acc");
2842 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2845 /* generate a jump to the return label
2846 if the next is not the return statement */
2847 if (!(ic->next && ic->next->op == LABEL &&
2848 IC_LABEL(ic->next) == returnLabel)) {
2850 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2851 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2856 /*-----------------------------------------------------------------*/
2857 /* genLabel - generates a label */
2858 /*-----------------------------------------------------------------*/
2859 static void genLabel (iCode *ic)
2861 /* special case never generate */
2862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2863 if (IC_LABEL(ic) == entryLabel)
2866 emitpLabel(IC_LABEL(ic)->key);
2867 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2870 /*-----------------------------------------------------------------*/
2871 /* genGoto - generates a goto */
2872 /*-----------------------------------------------------------------*/
2874 static void genGoto (iCode *ic)
2876 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2877 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2881 /*-----------------------------------------------------------------*/
2882 /* genMultbits :- multiplication of bits */
2883 /*-----------------------------------------------------------------*/
2884 static void genMultbits (operand *left,
2888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2890 if(!pic14_sameRegs(AOP(result),AOP(right)))
2891 emitpcode(POC_BSF, popGet(AOP(result),0));
2893 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2894 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2895 emitpcode(POC_BCF, popGet(AOP(result),0));
2900 /*-----------------------------------------------------------------*/
2901 /* genMultOneByte : 8 bit multiplication & division */
2902 /*-----------------------------------------------------------------*/
2903 static void genMultOneByte (operand *left,
2907 sym_link *opetype = operandType(result);
2912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2913 DEBUGpic14_AopType(__LINE__,left,right,result);
2915 /* (if two literals, the value is computed before) */
2916 /* if one literal, literal on the right */
2917 if (AOP_TYPE(left) == AOP_LIT){
2923 size = AOP_SIZE(result);
2924 /* signed or unsigned */
2925 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2926 l = aopGet(AOP(left),0,FALSE,FALSE);
2928 pic14_emitcode("mul","ab");
2929 /* if result size = 1, mul signed = mul unsigned */
2930 aopPut(AOP(result),"a",0);
2932 if (SPEC_USIGN(opetype)){
2933 aopPut(AOP(result),"b",1);
2935 /* for filling the MSBs */
2936 pic14_emitcode("clr","a");
2939 pic14_emitcode("mov","a,b");
2941 /* adjust the MSB if left or right neg */
2943 /* if one literal */
2944 if (AOP_TYPE(right) == AOP_LIT){
2945 /* AND literal negative */
2946 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2947 /* adjust MSB (c==0 after mul) */
2948 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2952 lbl = newiTempLabel(NULL);
2953 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2954 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2955 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2956 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2957 lbl = newiTempLabel(NULL);
2958 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2959 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2960 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2963 lbl = newiTempLabel(NULL);
2964 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2965 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2966 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2967 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2968 lbl = newiTempLabel(NULL);
2969 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2970 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2971 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2973 aopPut(AOP(result),"a",1);
2976 pic14_emitcode("rlc","a");
2977 pic14_emitcode("subb","a,acc");
2984 aopPut(AOP(result),"a",offset++);
2988 /*-----------------------------------------------------------------*/
2989 /* genMult - generates code for multiplication */
2990 /*-----------------------------------------------------------------*/
2991 static void genMult (iCode *ic)
2993 operand *left = IC_LEFT(ic);
2994 operand *right = IC_RIGHT(ic);
2995 operand *result= IC_RESULT(ic);
2997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2998 /* assign the amsops */
2999 aopOp (left,ic,FALSE);
3000 aopOp (right,ic,FALSE);
3001 aopOp (result,ic,TRUE);
3003 DEBUGpic14_AopType(__LINE__,left,right,result);
3005 /* special cases first */
3007 if (AOP_TYPE(left) == AOP_CRY &&
3008 AOP_TYPE(right)== AOP_CRY) {
3009 genMultbits(left,right,result);
3013 /* if both are of size == 1 */
3014 if (AOP_SIZE(left) == 1 &&
3015 AOP_SIZE(right) == 1 ) {
3016 genMultOneByte(left,right,result);
3020 /* should have been converted to function call */
3024 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3025 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3026 freeAsmop(result,NULL,ic,TRUE);
3029 /*-----------------------------------------------------------------*/
3030 /* genDivbits :- division of bits */
3031 /*-----------------------------------------------------------------*/
3032 static void genDivbits (operand *left,
3039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3040 /* the result must be bit */
3041 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3042 l = aopGet(AOP(left),0,FALSE,FALSE);
3046 pic14_emitcode("div","ab");
3047 pic14_emitcode("rrc","a");
3048 aopPut(AOP(result),"c",0);
3051 /*-----------------------------------------------------------------*/
3052 /* genDivOneByte : 8 bit division */
3053 /*-----------------------------------------------------------------*/
3054 static void genDivOneByte (operand *left,
3058 sym_link *opetype = operandType(result);
3063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3064 size = AOP_SIZE(result) - 1;
3066 /* signed or unsigned */
3067 if (SPEC_USIGN(opetype)) {
3068 /* unsigned is easy */
3069 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3070 l = aopGet(AOP(left),0,FALSE,FALSE);
3072 pic14_emitcode("div","ab");
3073 aopPut(AOP(result),"a",0);
3075 aopPut(AOP(result),zero,offset++);
3079 /* signed is a little bit more difficult */
3081 /* save the signs of the operands */
3082 l = aopGet(AOP(left),0,FALSE,FALSE);
3084 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3085 pic14_emitcode("push","acc"); /* save it on the stack */
3087 /* now sign adjust for both left & right */
3088 l = aopGet(AOP(right),0,FALSE,FALSE);
3090 lbl = newiTempLabel(NULL);
3091 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3092 pic14_emitcode("cpl","a");
3093 pic14_emitcode("inc","a");
3094 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3095 pic14_emitcode("mov","b,a");
3097 /* sign adjust left side */
3098 l = aopGet(AOP(left),0,FALSE,FALSE);
3101 lbl = newiTempLabel(NULL);
3102 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3103 pic14_emitcode("cpl","a");
3104 pic14_emitcode("inc","a");
3105 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3107 /* now the division */
3108 pic14_emitcode("div","ab");
3109 /* we are interested in the lower order
3111 pic14_emitcode("mov","b,a");
3112 lbl = newiTempLabel(NULL);
3113 pic14_emitcode("pop","acc");
3114 /* if there was an over flow we don't
3115 adjust the sign of the result */
3116 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3117 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3119 pic14_emitcode("clr","a");
3120 pic14_emitcode("subb","a,b");
3121 pic14_emitcode("mov","b,a");
3122 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3124 /* now we are done */
3125 aopPut(AOP(result),"b",0);
3127 pic14_emitcode("mov","c,b.7");
3128 pic14_emitcode("subb","a,acc");
3131 aopPut(AOP(result),"a",offset++);
3135 /*-----------------------------------------------------------------*/
3136 /* genDiv - generates code for division */
3137 /*-----------------------------------------------------------------*/
3138 static void genDiv (iCode *ic)
3140 operand *left = IC_LEFT(ic);
3141 operand *right = IC_RIGHT(ic);
3142 operand *result= IC_RESULT(ic);
3144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3145 /* assign the amsops */
3146 aopOp (left,ic,FALSE);
3147 aopOp (right,ic,FALSE);
3148 aopOp (result,ic,TRUE);
3150 /* special cases first */
3152 if (AOP_TYPE(left) == AOP_CRY &&
3153 AOP_TYPE(right)== AOP_CRY) {
3154 genDivbits(left,right,result);
3158 /* if both are of size == 1 */
3159 if (AOP_SIZE(left) == 1 &&
3160 AOP_SIZE(right) == 1 ) {
3161 genDivOneByte(left,right,result);
3165 /* should have been converted to function call */
3168 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3169 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3170 freeAsmop(result,NULL,ic,TRUE);
3173 /*-----------------------------------------------------------------*/
3174 /* genModbits :- modulus of bits */
3175 /*-----------------------------------------------------------------*/
3176 static void genModbits (operand *left,
3183 /* the result must be bit */
3184 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3185 l = aopGet(AOP(left),0,FALSE,FALSE);
3189 pic14_emitcode("div","ab");
3190 pic14_emitcode("mov","a,b");
3191 pic14_emitcode("rrc","a");
3192 aopPut(AOP(result),"c",0);
3195 /*-----------------------------------------------------------------*/
3196 /* genModOneByte : 8 bit modulus */
3197 /*-----------------------------------------------------------------*/
3198 static void genModOneByte (operand *left,
3202 sym_link *opetype = operandType(result);
3206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3207 /* signed or unsigned */
3208 if (SPEC_USIGN(opetype)) {
3209 /* unsigned is easy */
3210 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3211 l = aopGet(AOP(left),0,FALSE,FALSE);
3213 pic14_emitcode("div","ab");
3214 aopPut(AOP(result),"b",0);
3218 /* signed is a little bit more difficult */
3220 /* save the signs of the operands */
3221 l = aopGet(AOP(left),0,FALSE,FALSE);
3224 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3225 pic14_emitcode("push","acc"); /* save it on the stack */
3227 /* now sign adjust for both left & right */
3228 l = aopGet(AOP(right),0,FALSE,FALSE);
3231 lbl = newiTempLabel(NULL);
3232 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3233 pic14_emitcode("cpl","a");
3234 pic14_emitcode("inc","a");
3235 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3236 pic14_emitcode("mov","b,a");
3238 /* sign adjust left side */
3239 l = aopGet(AOP(left),0,FALSE,FALSE);
3242 lbl = newiTempLabel(NULL);
3243 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3244 pic14_emitcode("cpl","a");
3245 pic14_emitcode("inc","a");
3246 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3248 /* now the multiplication */
3249 pic14_emitcode("div","ab");
3250 /* we are interested in the lower order
3252 lbl = newiTempLabel(NULL);
3253 pic14_emitcode("pop","acc");
3254 /* if there was an over flow we don't
3255 adjust the sign of the result */
3256 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3257 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3259 pic14_emitcode("clr","a");
3260 pic14_emitcode("subb","a,b");
3261 pic14_emitcode("mov","b,a");
3262 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3264 /* now we are done */
3265 aopPut(AOP(result),"b",0);
3269 /*-----------------------------------------------------------------*/
3270 /* genMod - generates code for division */
3271 /*-----------------------------------------------------------------*/
3272 static void genMod (iCode *ic)
3274 operand *left = IC_LEFT(ic);
3275 operand *right = IC_RIGHT(ic);
3276 operand *result= IC_RESULT(ic);
3278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3279 /* assign the amsops */
3280 aopOp (left,ic,FALSE);
3281 aopOp (right,ic,FALSE);
3282 aopOp (result,ic,TRUE);
3284 /* special cases first */
3286 if (AOP_TYPE(left) == AOP_CRY &&
3287 AOP_TYPE(right)== AOP_CRY) {
3288 genModbits(left,right,result);
3292 /* if both are of size == 1 */
3293 if (AOP_SIZE(left) == 1 &&
3294 AOP_SIZE(right) == 1 ) {
3295 genModOneByte(left,right,result);
3299 /* should have been converted to function call */
3303 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3304 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3305 freeAsmop(result,NULL,ic,TRUE);
3308 /*-----------------------------------------------------------------*/
3309 /* genIfxJump :- will create a jump depending on the ifx */
3310 /*-----------------------------------------------------------------*/
3312 note: May need to add parameter to indicate when a variable is in bit space.
3314 static void genIfxJump (iCode *ic, char *jval)
3317 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3318 /* if true label then we jump if condition
3320 if ( IC_TRUE(ic) ) {
3322 if(strcmp(jval,"a") == 0)
3324 else if (strcmp(jval,"c") == 0)
3327 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3328 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3331 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3332 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3336 /* false label is present */
3337 if(strcmp(jval,"a") == 0)
3339 else if (strcmp(jval,"c") == 0)
3342 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3343 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3346 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3347 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3352 /* mark the icode as generated */
3356 /*-----------------------------------------------------------------*/
3358 /*-----------------------------------------------------------------*/
3359 static void genSkip(iCode *ifx,int status_bit)
3364 if ( IC_TRUE(ifx) ) {
3365 switch(status_bit) {
3380 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3381 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3385 switch(status_bit) {
3399 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3400 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3406 /*-----------------------------------------------------------------*/
3408 /*-----------------------------------------------------------------*/
3409 static void genSkipc(resolvedIfx *rifx)
3419 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3420 rifx->generated = 1;
3423 /*-----------------------------------------------------------------*/
3425 /*-----------------------------------------------------------------*/
3426 static void genSkipz2(resolvedIfx *rifx)
3436 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3437 rifx->generated = 1;
3440 /*-----------------------------------------------------------------*/
3442 /*-----------------------------------------------------------------*/
3443 static void genSkipz(iCode *ifx, int condition)
3454 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3456 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3459 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3461 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3464 /*-----------------------------------------------------------------*/
3466 /*-----------------------------------------------------------------*/
3467 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3473 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3475 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3478 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3479 rifx->generated = 1;
3483 /*-----------------------------------------------------------------*/
3484 /* genChkZeroes :- greater or less than comparison */
3485 /* For each byte in a literal that is zero, inclusive or the */
3486 /* the corresponding byte in the operand with W */
3487 /* returns true if any of the bytes are zero */
3488 /*-----------------------------------------------------------------*/
3489 static int genChkZeroes(operand *op, int lit, int size)
3496 i = (lit >> (size*8)) & 0xff;
3500 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3502 emitpcode(POC_IORFW, popGet(AOP(op),size));
3511 /*-----------------------------------------------------------------*/
3512 /* genCmp :- greater or less than comparison */
3513 /*-----------------------------------------------------------------*/
3514 static void genCmp (operand *left,operand *right,
3515 operand *result, iCode *ifx, int sign)
3517 int size, offset = 0 ;
3518 unsigned long lit = 0L,i = 0;
3519 resolvedIfx rFalseIfx;
3520 // resolvedIfx rTrueIfx;
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"));
3529 resolveIfx(&rFalseIfx,ifx);
3530 truelbl = newiTempLabel(NULL);
3532 //if(IC_TRUE(ifx) == NULL)
3533 /* if left & right are bit variables */
3534 if (AOP_TYPE(left) == AOP_CRY &&
3535 AOP_TYPE(right) == AOP_CRY ) {
3536 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3537 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3539 /* subtract right from left if at the
3540 end the carry flag is set then we know that
3541 left is greater than right */
3542 size = max(AOP_SIZE(left),AOP_SIZE(right));
3544 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3545 if((size == 1) && !sign &&
3546 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3547 symbol *lbl = newiTempLabel(NULL);
3548 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3549 aopGet(AOP(left),offset,FALSE,FALSE),
3550 aopGet(AOP(right),offset,FALSE,FALSE),
3552 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3555 symbol *lbl = newiTempLabel(NULL);
3557 if(AOP_TYPE(right) == AOP_LIT) {
3559 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3561 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3568 genSkipCond(&rFalseIfx,left,size-1,7);
3570 /* no need to compare to 0...*/
3571 /* NOTE: this is a de-generate compare that most certainly
3572 * creates some dead code. */
3573 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3575 if(ifx) ifx->generated = 1;
3582 //i = (lit >> (size*8)) & 0xff;
3583 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3585 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3587 i = ((0-lit) & 0xff);
3590 /* lit is 0x7f, all signed chars are less than
3591 * this except for 0x7f itself */
3592 emitpcode(POC_XORLW, popGetLit(0x7f));
3593 genSkipz2(&rFalseIfx);
3595 emitpcode(POC_ADDLW, popGetLit(0x80));
3596 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3597 genSkipc(&rFalseIfx);
3601 emitpcode(POC_ADDLW, popGetLit(i));
3602 genSkipc(&rFalseIfx);
3606 if(ifx) ifx->generated = 1;
3610 /* chars are out of the way. now do ints and longs */
3613 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3620 genSkipCond(&rFalseIfx,left,size,7);
3621 if(ifx) ifx->generated = 1;
3626 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3628 //rFalseIfx.condition ^= 1;
3629 //genSkipCond(&rFalseIfx,left,size,7);
3630 //rFalseIfx.condition ^= 1;
3632 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3633 if(rFalseIfx.condition)
3634 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3636 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3638 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3639 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3640 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3643 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3645 if(rFalseIfx.condition) {
3647 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3653 genSkipc(&rFalseIfx);
3654 emitpLabel(truelbl->key);
3655 if(ifx) ifx->generated = 1;
3662 if( (lit & 0xff) == 0) {
3663 /* lower byte is zero */
3664 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3665 i = ((lit >> 8) & 0xff) ^0x80;
3666 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3667 emitpcode(POC_ADDLW, popGetLit( 0x80));
3668 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3669 genSkipc(&rFalseIfx);
3672 if(ifx) ifx->generated = 1;
3677 /* Special cases for signed longs */
3678 if( (lit & 0xffffff) == 0) {
3679 /* lower byte is zero */
3680 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3681 i = ((lit >> 8*3) & 0xff) ^0x80;
3682 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3683 emitpcode(POC_ADDLW, popGetLit( 0x80));
3684 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3685 genSkipc(&rFalseIfx);
3688 if(ifx) ifx->generated = 1;
3696 if(lit & (0x80 << (size*8))) {
3697 /* lit is negative */
3698 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3700 //genSkipCond(&rFalseIfx,left,size,7);
3702 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3704 if(rFalseIfx.condition)
3705 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3707 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3711 /* lit is positive */
3712 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3713 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3714 if(rFalseIfx.condition)
3715 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3717 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3719 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3720 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3721 //rFalseIfx.condition ^= 1;
3722 //genSkipCond(&rFalseIfx,left,size,7);
3723 //rFalseIfx.condition ^= 1;
3727 This works, but is only good for ints.
3728 It also requires a "known zero" register.
3729 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3730 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3731 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3732 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3733 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3734 genSkipc(&rFalseIfx);
3736 emitpLabel(truelbl->key);
3737 if(ifx) ifx->generated = 1;
3741 /* There are no more special cases, so perform a general compare */
3743 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3744 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3748 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3750 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3752 //rFalseIfx.condition ^= 1;
3753 genSkipc(&rFalseIfx);
3755 emitpLabel(truelbl->key);
3757 if(ifx) ifx->generated = 1;
3764 /* sign is out of the way. So now do an unsigned compare */
3765 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3768 //genChkZeroes(left)
3770 /* General case - compare to an unsigned literal on the right.*/
3772 i = (lit >> (size*8)) & 0xff;
3773 emitpcode(POC_MOVLW, popGetLit(i));
3774 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3776 i = (lit >> (size*8)) & 0xff;
3779 emitpcode(POC_MOVLW, popGetLit(i));
3781 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3783 /* this byte of the lit is zero,
3784 *if it's not the last then OR in the variable */
3786 emitpcode(POC_IORFW, popGet(AOP(left),size));
3791 emitpLabel(lbl->key);
3792 //if(emitFinalCheck)
3793 genSkipc(&rFalseIfx);
3795 emitpLabel(truelbl->key);
3797 if(ifx) ifx->generated = 1;
3803 if(AOP_TYPE(left) == AOP_LIT) {
3804 //symbol *lbl = newiTempLabel(NULL);
3806 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3809 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3812 if((lit == 0) && (sign == 0)){
3815 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3817 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3819 //rFalseIfx.condition ^= 1;
3820 genSkipz2(&rFalseIfx);
3821 if(ifx) ifx->generated = 1;
3828 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3829 /* degenerate compare can never be true */
3830 if(rFalseIfx.condition == 0)
3831 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3833 if(ifx) ifx->generated = 1;
3839 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3840 emitpcode(POC_ADDLW, popGetLit(0x80));
3841 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3842 rFalseIfx.condition ^= 1;
3843 genSkipc(&rFalseIfx);
3845 rFalseIfx.condition ^= 1;
3846 genSkipCond(&rFalseIfx,right,0,7);
3851 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3852 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3854 rFalseIfx.condition ^= 1;
3855 genSkipc(&rFalseIfx);
3857 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3858 genSkipz2(&rFalseIfx);
3862 if(ifx) ifx->generated = 1;
3867 /* Size is greater than 1 */
3877 /* this means lit = 0xffffffff, or -1 */
3880 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
3881 rFalseIfx.condition ^= 1;
3882 genSkipCond(&rFalseIfx,right,size,7);
3883 if(ifx) ifx->generated = 1;
3890 if(rFalseIfx.condition) {
3891 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3892 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3895 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3897 emitpcode(POC_IORFW, popGet(AOP(right),size));
3901 if(rFalseIfx.condition) {
3902 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3903 emitpLabel(truelbl->key);
3905 rFalseIfx.condition ^= 1;
3906 genSkipCond(&rFalseIfx,right,s,7);
3909 if(ifx) ifx->generated = 1;
3914 if(lit & (0x80 << (size*8))) {
3915 /* Lit is less than zero */
3916 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
3917 //rFalseIfx.condition ^= 1;
3918 //genSkipCond(&rFalseIfx,left,size,7);
3919 //rFalseIfx.condition ^= 1;
3920 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3921 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3923 if(rFalseIfx.condition)
3924 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3926 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3930 /* Lit is greater than or equal to zero */
3931 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
3932 //rFalseIfx.condition ^= 1;
3933 //genSkipCond(&rFalseIfx,right,size,7);
3934 //rFalseIfx.condition ^= 1;
3936 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3937 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3939 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3940 if(rFalseIfx.condition)
3941 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3943 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3946 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3947 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3951 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3953 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3955 rFalseIfx.condition ^= 1;
3956 //rFalseIfx.condition = 1;
3957 genSkipc(&rFalseIfx);
3959 emitpLabel(truelbl->key);
3961 if(ifx) ifx->generated = 1;
3965 /* Unsigned compare for sizes greater than 1 */
3968 i = (lit >> (size*8)) & 0xff;
3972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3973 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3974 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3976 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3978 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3979 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3980 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3987 emitpLabel(lbl->key);
3989 rFalseIfx.condition ^= 1;
3990 genSkipc(&rFalseIfx);
3994 emitpLabel(truelbl->key);
3995 if(ifx) ifx->generated = 1;
3999 /* Compare two variables */
4001 DEBUGpic14_emitcode(";sign","%d",sign);
4005 /* Sigh. thus sucks... */
4007 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4008 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4009 emitpcode(POC_MOVLW, popGetLit(0x80));
4010 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4011 emitpcode(POC_XORFW, popGet(AOP(right),size));
4012 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4014 /* Signed char comparison */
4015 /* Special thanks to Nikolai Golovchenko for this snippet */
4016 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4017 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4018 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4019 emitpcode(POC_XORFW, popGet(AOP(left),0));
4020 emitpcode(POC_XORFW, popGet(AOP(right),0));
4021 emitpcode(POC_ADDLW, popGetLit(0x80));
4023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4024 genSkipc(&rFalseIfx);
4026 if(ifx) ifx->generated = 1;
4032 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4033 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4037 /* The rest of the bytes of a multi-byte compare */
4041 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4044 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4045 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4050 emitpLabel(lbl->key);
4052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4053 genSkipc(&rFalseIfx);
4054 if(ifx) ifx->generated = 1;
4061 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4062 pic14_outBitC(result);
4064 /* if the result is used in the next
4065 ifx conditional branch then generate
4066 code a little differently */
4068 genIfxJump (ifx,"c");
4070 pic14_outBitC(result);
4071 /* leave the result in acc */
4076 /*-----------------------------------------------------------------*/
4077 /* genCmpGt :- greater than comparison */
4078 /*-----------------------------------------------------------------*/
4079 static void genCmpGt (iCode *ic, iCode *ifx)
4081 operand *left, *right, *result;
4082 sym_link *letype , *retype;
4085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4087 right= IC_RIGHT(ic);
4088 result = IC_RESULT(ic);
4090 letype = getSpec(operandType(left));
4091 retype =getSpec(operandType(right));
4092 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4093 /* assign the amsops */
4094 aopOp (left,ic,FALSE);
4095 aopOp (right,ic,FALSE);
4096 aopOp (result,ic,TRUE);
4098 genCmp(right, left, result, ifx, sign);
4100 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4101 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4102 freeAsmop(result,NULL,ic,TRUE);
4105 /*-----------------------------------------------------------------*/
4106 /* genCmpLt - less than comparisons */
4107 /*-----------------------------------------------------------------*/
4108 static void genCmpLt (iCode *ic, iCode *ifx)
4110 operand *left, *right, *result;
4111 sym_link *letype , *retype;
4114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4116 right= IC_RIGHT(ic);
4117 result = IC_RESULT(ic);
4119 letype = getSpec(operandType(left));
4120 retype =getSpec(operandType(right));
4121 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4123 /* assign the amsops */
4124 aopOp (left,ic,FALSE);
4125 aopOp (right,ic,FALSE);
4126 aopOp (result,ic,TRUE);
4128 genCmp(left, right, result, ifx, sign);
4130 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4131 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4132 freeAsmop(result,NULL,ic,TRUE);
4135 /*-----------------------------------------------------------------*/
4136 /* genc16bit2lit - compare a 16 bit value to a literal */
4137 /*-----------------------------------------------------------------*/
4138 static void genc16bit2lit(operand *op, int lit, int offset)
4142 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4143 if( (lit&0xff) == 0)
4148 switch( BYTEofLONG(lit,i)) {
4150 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4153 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4156 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4159 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4160 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4165 switch( BYTEofLONG(lit,i)) {
4167 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4171 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4175 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4178 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4180 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4186 /*-----------------------------------------------------------------*/
4187 /* gencjneshort - compare and jump if not equal */
4188 /*-----------------------------------------------------------------*/
4189 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4191 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4196 unsigned long lit = 0L;
4197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4198 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4200 resolveIfx(&rIfx,ifx);
4201 lbl = newiTempLabel(NULL);
4204 /* if the left side is a literal or
4205 if the right is in a pointer register and left
4207 if ((AOP_TYPE(left) == AOP_LIT) ||
4208 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4213 if(AOP_TYPE(right) == AOP_LIT)
4214 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4216 /* if the right side is a literal then anything goes */
4217 if (AOP_TYPE(right) == AOP_LIT &&
4218 AOP_TYPE(left) != AOP_DIR ) {
4221 genc16bit2lit(left, lit, 0);
4223 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4228 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4229 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4231 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4235 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4243 /* if the right side is in a register or in direct space or
4244 if the left is a pointer register & right is not */
4245 else if (AOP_TYPE(right) == AOP_REG ||
4246 AOP_TYPE(right) == AOP_DIR ||
4247 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4248 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4251 genc16bit2lit(left, lit, 0);
4253 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4258 if((AOP_TYPE(left) == AOP_DIR) &&
4259 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4261 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4262 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4264 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4266 switch (lit & 0xff) {
4268 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4271 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4272 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4276 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4277 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4281 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4282 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4287 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4290 if(AOP_TYPE(result) == AOP_CRY) {
4291 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4296 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4298 /* fix me. probably need to check result size too */
4299 emitpcode(POC_CLRF,popGet(AOP(result),0));
4304 emitpcode(POC_INCF,popGet(AOP(result),0));
4314 } else if(AOP_TYPE(right) == AOP_REG &&
4315 AOP_TYPE(left) != AOP_DIR){
4318 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4319 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4320 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4325 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4330 /* right is a pointer reg need both a & b */
4332 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4334 pic14_emitcode("mov","b,%s",l);
4335 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4336 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4340 emitpLabel(lbl->key);
4347 /*-----------------------------------------------------------------*/
4348 /* gencjne - compare and jump if not equal */
4349 /*-----------------------------------------------------------------*/
4350 static void gencjne(operand *left, operand *right, iCode *ifx)
4352 symbol *tlbl = newiTempLabel(NULL);
4354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4355 gencjneshort(left, right, lbl);
4357 pic14_emitcode("mov","a,%s",one);
4358 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4359 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4360 pic14_emitcode("clr","a");
4361 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4363 emitpLabel(lbl->key);
4364 emitpLabel(tlbl->key);
4369 /*-----------------------------------------------------------------*/
4370 /* genCmpEq - generates code for equal to */
4371 /*-----------------------------------------------------------------*/
4372 static void genCmpEq (iCode *ic, iCode *ifx)
4374 operand *left, *right, *result;
4375 unsigned long lit = 0L;
4378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4381 DEBUGpic14_emitcode ("; ifx is non-null","");
4383 DEBUGpic14_emitcode ("; ifx is null","");
4385 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4386 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4387 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4389 size = max(AOP_SIZE(left),AOP_SIZE(right));
4391 DEBUGpic14_AopType(__LINE__,left,right,result);
4393 /* if literal, literal on the right or
4394 if the right is in a pointer register and left
4396 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4397 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4398 operand *tmp = right ;
4404 if(ifx && !AOP_SIZE(result)){
4406 /* if they are both bit variables */
4407 if (AOP_TYPE(left) == AOP_CRY &&
4408 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4409 if(AOP_TYPE(right) == AOP_LIT){
4410 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4412 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4413 pic14_emitcode("cpl","c");
4414 } else if(lit == 1L) {
4415 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4417 pic14_emitcode("clr","c");
4419 /* AOP_TYPE(right) == AOP_CRY */
4421 symbol *lbl = newiTempLabel(NULL);
4422 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4423 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4424 pic14_emitcode("cpl","c");
4425 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4427 /* if true label then we jump if condition
4429 tlbl = newiTempLabel(NULL);
4430 if ( IC_TRUE(ifx) ) {
4431 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4432 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4434 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4435 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4437 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4440 /* They're not both bit variables. Is the right a literal? */
4441 if(AOP_TYPE(right) == AOP_LIT) {
4442 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4447 switch(lit & 0xff) {
4449 if ( IC_TRUE(ifx) ) {
4450 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4452 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4454 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4455 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4459 if ( IC_TRUE(ifx) ) {
4460 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4462 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4464 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4465 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4469 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4471 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4476 /* end of size == 1 */
4480 genc16bit2lit(left,lit,offset);
4483 /* end of size == 2 */
4488 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4489 emitpcode(POC_IORFW,popGet(AOP(left),1));
4490 emitpcode(POC_IORFW,popGet(AOP(left),2));
4491 emitpcode(POC_IORFW,popGet(AOP(left),3));
4495 /* search for patterns that can be optimized */
4497 genc16bit2lit(left,lit,0);
4500 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4502 genc16bit2lit(left,lit,2);
4504 emitpcode(POC_IORFW,popGet(AOP(left),2));
4505 emitpcode(POC_IORFW,popGet(AOP(left),3));
4518 } else if(AOP_TYPE(right) == AOP_CRY ) {
4519 /* we know the left is not a bit, but that the right is */
4520 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4521 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4522 popGet(AOP(right),offset));
4523 emitpcode(POC_XORLW,popGetLit(1));
4525 /* if the two are equal, then W will be 0 and the Z bit is set
4526 * we could test Z now, or go ahead and check the high order bytes if
4527 * the variable we're comparing is larger than a byte. */
4530 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4532 if ( IC_TRUE(ifx) ) {
4534 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4535 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4538 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4539 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4543 /* They're both variables that are larger than bits */
4546 tlbl = newiTempLabel(NULL);
4549 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4550 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4552 if ( IC_TRUE(ifx) ) {
4555 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4556 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4559 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4560 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4564 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4565 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4569 if(s>1 && IC_TRUE(ifx)) {
4570 emitpLabel(tlbl->key);
4571 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4575 /* mark the icode as generated */
4580 /* if they are both bit variables */
4581 if (AOP_TYPE(left) == AOP_CRY &&
4582 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4583 if(AOP_TYPE(right) == AOP_LIT){
4584 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4586 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4587 pic14_emitcode("cpl","c");
4588 } else if(lit == 1L) {
4589 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4591 pic14_emitcode("clr","c");
4593 /* AOP_TYPE(right) == AOP_CRY */
4595 symbol *lbl = newiTempLabel(NULL);
4596 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4597 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4598 pic14_emitcode("cpl","c");
4599 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4602 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4603 pic14_outBitC(result);
4607 genIfxJump (ifx,"c");
4610 /* if the result is used in an arithmetic operation
4611 then put the result in place */
4612 pic14_outBitC(result);
4615 gencjne(left,right,result,ifx);
4618 gencjne(left,right,newiTempLabel(NULL));
4620 if(IC_TRUE(ifx)->key)
4621 gencjne(left,right,IC_TRUE(ifx)->key);
4623 gencjne(left,right,IC_FALSE(ifx)->key);
4627 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4628 aopPut(AOP(result),"a",0);
4633 genIfxJump (ifx,"a");
4637 /* if the result is used in an arithmetic operation
4638 then put the result in place */
4640 if (AOP_TYPE(result) != AOP_CRY)
4641 pic14_outAcc(result);
4643 /* leave the result in acc */
4647 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4648 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4649 freeAsmop(result,NULL,ic,TRUE);
4652 /*-----------------------------------------------------------------*/
4653 /* ifxForOp - returns the icode containing the ifx for operand */
4654 /*-----------------------------------------------------------------*/
4655 static iCode *ifxForOp ( operand *op, iCode *ic )
4657 /* if true symbol then needs to be assigned */
4658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4659 if (IS_TRUE_SYMOP(op))
4662 /* if this has register type condition and
4663 the next instruction is ifx with the same operand
4664 and live to of the operand is upto the ifx only then */
4666 ic->next->op == IFX &&
4667 IC_COND(ic->next)->key == op->key &&
4668 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4672 ic->next->op == IFX &&
4673 IC_COND(ic->next)->key == op->key) {
4674 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4678 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4680 ic->next->op == IFX)
4681 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4684 ic->next->op == IFX &&
4685 IC_COND(ic->next)->key == op->key) {
4686 DEBUGpic14_emitcode ("; "," key is okay");
4687 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4688 OP_SYMBOL(op)->liveTo,
4695 /*-----------------------------------------------------------------*/
4696 /* genAndOp - for && operation */
4697 /*-----------------------------------------------------------------*/
4698 static void genAndOp (iCode *ic)
4700 operand *left,*right, *result;
4703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4704 /* note here that && operations that are in an
4705 if statement are taken away by backPatchLabels
4706 only those used in arthmetic operations remain */
4707 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4708 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4709 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4711 /* if both are bit variables */
4712 if (AOP_TYPE(left) == AOP_CRY &&
4713 AOP_TYPE(right) == AOP_CRY ) {
4714 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4715 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4716 pic14_outBitC(result);
4718 tlbl = newiTempLabel(NULL);
4719 pic14_toBoolean(left);
4720 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4721 pic14_toBoolean(right);
4722 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4723 pic14_outBitAcc(result);
4726 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4727 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4728 freeAsmop(result,NULL,ic,TRUE);
4732 /*-----------------------------------------------------------------*/
4733 /* genOrOp - for || operation */
4734 /*-----------------------------------------------------------------*/
4737 modified this code, but it doesn't appear to ever get called
4740 static void genOrOp (iCode *ic)
4742 operand *left,*right, *result;
4745 /* note here that || operations that are in an
4746 if statement are taken away by backPatchLabels
4747 only those used in arthmetic operations remain */
4748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4749 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4750 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4751 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4753 DEBUGpic14_AopType(__LINE__,left,right,result);
4755 /* if both are bit variables */
4756 if (AOP_TYPE(left) == AOP_CRY &&
4757 AOP_TYPE(right) == AOP_CRY ) {
4758 pic14_emitcode("clrc","");
4759 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4760 AOP(left)->aopu.aop_dir,
4761 AOP(left)->aopu.aop_dir);
4762 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4763 AOP(right)->aopu.aop_dir,
4764 AOP(right)->aopu.aop_dir);
4765 pic14_emitcode("setc","");
4768 tlbl = newiTempLabel(NULL);
4769 pic14_toBoolean(left);
4771 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4772 pic14_toBoolean(right);
4773 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4775 pic14_outBitAcc(result);
4778 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4779 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4780 freeAsmop(result,NULL,ic,TRUE);
4783 /*-----------------------------------------------------------------*/
4784 /* isLiteralBit - test if lit == 2^n */
4785 /*-----------------------------------------------------------------*/
4786 static int isLiteralBit(unsigned long lit)
4788 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4789 0x100L,0x200L,0x400L,0x800L,
4790 0x1000L,0x2000L,0x4000L,0x8000L,
4791 0x10000L,0x20000L,0x40000L,0x80000L,
4792 0x100000L,0x200000L,0x400000L,0x800000L,
4793 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4794 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4798 for(idx = 0; idx < 32; idx++)
4804 /*-----------------------------------------------------------------*/
4805 /* continueIfTrue - */
4806 /*-----------------------------------------------------------------*/
4807 static void continueIfTrue (iCode *ic)
4809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4811 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4815 /*-----------------------------------------------------------------*/
4817 /*-----------------------------------------------------------------*/
4818 static void jumpIfTrue (iCode *ic)
4820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4822 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4826 /*-----------------------------------------------------------------*/
4827 /* jmpTrueOrFalse - */
4828 /*-----------------------------------------------------------------*/
4829 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4831 // ugly but optimized by peephole
4832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4834 symbol *nlbl = newiTempLabel(NULL);
4835 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4836 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4837 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4838 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4841 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4842 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4847 /*-----------------------------------------------------------------*/
4848 /* genAnd - code for and */
4849 /*-----------------------------------------------------------------*/
4850 static void genAnd (iCode *ic, iCode *ifx)
4852 operand *left, *right, *result;
4854 unsigned long lit = 0L;
4859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4860 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4861 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4862 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4864 resolveIfx(&rIfx,ifx);
4866 /* if left is a literal & right is not then exchange them */
4867 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4868 AOP_NEEDSACC(left)) {
4869 operand *tmp = right ;
4874 /* if result = right then exchange them */
4875 if(pic14_sameRegs(AOP(result),AOP(right))){
4876 operand *tmp = right ;
4881 /* if right is bit then exchange them */
4882 if (AOP_TYPE(right) == AOP_CRY &&
4883 AOP_TYPE(left) != AOP_CRY){
4884 operand *tmp = right ;
4888 if(AOP_TYPE(right) == AOP_LIT)
4889 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4891 size = AOP_SIZE(result);
4893 DEBUGpic14_AopType(__LINE__,left,right,result);
4896 // result = bit & yy;
4897 if (AOP_TYPE(left) == AOP_CRY){
4898 // c = bit & literal;
4899 if(AOP_TYPE(right) == AOP_LIT){
4901 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4904 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4907 if(size && (AOP_TYPE(result) == AOP_CRY)){
4908 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4911 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4915 pic14_emitcode("clr","c");
4918 if (AOP_TYPE(right) == AOP_CRY){
4920 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4921 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4924 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4926 pic14_emitcode("rrc","a");
4927 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4933 pic14_outBitC(result);
4935 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4936 genIfxJump(ifx, "c");
4940 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4941 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4942 if((AOP_TYPE(right) == AOP_LIT) &&
4943 (AOP_TYPE(result) == AOP_CRY) &&
4944 (AOP_TYPE(left) != AOP_CRY)){
4945 int posbit = isLiteralBit(lit);
4949 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4952 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4958 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4959 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4961 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4962 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4965 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4966 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4967 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4974 symbol *tlbl = newiTempLabel(NULL);
4975 int sizel = AOP_SIZE(left);
4977 pic14_emitcode("setb","c");
4979 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4980 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4982 if((posbit = isLiteralBit(bytelit)) != 0)
4983 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4985 if(bytelit != 0x0FFL)
4986 pic14_emitcode("anl","a,%s",
4987 aopGet(AOP(right),offset,FALSE,TRUE));
4988 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4993 // bit = left & literal
4995 pic14_emitcode("clr","c");
4996 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4998 // if(left & literal)
5001 jmpTrueOrFalse(ifx, tlbl);
5005 pic14_outBitC(result);
5009 /* if left is same as result */
5010 if(pic14_sameRegs(AOP(result),AOP(left))){
5012 for(;size--; offset++,lit>>=8) {
5013 if(AOP_TYPE(right) == AOP_LIT){
5014 switch(lit & 0xff) {
5016 /* and'ing with 0 has clears the result */
5017 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5018 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5021 /* and'ing with 0xff is a nop when the result and left are the same */
5026 int p = my_powof2( (~lit) & 0xff );
5028 /* only one bit is set in the literal, so use a bcf instruction */
5029 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5030 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5033 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5034 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5035 if(know_W != (lit&0xff))
5036 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5038 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5043 if (AOP_TYPE(left) == AOP_ACC) {
5044 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5046 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5047 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5054 // left & result in different registers
5055 if(AOP_TYPE(result) == AOP_CRY){
5057 // if(size), result in bit
5058 // if(!size && ifx), conditional oper: if(left & right)
5059 symbol *tlbl = newiTempLabel(NULL);
5060 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5062 pic14_emitcode("setb","c");
5064 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5065 pic14_emitcode("anl","a,%s",
5066 aopGet(AOP(left),offset,FALSE,FALSE));
5067 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5072 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5073 pic14_outBitC(result);
5075 jmpTrueOrFalse(ifx, tlbl);
5077 for(;(size--);offset++) {
5079 // result = left & right
5080 if(AOP_TYPE(right) == AOP_LIT){
5081 int t = (lit >> (offset*8)) & 0x0FFL;
5084 pic14_emitcode("clrf","%s",
5085 aopGet(AOP(result),offset,FALSE,FALSE));
5086 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5089 pic14_emitcode("movf","%s,w",
5090 aopGet(AOP(left),offset,FALSE,FALSE));
5091 pic14_emitcode("movwf","%s",
5092 aopGet(AOP(result),offset,FALSE,FALSE));
5093 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5094 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5097 pic14_emitcode("movlw","0x%x",t);
5098 pic14_emitcode("andwf","%s,w",
5099 aopGet(AOP(left),offset,FALSE,FALSE));
5100 pic14_emitcode("movwf","%s",
5101 aopGet(AOP(result),offset,FALSE,FALSE));
5103 emitpcode(POC_MOVLW, popGetLit(t));
5104 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5105 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5110 if (AOP_TYPE(left) == AOP_ACC) {
5111 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5112 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5114 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5115 pic14_emitcode("andwf","%s,w",
5116 aopGet(AOP(left),offset,FALSE,FALSE));
5117 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5118 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5120 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5121 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5127 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5128 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5129 freeAsmop(result,NULL,ic,TRUE);
5132 /*-----------------------------------------------------------------*/
5133 /* genOr - code for or */
5134 /*-----------------------------------------------------------------*/
5135 static void genOr (iCode *ic, iCode *ifx)
5137 operand *left, *right, *result;
5139 unsigned long lit = 0L;
5141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5144 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5145 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5147 DEBUGpic14_AopType(__LINE__,left,right,result);
5149 /* if left is a literal & right is not then exchange them */
5150 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5151 AOP_NEEDSACC(left)) {
5152 operand *tmp = right ;
5157 /* if result = right then exchange them */
5158 if(pic14_sameRegs(AOP(result),AOP(right))){
5159 operand *tmp = right ;
5164 /* if right is bit then exchange them */
5165 if (AOP_TYPE(right) == AOP_CRY &&
5166 AOP_TYPE(left) != AOP_CRY){
5167 operand *tmp = right ;
5172 DEBUGpic14_AopType(__LINE__,left,right,result);
5174 if(AOP_TYPE(right) == AOP_LIT)
5175 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5177 size = AOP_SIZE(result);
5181 if (AOP_TYPE(left) == AOP_CRY){
5182 if(AOP_TYPE(right) == AOP_LIT){
5183 // c = bit & literal;
5185 // lit != 0 => result = 1
5186 if(AOP_TYPE(result) == AOP_CRY){
5188 emitpcode(POC_BSF, popGet(AOP(result),0));
5189 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5190 // AOP(result)->aopu.aop_dir,
5191 // AOP(result)->aopu.aop_dir);
5193 continueIfTrue(ifx);
5197 // lit == 0 => result = left
5198 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5200 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5203 if (AOP_TYPE(right) == AOP_CRY){
5204 if(pic14_sameRegs(AOP(result),AOP(left))){
5206 emitpcode(POC_BCF, popGet(AOP(result),0));
5207 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5208 emitpcode(POC_BSF, popGet(AOP(result),0));
5210 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5211 AOP(result)->aopu.aop_dir,
5212 AOP(result)->aopu.aop_dir);
5213 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5214 AOP(right)->aopu.aop_dir,
5215 AOP(right)->aopu.aop_dir);
5216 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5217 AOP(result)->aopu.aop_dir,
5218 AOP(result)->aopu.aop_dir);
5220 if( AOP_TYPE(result) == AOP_ACC) {
5221 emitpcode(POC_MOVLW, popGetLit(0));
5222 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5223 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5224 emitpcode(POC_MOVLW, popGetLit(1));
5228 emitpcode(POC_BCF, popGet(AOP(result),0));
5229 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5230 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5231 emitpcode(POC_BSF, popGet(AOP(result),0));
5233 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5234 AOP(result)->aopu.aop_dir,
5235 AOP(result)->aopu.aop_dir);
5236 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5237 AOP(right)->aopu.aop_dir,
5238 AOP(right)->aopu.aop_dir);
5239 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5240 AOP(left)->aopu.aop_dir,
5241 AOP(left)->aopu.aop_dir);
5242 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5243 AOP(result)->aopu.aop_dir,
5244 AOP(result)->aopu.aop_dir);
5249 symbol *tlbl = newiTempLabel(NULL);
5250 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5253 emitpcode(POC_BCF, popGet(AOP(result),0));
5254 if( AOP_TYPE(right) == AOP_ACC) {
5255 emitpcode(POC_IORLW, popGetLit(0));
5257 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5258 emitpcode(POC_BSF, popGet(AOP(result),0));
5263 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5264 pic14_emitcode(";XXX setb","c");
5265 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5266 AOP(left)->aopu.aop_dir,tlbl->key+100);
5267 pic14_toBoolean(right);
5268 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5269 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5270 jmpTrueOrFalse(ifx, tlbl);
5274 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5281 pic14_outBitC(result);
5283 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5284 genIfxJump(ifx, "c");
5288 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5289 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5290 if((AOP_TYPE(right) == AOP_LIT) &&
5291 (AOP_TYPE(result) == AOP_CRY) &&
5292 (AOP_TYPE(left) != AOP_CRY)){
5294 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5297 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5299 continueIfTrue(ifx);
5302 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5303 // lit = 0, result = boolean(left)
5305 pic14_emitcode(";XXX setb","c");
5306 pic14_toBoolean(right);
5308 symbol *tlbl = newiTempLabel(NULL);
5309 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5311 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5313 genIfxJump (ifx,"a");
5317 pic14_outBitC(result);
5321 /* if left is same as result */
5322 if(pic14_sameRegs(AOP(result),AOP(left))){
5324 for(;size--; offset++,lit>>=8) {
5325 if(AOP_TYPE(right) == AOP_LIT){
5326 if((lit & 0xff) == 0)
5327 /* or'ing with 0 has no effect */
5330 int p = my_powof2(lit & 0xff);
5332 /* only one bit is set in the literal, so use a bsf instruction */
5334 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5336 if(know_W != (lit & 0xff))
5337 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5338 know_W = lit & 0xff;
5339 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5344 if (AOP_TYPE(left) == AOP_ACC) {
5345 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5346 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5348 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5349 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5351 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5352 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5358 // left & result in different registers
5359 if(AOP_TYPE(result) == AOP_CRY){
5361 // if(size), result in bit
5362 // if(!size && ifx), conditional oper: if(left | right)
5363 symbol *tlbl = newiTempLabel(NULL);
5364 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5365 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5369 pic14_emitcode(";XXX setb","c");
5371 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5372 pic14_emitcode(";XXX orl","a,%s",
5373 aopGet(AOP(left),offset,FALSE,FALSE));
5374 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5379 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5380 pic14_outBitC(result);
5382 jmpTrueOrFalse(ifx, tlbl);
5383 } else for(;(size--);offset++){
5385 // result = left & right
5386 if(AOP_TYPE(right) == AOP_LIT){
5387 int t = (lit >> (offset*8)) & 0x0FFL;
5390 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5391 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5393 pic14_emitcode("movf","%s,w",
5394 aopGet(AOP(left),offset,FALSE,FALSE));
5395 pic14_emitcode("movwf","%s",
5396 aopGet(AOP(result),offset,FALSE,FALSE));
5399 emitpcode(POC_MOVLW, popGetLit(t));
5400 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5401 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5403 pic14_emitcode("movlw","0x%x",t);
5404 pic14_emitcode("iorwf","%s,w",
5405 aopGet(AOP(left),offset,FALSE,FALSE));
5406 pic14_emitcode("movwf","%s",
5407 aopGet(AOP(result),offset,FALSE,FALSE));
5413 // faster than result <- left, anl result,right
5414 // and better if result is SFR
5415 if (AOP_TYPE(left) == AOP_ACC) {
5416 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5417 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5419 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5420 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5422 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5423 pic14_emitcode("iorwf","%s,w",
5424 aopGet(AOP(left),offset,FALSE,FALSE));
5426 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5427 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5432 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5433 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5434 freeAsmop(result,NULL,ic,TRUE);
5437 /*-----------------------------------------------------------------*/
5438 /* genXor - code for xclusive or */
5439 /*-----------------------------------------------------------------*/
5440 static void genXor (iCode *ic, iCode *ifx)
5442 operand *left, *right, *result;
5444 unsigned long lit = 0L;
5446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5448 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5449 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5450 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5452 /* if left is a literal & right is not ||
5453 if left needs acc & right does not */
5454 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5455 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5456 operand *tmp = right ;
5461 /* if result = right then exchange them */
5462 if(pic14_sameRegs(AOP(result),AOP(right))){
5463 operand *tmp = right ;
5468 /* if right is bit then exchange them */
5469 if (AOP_TYPE(right) == AOP_CRY &&
5470 AOP_TYPE(left) != AOP_CRY){
5471 operand *tmp = right ;
5475 if(AOP_TYPE(right) == AOP_LIT)
5476 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5478 size = AOP_SIZE(result);
5482 if (AOP_TYPE(left) == AOP_CRY){
5483 if(AOP_TYPE(right) == AOP_LIT){
5484 // c = bit & literal;
5486 // lit>>1 != 0 => result = 1
5487 if(AOP_TYPE(result) == AOP_CRY){
5489 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5491 continueIfTrue(ifx);
5494 pic14_emitcode("setb","c");
5498 // lit == 0, result = left
5499 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5501 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5503 // lit == 1, result = not(left)
5504 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5505 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5508 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5509 pic14_emitcode("cpl","c");
5516 symbol *tlbl = newiTempLabel(NULL);
5517 if (AOP_TYPE(right) == AOP_CRY){
5519 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5522 int sizer = AOP_SIZE(right);
5524 // if val>>1 != 0, result = 1
5525 pic14_emitcode("setb","c");
5527 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5529 // test the msb of the lsb
5530 pic14_emitcode("anl","a,#0xfe");
5531 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5535 pic14_emitcode("rrc","a");
5537 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5538 pic14_emitcode("cpl","c");
5539 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5544 pic14_outBitC(result);
5546 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5547 genIfxJump(ifx, "c");
5551 if(pic14_sameRegs(AOP(result),AOP(left))){
5552 /* if left is same as result */
5553 for(;size--; offset++) {
5554 if(AOP_TYPE(right) == AOP_LIT){
5555 int t = (lit >> (offset*8)) & 0x0FFL;
5559 if (IS_AOP_PREG(left)) {
5560 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5561 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5562 aopPut(AOP(result),"a",offset);
5564 emitpcode(POC_MOVLW, popGetLit(t));
5565 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5566 pic14_emitcode("xrl","%s,%s",
5567 aopGet(AOP(left),offset,FALSE,TRUE),
5568 aopGet(AOP(right),offset,FALSE,FALSE));
5571 if (AOP_TYPE(left) == AOP_ACC)
5572 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5574 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5575 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5577 if (IS_AOP_PREG(left)) {
5578 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5579 aopPut(AOP(result),"a",offset);
5581 pic14_emitcode("xrl","%s,a",
5582 aopGet(AOP(left),offset,FALSE,TRUE));
5588 // left & result in different registers
5589 if(AOP_TYPE(result) == AOP_CRY){
5591 // if(size), result in bit
5592 // if(!size && ifx), conditional oper: if(left ^ right)
5593 symbol *tlbl = newiTempLabel(NULL);
5594 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5596 pic14_emitcode("setb","c");
5598 if((AOP_TYPE(right) == AOP_LIT) &&
5599 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5600 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5602 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5603 pic14_emitcode("xrl","a,%s",
5604 aopGet(AOP(left),offset,FALSE,FALSE));
5606 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5611 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5612 pic14_outBitC(result);
5614 jmpTrueOrFalse(ifx, tlbl);
5615 } else for(;(size--);offset++){
5617 // result = left & right
5618 if(AOP_TYPE(right) == AOP_LIT){
5619 int t = (lit >> (offset*8)) & 0x0FFL;
5622 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5623 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5624 pic14_emitcode("movf","%s,w",
5625 aopGet(AOP(left),offset,FALSE,FALSE));
5626 pic14_emitcode("movwf","%s",
5627 aopGet(AOP(result),offset,FALSE,FALSE));
5630 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5631 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5632 pic14_emitcode("comf","%s,w",
5633 aopGet(AOP(left),offset,FALSE,FALSE));
5634 pic14_emitcode("movwf","%s",
5635 aopGet(AOP(result),offset,FALSE,FALSE));
5638 emitpcode(POC_MOVLW, popGetLit(t));
5639 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5640 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5641 pic14_emitcode("movlw","0x%x",t);
5642 pic14_emitcode("xorwf","%s,w",
5643 aopGet(AOP(left),offset,FALSE,FALSE));
5644 pic14_emitcode("movwf","%s",
5645 aopGet(AOP(result),offset,FALSE,FALSE));
5651 // faster than result <- left, anl result,right
5652 // and better if result is SFR
5653 if (AOP_TYPE(left) == AOP_ACC) {
5654 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5655 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5657 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5658 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5659 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5660 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5662 if ( AOP_TYPE(result) != AOP_ACC){
5663 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5664 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5670 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5671 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5672 freeAsmop(result,NULL,ic,TRUE);
5675 /*-----------------------------------------------------------------*/
5676 /* genInline - write the inline code out */
5677 /*-----------------------------------------------------------------*/
5678 static void genInline (iCode *ic)
5680 char *buffer, *bp, *bp1;
5682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5684 _G.inLine += (!options.asmpeep);
5686 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5687 strcpy(buffer,IC_INLINE(ic));
5689 /* emit each line as a code */
5693 pic14_emitcode(bp1,"");
5700 pic14_emitcode(bp1,"");
5707 pic14_emitcode(bp1,"");
5708 /* pic14_emitcode("",buffer); */
5709 _G.inLine -= (!options.asmpeep);
5712 /*-----------------------------------------------------------------*/
5713 /* genRRC - rotate right with carry */
5714 /*-----------------------------------------------------------------*/
5715 static void genRRC (iCode *ic)
5717 operand *left , *result ;
5718 int size, offset = 0, same;
5720 /* rotate right with carry */
5722 result=IC_RESULT(ic);
5723 aopOp (left,ic,FALSE);
5724 aopOp (result,ic,FALSE);
5726 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5728 same = pic14_sameRegs(AOP(result),AOP(left));
5730 size = AOP_SIZE(result);
5732 /* get the lsb and put it into the carry */
5733 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5740 emitpcode(POC_RRF, popGet(AOP(left),offset));
5742 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5743 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5749 freeAsmop(left,NULL,ic,TRUE);
5750 freeAsmop(result,NULL,ic,TRUE);
5753 /*-----------------------------------------------------------------*/
5754 /* genRLC - generate code for rotate left with carry */
5755 /*-----------------------------------------------------------------*/
5756 static void genRLC (iCode *ic)
5758 operand *left , *result ;
5759 int size, offset = 0;
5762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5763 /* rotate right with carry */
5765 result=IC_RESULT(ic);
5766 aopOp (left,ic,FALSE);
5767 aopOp (result,ic,FALSE);
5769 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5771 same = pic14_sameRegs(AOP(result),AOP(left));
5773 /* move it to the result */
5774 size = AOP_SIZE(result);
5776 /* get the msb and put it into the carry */
5777 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5784 emitpcode(POC_RLF, popGet(AOP(left),offset));
5786 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5787 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5794 freeAsmop(left,NULL,ic,TRUE);
5795 freeAsmop(result,NULL,ic,TRUE);
5798 /*-----------------------------------------------------------------*/
5799 /* genGetHbit - generates code get highest order bit */
5800 /*-----------------------------------------------------------------*/
5801 static void genGetHbit (iCode *ic)
5803 operand *left, *result;
5805 result=IC_RESULT(ic);
5806 aopOp (left,ic,FALSE);
5807 aopOp (result,ic,FALSE);
5809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5810 /* get the highest order byte into a */
5811 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5812 if(AOP_TYPE(result) == AOP_CRY){
5813 pic14_emitcode("rlc","a");
5814 pic14_outBitC(result);
5817 pic14_emitcode("rl","a");
5818 pic14_emitcode("anl","a,#0x01");
5819 pic14_outAcc(result);
5823 freeAsmop(left,NULL,ic,TRUE);
5824 freeAsmop(result,NULL,ic,TRUE);
5827 /*-----------------------------------------------------------------*/
5828 /* AccRol - rotate left accumulator by known count */
5829 /*-----------------------------------------------------------------*/
5830 static void AccRol (int shCount)
5832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5833 shCount &= 0x0007; // shCount : 0..7
5838 pic14_emitcode("rl","a");
5841 pic14_emitcode("rl","a");
5842 pic14_emitcode("rl","a");
5845 pic14_emitcode("swap","a");
5846 pic14_emitcode("rr","a");
5849 pic14_emitcode("swap","a");
5852 pic14_emitcode("swap","a");
5853 pic14_emitcode("rl","a");
5856 pic14_emitcode("rr","a");
5857 pic14_emitcode("rr","a");
5860 pic14_emitcode("rr","a");
5865 /*-----------------------------------------------------------------*/
5866 /* AccLsh - left shift accumulator by known count */
5867 /*-----------------------------------------------------------------*/
5868 static void AccLsh (int shCount)
5870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5873 pic14_emitcode("add","a,acc");
5876 pic14_emitcode("add","a,acc");
5877 pic14_emitcode("add","a,acc");
5879 /* rotate left accumulator */
5881 /* and kill the lower order bits */
5882 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5887 /*-----------------------------------------------------------------*/
5888 /* AccRsh - right shift accumulator by known count */
5889 /*-----------------------------------------------------------------*/
5890 static void AccRsh (int shCount)
5892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5896 pic14_emitcode("rrc","a");
5898 /* rotate right accumulator */
5899 AccRol(8 - shCount);
5900 /* and kill the higher order bits */
5901 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5907 /*-----------------------------------------------------------------*/
5908 /* AccSRsh - signed right shift accumulator by known count */
5909 /*-----------------------------------------------------------------*/
5910 static void AccSRsh (int shCount)
5913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5916 pic14_emitcode("mov","c,acc.7");
5917 pic14_emitcode("rrc","a");
5918 } else if(shCount == 2){
5919 pic14_emitcode("mov","c,acc.7");
5920 pic14_emitcode("rrc","a");
5921 pic14_emitcode("mov","c,acc.7");
5922 pic14_emitcode("rrc","a");
5924 tlbl = newiTempLabel(NULL);
5925 /* rotate right accumulator */
5926 AccRol(8 - shCount);
5927 /* and kill the higher order bits */
5928 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5929 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5930 pic14_emitcode("orl","a,#0x%02x",
5931 (unsigned char)~SRMask[shCount]);
5932 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5937 /*-----------------------------------------------------------------*/
5938 /* shiftR1Left2Result - shift right one byte from left to result */
5939 /*-----------------------------------------------------------------*/
5940 static void shiftR1Left2ResultSigned (operand *left, int offl,
5941 operand *result, int offr,
5946 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5948 same = (left == result) || (AOP(left) == AOP(result));
5952 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5954 emitpcode(POC_RRF, popGet(AOP(result),offr));
5956 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5957 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5967 /*-----------------------------------------------------------------*/
5968 /* shiftR1Left2Result - shift right one byte from left to result */
5969 /*-----------------------------------------------------------------*/
5970 static void shiftR1Left2Result (operand *left, int offl,
5971 operand *result, int offr,
5972 int shCount, int sign)
5976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5978 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5980 /* Copy the msb into the carry if signed. */
5982 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5992 emitpcode(POC_RRF, popGet(AOP(result),offr));
5994 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5995 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6001 emitpcode(POC_RRF, popGet(AOP(result),offr));
6003 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6004 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6007 emitpcode(POC_RRF, popGet(AOP(result),offr));
6012 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6014 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6015 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6018 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6019 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6020 emitpcode(POC_ANDLW, popGetLit(0x1f));
6021 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6025 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6026 emitpcode(POC_ANDLW, popGetLit(0x0f));
6027 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6031 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6032 emitpcode(POC_ANDLW, popGetLit(0x0f));
6033 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6035 emitpcode(POC_RRF, popGet(AOP(result),offr));
6040 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6041 emitpcode(POC_ANDLW, popGetLit(0x80));
6042 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6043 emitpcode(POC_RLF, popGet(AOP(result),offr));
6044 emitpcode(POC_RLF, popGet(AOP(result),offr));
6049 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6050 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6051 emitpcode(POC_RLF, popGet(AOP(result),offr));
6062 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6064 /* shift right accumulator */
6069 aopPut(AOP(result),"a",offr);
6073 /*-----------------------------------------------------------------*/
6074 /* shiftL1Left2Result - shift left one byte from left to result */
6075 /*-----------------------------------------------------------------*/
6076 static void shiftL1Left2Result (operand *left, int offl,
6077 operand *result, int offr, int shCount)
6082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6084 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6085 DEBUGpic14_emitcode ("; ***","same = %d",same);
6086 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6088 /* shift left accumulator */
6089 //AccLsh(shCount); // don't comment out just yet...
6090 // aopPut(AOP(result),"a",offr);
6094 /* Shift left 1 bit position */
6095 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6097 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6099 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6100 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6104 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6105 emitpcode(POC_ANDLW,popGetLit(0x7e));
6106 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6107 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6110 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6111 emitpcode(POC_ANDLW,popGetLit(0x3e));
6112 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6113 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6114 emitpcode(POC_RLF, popGet(AOP(result),offr));
6117 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6118 emitpcode(POC_ANDLW, popGetLit(0xf0));
6119 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6122 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6123 emitpcode(POC_ANDLW, popGetLit(0xf0));
6124 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6125 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6128 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6129 emitpcode(POC_ANDLW, popGetLit(0x30));
6130 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6131 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6132 emitpcode(POC_RLF, popGet(AOP(result),offr));
6135 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6136 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6137 emitpcode(POC_RRF, popGet(AOP(result),offr));
6141 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6146 /*-----------------------------------------------------------------*/
6147 /* movLeft2Result - move byte from left to result */
6148 /*-----------------------------------------------------------------*/
6149 static void movLeft2Result (operand *left, int offl,
6150 operand *result, int offr, int sign)
6153 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6154 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6155 l = aopGet(AOP(left),offl,FALSE,FALSE);
6157 if (*l == '@' && (IS_AOP_PREG(result))) {
6158 pic14_emitcode("mov","a,%s",l);
6159 aopPut(AOP(result),"a",offr);
6162 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6163 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6165 //aopPut(AOP(result),l,offr);
6167 /* MSB sign in acc.7 ! */
6168 if(pic14_getDataSize(left) == offl+1){
6169 pic14_emitcode("mov","a,%s",l);
6170 aopPut(AOP(result),"a",offr);
6177 /*-----------------------------------------------------------------*/
6178 /* shiftL2Left2Result - shift left two bytes from left to result */
6179 /*-----------------------------------------------------------------*/
6180 static void shiftL2Left2Result (operand *left, int offl,
6181 operand *result, int offr, int shCount)
6185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6187 if(pic14_sameRegs(AOP(result), AOP(left))) {
6195 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6196 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6197 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6201 emitpcode(POC_RLF, popGet(AOP(result),offr));
6202 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6208 emitpcode(POC_MOVLW, popGetLit(0x0f));
6209 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6210 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6211 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6212 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6213 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6214 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6216 emitpcode(POC_RLF, popGet(AOP(result),offr));
6217 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6221 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6222 emitpcode(POC_RRF, popGet(AOP(result),offr));
6223 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6224 emitpcode(POC_RRF, popGet(AOP(result),offr));
6225 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6226 emitpcode(POC_ANDLW,popGetLit(0xc0));
6227 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6228 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6229 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6230 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6233 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6234 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6235 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6236 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6237 emitpcode(POC_RRF, popGet(AOP(result),offr));
6247 /* note, use a mov/add for the shift since the mov has a
6248 chance of getting optimized out */
6249 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6250 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6251 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6252 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6253 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6257 emitpcode(POC_RLF, popGet(AOP(result),offr));
6258 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6264 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6265 emitpcode(POC_ANDLW, popGetLit(0xF0));
6266 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6267 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6268 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6269 emitpcode(POC_ANDLW, popGetLit(0xF0));
6270 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6271 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6275 emitpcode(POC_RLF, popGet(AOP(result),offr));
6276 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6280 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6281 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6282 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6283 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6285 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6286 emitpcode(POC_RRF, popGet(AOP(result),offr));
6287 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6288 emitpcode(POC_ANDLW,popGetLit(0xc0));
6289 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6290 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6291 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6292 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6295 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6296 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6297 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6298 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6299 emitpcode(POC_RRF, popGet(AOP(result),offr));
6304 /*-----------------------------------------------------------------*/
6305 /* shiftR2Left2Result - shift right two bytes from left to result */
6306 /*-----------------------------------------------------------------*/
6307 static void shiftR2Left2Result (operand *left, int offl,
6308 operand *result, int offr,
6309 int shCount, int sign)
6313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6314 same = pic14_sameRegs(AOP(result), AOP(left));
6316 if(same && ((offl + MSB16) == offr)){
6318 /* don't crash result[offr] */
6319 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6320 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6322 movLeft2Result(left,offl, result, offr, 0);
6323 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6325 /* a:x >> shCount (x = lsb(result))*/
6328 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6330 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6340 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6341 emitpcode(POC_RRF,popGet(AOP(result),offr));
6344 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6345 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6346 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6347 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6352 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6353 emitpcode(POC_RRF,popGet(AOP(result),offr));
6360 emitpcode(POC_MOVLW, popGetLit(0xf0));
6361 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6362 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6364 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6365 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6366 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6367 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6369 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6370 emitpcode(POC_ANDLW, popGetLit(0x0f));
6371 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6373 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6374 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6375 emitpcode(POC_ANDLW, popGetLit(0xf0));
6376 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6377 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6381 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6382 emitpcode(POC_RRF, popGet(AOP(result),offr));
6390 emitpcode(POC_RLF, popGet(AOP(result),offr));
6391 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6393 emitpcode(POC_RLF, popGet(AOP(result),offr));
6394 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6395 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6396 emitpcode(POC_ANDLW,popGetLit(0x03));
6397 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6398 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6399 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6400 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6402 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6403 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6404 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6405 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6406 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6407 emitpcode(POC_RLF, popGet(AOP(result),offr));
6408 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6409 emitpcode(POC_ANDLW,popGetLit(0x03));
6410 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6415 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6416 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6417 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6418 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6419 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6424 /*-----------------------------------------------------------------*/
6425 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6426 /*-----------------------------------------------------------------*/
6427 static void shiftLLeftOrResult (operand *left, int offl,
6428 operand *result, int offr, int shCount)
6430 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6431 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6432 /* shift left accumulator */
6434 /* or with result */
6435 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6436 /* back to result */
6437 aopPut(AOP(result),"a",offr);
6440 /*-----------------------------------------------------------------*/
6441 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6442 /*-----------------------------------------------------------------*/
6443 static void shiftRLeftOrResult (operand *left, int offl,
6444 operand *result, int offr, int shCount)
6446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6447 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6448 /* shift right accumulator */
6450 /* or with result */
6451 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6452 /* back to result */
6453 aopPut(AOP(result),"a",offr);
6456 /*-----------------------------------------------------------------*/
6457 /* genlshOne - left shift a one byte quantity by known count */
6458 /*-----------------------------------------------------------------*/
6459 static void genlshOne (operand *result, operand *left, int shCount)
6461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6462 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6465 /*-----------------------------------------------------------------*/
6466 /* genlshTwo - left shift two bytes by known amount != 0 */
6467 /*-----------------------------------------------------------------*/
6468 static void genlshTwo (operand *result,operand *left, int shCount)
6472 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6473 size = pic14_getDataSize(result);
6475 /* if shCount >= 8 */
6481 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6483 movLeft2Result(left, LSB, result, MSB16, 0);
6485 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6488 /* 1 <= shCount <= 7 */
6491 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6493 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6497 /*-----------------------------------------------------------------*/
6498 /* shiftLLong - shift left one long from left to result */
6499 /* offl = LSB or MSB16 */
6500 /*-----------------------------------------------------------------*/
6501 static void shiftLLong (operand *left, operand *result, int offr )
6504 int size = AOP_SIZE(result);
6506 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6507 if(size >= LSB+offr){
6508 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6510 pic14_emitcode("add","a,acc");
6511 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6512 size >= MSB16+offr && offr != LSB )
6513 pic14_emitcode("xch","a,%s",
6514 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6516 aopPut(AOP(result),"a",LSB+offr);
6519 if(size >= MSB16+offr){
6520 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6521 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6524 pic14_emitcode("rlc","a");
6525 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6526 size >= MSB24+offr && offr != LSB)
6527 pic14_emitcode("xch","a,%s",
6528 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6530 aopPut(AOP(result),"a",MSB16+offr);
6533 if(size >= MSB24+offr){
6534 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6535 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6538 pic14_emitcode("rlc","a");
6539 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6540 size >= MSB32+offr && offr != LSB )
6541 pic14_emitcode("xch","a,%s",
6542 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6544 aopPut(AOP(result),"a",MSB24+offr);
6547 if(size > MSB32+offr){
6548 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6549 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6552 pic14_emitcode("rlc","a");
6553 aopPut(AOP(result),"a",MSB32+offr);
6556 aopPut(AOP(result),zero,LSB);
6559 /*-----------------------------------------------------------------*/
6560 /* genlshFour - shift four byte by a known amount != 0 */
6561 /*-----------------------------------------------------------------*/
6562 static void genlshFour (operand *result, operand *left, int shCount)
6566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6567 size = AOP_SIZE(result);
6569 /* if shifting more that 3 bytes */
6570 if (shCount >= 24 ) {
6573 /* lowest order of left goes to the highest
6574 order of the destination */
6575 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6577 movLeft2Result(left, LSB, result, MSB32, 0);
6578 aopPut(AOP(result),zero,LSB);
6579 aopPut(AOP(result),zero,MSB16);
6580 aopPut(AOP(result),zero,MSB32);
6584 /* more than two bytes */
6585 else if ( shCount >= 16 ) {
6586 /* lower order two bytes goes to higher order two bytes */
6588 /* if some more remaining */
6590 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6592 movLeft2Result(left, MSB16, result, MSB32, 0);
6593 movLeft2Result(left, LSB, result, MSB24, 0);
6595 aopPut(AOP(result),zero,MSB16);
6596 aopPut(AOP(result),zero,LSB);
6600 /* if more than 1 byte */
6601 else if ( shCount >= 8 ) {
6602 /* lower order three bytes goes to higher order three bytes */
6606 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6608 movLeft2Result(left, LSB, result, MSB16, 0);
6610 else{ /* size = 4 */
6612 movLeft2Result(left, MSB24, result, MSB32, 0);
6613 movLeft2Result(left, MSB16, result, MSB24, 0);
6614 movLeft2Result(left, LSB, result, MSB16, 0);
6615 aopPut(AOP(result),zero,LSB);
6617 else if(shCount == 1)
6618 shiftLLong(left, result, MSB16);
6620 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6621 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6622 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6623 aopPut(AOP(result),zero,LSB);
6628 /* 1 <= shCount <= 7 */
6629 else if(shCount <= 2){
6630 shiftLLong(left, result, LSB);
6632 shiftLLong(result, result, LSB);
6634 /* 3 <= shCount <= 7, optimize */
6636 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6637 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6638 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6642 /*-----------------------------------------------------------------*/
6643 /* genLeftShiftLiteral - left shifting by known count */
6644 /*-----------------------------------------------------------------*/
6645 static void genLeftShiftLiteral (operand *left,
6650 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6654 freeAsmop(right,NULL,ic,TRUE);
6656 aopOp(left,ic,FALSE);
6657 aopOp(result,ic,FALSE);
6659 size = getSize(operandType(result));
6662 pic14_emitcode("; shift left ","result %d, left %d",size,
6666 /* I suppose that the left size >= result size */
6669 movLeft2Result(left, size, result, size, 0);
6673 else if(shCount >= (size * 8))
6675 aopPut(AOP(result),zero,size);
6679 genlshOne (result,left,shCount);
6684 genlshTwo (result,left,shCount);
6688 genlshFour (result,left,shCount);
6692 freeAsmop(left,NULL,ic,TRUE);
6693 freeAsmop(result,NULL,ic,TRUE);
6696 /*-----------------------------------------------------------------*/
6697 /* genLeftShift - generates code for left shifting */
6698 /*-----------------------------------------------------------------*/
6699 static void genLeftShift (iCode *ic)
6701 operand *left,*right, *result;
6704 symbol *tlbl , *tlbl1;
6706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6708 right = IC_RIGHT(ic);
6710 result = IC_RESULT(ic);
6712 aopOp(right,ic,FALSE);
6714 /* if the shift count is known then do it
6715 as efficiently as possible */
6716 if (AOP_TYPE(right) == AOP_LIT) {
6717 genLeftShiftLiteral (left,right,result,ic);
6721 /* shift count is unknown then we have to form
6722 a loop get the loop count in B : Note: we take
6723 only the lower order byte since shifting
6724 more that 32 bits make no sense anyway, ( the
6725 largest size of an object can be only 32 bits ) */
6728 aopOp(left,ic,FALSE);
6729 aopOp(result,ic,FALSE);
6731 /* now move the left to the result if they are not the
6733 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6734 AOP_SIZE(result) > 1) {
6736 size = AOP_SIZE(result);
6739 l = aopGet(AOP(left),offset,FALSE,TRUE);
6740 if (*l == '@' && (IS_AOP_PREG(result))) {
6742 pic14_emitcode("mov","a,%s",l);
6743 aopPut(AOP(result),"a",offset);
6745 aopPut(AOP(result),l,offset);
6750 size = AOP_SIZE(result);
6752 /* if it is only one byte then */
6754 if(optimized_for_speed) {
6755 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6756 emitpcode(POC_ANDLW, popGetLit(0xf0));
6757 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6758 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6759 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6760 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6761 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6762 emitpcode(POC_RLFW, popGet(AOP(result),0));
6763 emitpcode(POC_ANDLW, popGetLit(0xfe));
6764 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6765 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6766 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6769 tlbl = newiTempLabel(NULL);
6770 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6771 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6772 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6775 emitpcode(POC_COMFW, popGet(AOP(right),0));
6776 emitpcode(POC_RRF, popGet(AOP(result),0));
6777 emitpLabel(tlbl->key);
6778 emitpcode(POC_RLF, popGet(AOP(result),0));
6779 emitpcode(POC_ADDLW, popGetLit(1));
6781 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6787 tlbl = newiTempLabel(NULL);
6789 tlbl1 = newiTempLabel(NULL);
6791 reAdjustPreg(AOP(result));
6793 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6794 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6795 l = aopGet(AOP(result),offset,FALSE,FALSE);
6797 pic14_emitcode("add","a,acc");
6798 aopPut(AOP(result),"a",offset++);
6800 l = aopGet(AOP(result),offset,FALSE,FALSE);
6802 pic14_emitcode("rlc","a");
6803 aopPut(AOP(result),"a",offset++);
6805 reAdjustPreg(AOP(result));
6807 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6808 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6810 freeAsmop (right,NULL,ic,TRUE);
6811 freeAsmop(left,NULL,ic,TRUE);
6812 freeAsmop(result,NULL,ic,TRUE);
6815 /*-----------------------------------------------------------------*/
6816 /* genrshOne - right shift a one byte quantity by known count */
6817 /*-----------------------------------------------------------------*/
6818 static void genrshOne (operand *result, operand *left,
6819 int shCount, int sign)
6821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6822 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6825 /*-----------------------------------------------------------------*/
6826 /* genrshTwo - right shift two bytes by known amount != 0 */
6827 /*-----------------------------------------------------------------*/
6828 static void genrshTwo (operand *result,operand *left,
6829 int shCount, int sign)
6831 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6832 /* if shCount >= 8 */
6836 shiftR1Left2Result(left, MSB16, result, LSB,
6839 movLeft2Result(left, MSB16, result, LSB, sign);
6841 addSign(result, MSB16, sign);
6843 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6847 /* 1 <= shCount <= 7 */
6849 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6852 /*-----------------------------------------------------------------*/
6853 /* shiftRLong - shift right one long from left to result */
6854 /* offl = LSB or MSB16 */
6855 /*-----------------------------------------------------------------*/
6856 static void shiftRLong (operand *left, int offl,
6857 operand *result, int sign)
6859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6861 pic14_emitcode("clr","c");
6862 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6864 pic14_emitcode("mov","c,acc.7");
6865 pic14_emitcode("rrc","a");
6866 aopPut(AOP(result),"a",MSB32-offl);
6868 /* add sign of "a" */
6869 addSign(result, MSB32, sign);
6871 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6872 pic14_emitcode("rrc","a");
6873 aopPut(AOP(result),"a",MSB24-offl);
6875 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6876 pic14_emitcode("rrc","a");
6877 aopPut(AOP(result),"a",MSB16-offl);
6880 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6881 pic14_emitcode("rrc","a");
6882 aopPut(AOP(result),"a",LSB);
6886 /*-----------------------------------------------------------------*/
6887 /* genrshFour - shift four byte by a known amount != 0 */
6888 /*-----------------------------------------------------------------*/
6889 static void genrshFour (operand *result, operand *left,
6890 int shCount, int sign)
6892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6893 /* if shifting more that 3 bytes */
6894 if(shCount >= 24 ) {
6897 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6899 movLeft2Result(left, MSB32, result, LSB, sign);
6900 addSign(result, MSB16, sign);
6902 else if(shCount >= 16){
6905 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6907 movLeft2Result(left, MSB24, result, LSB, 0);
6908 movLeft2Result(left, MSB32, result, MSB16, sign);
6910 addSign(result, MSB24, sign);
6912 else if(shCount >= 8){
6915 shiftRLong(left, MSB16, result, sign);
6916 else if(shCount == 0){
6917 movLeft2Result(left, MSB16, result, LSB, 0);
6918 movLeft2Result(left, MSB24, result, MSB16, 0);
6919 movLeft2Result(left, MSB32, result, MSB24, sign);
6920 addSign(result, MSB32, sign);
6923 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6924 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6925 /* the last shift is signed */
6926 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6927 addSign(result, MSB32, sign);
6930 else{ /* 1 <= shCount <= 7 */
6932 shiftRLong(left, LSB, result, sign);
6934 shiftRLong(result, LSB, result, sign);
6937 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6938 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6939 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6944 /*-----------------------------------------------------------------*/
6945 /* genRightShiftLiteral - right shifting by known count */
6946 /*-----------------------------------------------------------------*/
6947 static void genRightShiftLiteral (operand *left,
6953 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6957 freeAsmop(right,NULL,ic,TRUE);
6959 aopOp(left,ic,FALSE);
6960 aopOp(result,ic,FALSE);
6963 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6967 size = pic14_getDataSize(left);
6968 /* test the LEFT size !!! */
6970 /* I suppose that the left size >= result size */
6972 size = pic14_getDataSize(result);
6974 movLeft2Result(left, size, result, size, 0);
6977 else if(shCount >= (size * 8)){
6979 /* get sign in acc.7 */
6980 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6981 addSign(result, LSB, sign);
6985 genrshOne (result,left,shCount,sign);
6989 genrshTwo (result,left,shCount,sign);
6993 genrshFour (result,left,shCount,sign);
6999 freeAsmop(left,NULL,ic,TRUE);
7000 freeAsmop(result,NULL,ic,TRUE);
7004 /*-----------------------------------------------------------------*/
7005 /* genSignedRightShift - right shift of signed number */
7006 /*-----------------------------------------------------------------*/
7007 static void genSignedRightShift (iCode *ic)
7009 operand *right, *left, *result;
7012 symbol *tlbl, *tlbl1 ;
7014 /* we do it the hard way put the shift count in b
7015 and loop thru preserving the sign */
7016 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7018 right = IC_RIGHT(ic);
7020 result = IC_RESULT(ic);
7022 aopOp(right,ic,FALSE);
7025 if ( AOP_TYPE(right) == AOP_LIT) {
7026 genRightShiftLiteral (left,right,result,ic,1);
7029 /* shift count is unknown then we have to form
7030 a loop get the loop count in B : Note: we take
7031 only the lower order byte since shifting
7032 more that 32 bits make no sense anyway, ( the
7033 largest size of an object can be only 32 bits ) */
7035 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7036 pic14_emitcode("inc","b");
7037 freeAsmop (right,NULL,ic,TRUE);
7038 aopOp(left,ic,FALSE);
7039 aopOp(result,ic,FALSE);
7041 /* now move the left to the result if they are not the
7043 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7044 AOP_SIZE(result) > 1) {
7046 size = AOP_SIZE(result);
7049 l = aopGet(AOP(left),offset,FALSE,TRUE);
7050 if (*l == '@' && IS_AOP_PREG(result)) {
7052 pic14_emitcode("mov","a,%s",l);
7053 aopPut(AOP(result),"a",offset);
7055 aopPut(AOP(result),l,offset);
7060 /* mov the highest order bit to OVR */
7061 tlbl = newiTempLabel(NULL);
7062 tlbl1= newiTempLabel(NULL);
7064 size = AOP_SIZE(result);
7066 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7067 pic14_emitcode("rlc","a");
7068 pic14_emitcode("mov","ov,c");
7069 /* if it is only one byte then */
7071 l = aopGet(AOP(left),0,FALSE,FALSE);
7073 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7074 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7075 pic14_emitcode("mov","c,ov");
7076 pic14_emitcode("rrc","a");
7077 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7078 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7079 aopPut(AOP(result),"a",0);
7083 reAdjustPreg(AOP(result));
7084 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7085 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7086 pic14_emitcode("mov","c,ov");
7088 l = aopGet(AOP(result),offset,FALSE,FALSE);
7090 pic14_emitcode("rrc","a");
7091 aopPut(AOP(result),"a",offset--);
7093 reAdjustPreg(AOP(result));
7094 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7095 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7098 freeAsmop(left,NULL,ic,TRUE);
7099 freeAsmop(result,NULL,ic,TRUE);
7102 /*-----------------------------------------------------------------*/
7103 /* genRightShift - generate code for right shifting */
7104 /*-----------------------------------------------------------------*/
7105 static void genRightShift (iCode *ic)
7107 operand *right, *left, *result;
7111 symbol *tlbl, *tlbl1 ;
7113 /* if signed then we do it the hard way preserve the
7114 sign bit moving it inwards */
7115 retype = getSpec(operandType(IC_RESULT(ic)));
7116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7118 if (!SPEC_USIGN(retype)) {
7119 genSignedRightShift (ic);
7123 /* signed & unsigned types are treated the same : i.e. the
7124 signed is NOT propagated inwards : quoting from the
7125 ANSI - standard : "for E1 >> E2, is equivalent to division
7126 by 2**E2 if unsigned or if it has a non-negative value,
7127 otherwise the result is implementation defined ", MY definition
7128 is that the sign does not get propagated */
7130 right = IC_RIGHT(ic);
7132 result = IC_RESULT(ic);
7134 aopOp(right,ic,FALSE);
7136 /* if the shift count is known then do it
7137 as efficiently as possible */
7138 if (AOP_TYPE(right) == AOP_LIT) {
7139 genRightShiftLiteral (left,right,result,ic, 0);
7143 /* shift count is unknown then we have to form
7144 a loop get the loop count in B : Note: we take
7145 only the lower order byte since shifting
7146 more that 32 bits make no sense anyway, ( the
7147 largest size of an object can be only 32 bits ) */
7149 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7150 pic14_emitcode("inc","b");
7151 aopOp(left,ic,FALSE);
7152 aopOp(result,ic,FALSE);
7154 /* now move the left to the result if they are not the
7156 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7157 AOP_SIZE(result) > 1) {
7159 size = AOP_SIZE(result);
7162 l = aopGet(AOP(left),offset,FALSE,TRUE);
7163 if (*l == '@' && IS_AOP_PREG(result)) {
7165 pic14_emitcode("mov","a,%s",l);
7166 aopPut(AOP(result),"a",offset);
7168 aopPut(AOP(result),l,offset);
7173 tlbl = newiTempLabel(NULL);
7174 tlbl1= newiTempLabel(NULL);
7175 size = AOP_SIZE(result);
7178 /* if it is only one byte then */
7181 l = aopGet(AOP(left),0,FALSE,FALSE);
7183 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7184 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7186 pic14_emitcode("rrc","a");
7187 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7188 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7189 aopPut(AOP(result),"a",0);
7191 tlbl = newiTempLabel(NULL);
7192 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7193 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7194 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7197 emitpcode(POC_COMFW, popGet(AOP(right),0));
7198 emitpcode(POC_RLF, popGet(AOP(result),0));
7199 emitpLabel(tlbl->key);
7200 emitpcode(POC_RRF, popGet(AOP(result),0));
7201 emitpcode(POC_ADDLW, popGetLit(1));
7203 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7208 reAdjustPreg(AOP(result));
7209 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7210 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7213 l = aopGet(AOP(result),offset,FALSE,FALSE);
7215 pic14_emitcode("rrc","a");
7216 aopPut(AOP(result),"a",offset--);
7218 reAdjustPreg(AOP(result));
7220 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7221 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7224 freeAsmop(left,NULL,ic,TRUE);
7225 freeAsmop (right,NULL,ic,TRUE);
7226 freeAsmop(result,NULL,ic,TRUE);
7229 /*-----------------------------------------------------------------*/
7230 /* genUnpackBits - generates code for unpacking bits */
7231 /*-----------------------------------------------------------------*/
7232 static void genUnpackBits (operand *result, char *rname, int ptype)
7239 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7240 etype = getSpec(operandType(result));
7242 /* read the first byte */
7247 pic14_emitcode("mov","a,@%s",rname);
7251 pic14_emitcode("movx","a,@%s",rname);
7255 pic14_emitcode("movx","a,@dptr");
7259 pic14_emitcode("clr","a");
7260 pic14_emitcode("movc","a","@a+dptr");
7264 pic14_emitcode("lcall","__gptrget");
7268 /* if we have bitdisplacement then it fits */
7269 /* into this byte completely or if length is */
7270 /* less than a byte */
7271 if ((shCnt = SPEC_BSTR(etype)) ||
7272 (SPEC_BLEN(etype) <= 8)) {
7274 /* shift right acc */
7277 pic14_emitcode("anl","a,#0x%02x",
7278 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7279 aopPut(AOP(result),"a",offset);
7283 /* bit field did not fit in a byte */
7284 rlen = SPEC_BLEN(etype) - 8;
7285 aopPut(AOP(result),"a",offset++);
7292 pic14_emitcode("inc","%s",rname);
7293 pic14_emitcode("mov","a,@%s",rname);
7297 pic14_emitcode("inc","%s",rname);
7298 pic14_emitcode("movx","a,@%s",rname);
7302 pic14_emitcode("inc","dptr");
7303 pic14_emitcode("movx","a,@dptr");
7307 pic14_emitcode("clr","a");
7308 pic14_emitcode("inc","dptr");
7309 pic14_emitcode("movc","a","@a+dptr");
7313 pic14_emitcode("inc","dptr");
7314 pic14_emitcode("lcall","__gptrget");
7319 /* if we are done */
7323 aopPut(AOP(result),"a",offset++);
7328 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7329 aopPut(AOP(result),"a",offset);
7336 /*-----------------------------------------------------------------*/
7337 /* genDataPointerGet - generates code when ptr offset is known */
7338 /*-----------------------------------------------------------------*/
7339 static void genDataPointerGet (operand *left,
7343 int size , offset = 0;
7346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7349 /* optimization - most of the time, left and result are the same
7350 * address, but different types. for the pic code, we could omit
7354 aopOp(result,ic,TRUE);
7356 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7358 size = AOP_SIZE(result);
7361 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7365 freeAsmop(left,NULL,ic,TRUE);
7366 freeAsmop(result,NULL,ic,TRUE);
7369 /*-----------------------------------------------------------------*/
7370 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7371 /*-----------------------------------------------------------------*/
7372 static void genNearPointerGet (operand *left,
7379 sym_link *rtype, *retype;
7380 sym_link *ltype = operandType(left);
7383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7385 rtype = operandType(result);
7386 retype= getSpec(rtype);
7388 aopOp(left,ic,FALSE);
7390 /* if left is rematerialisable and
7391 result is not bit variable type and
7392 the left is pointer to data space i.e
7393 lower 128 bytes of space */
7394 if (AOP_TYPE(left) == AOP_IMMD &&
7395 !IS_BITVAR(retype) &&
7396 DCL_TYPE(ltype) == POINTER) {
7397 genDataPointerGet (left,result,ic);
7401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7403 /* if the value is already in a pointer register
7404 then don't need anything more */
7405 if (!AOP_INPREG(AOP(left))) {
7406 /* otherwise get a free pointer register */
7407 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7409 preg = getFreePtr(ic,&aop,FALSE);
7410 pic14_emitcode("mov","%s,%s",
7412 aopGet(AOP(left),0,FALSE,TRUE));
7413 rname = preg->name ;
7415 rname = aopGet(AOP(left),0,FALSE,FALSE);
7417 freeAsmop(left,NULL,ic,TRUE);
7418 aopOp (result,ic,FALSE);
7420 /* if bitfield then unpack the bits */
7421 if (IS_BITVAR(retype))
7422 genUnpackBits (result,rname,POINTER);
7424 /* we have can just get the values */
7425 int size = AOP_SIZE(result);
7428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7430 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7432 pic14_emitcode("mov","a,@%s",rname);
7433 aopPut(AOP(result),"a",offset);
7435 sprintf(buffer,"@%s",rname);
7436 aopPut(AOP(result),buffer,offset);
7440 pic14_emitcode("inc","%s",rname);
7444 /* now some housekeeping stuff */
7446 /* we had to allocate for this iCode */
7447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7448 freeAsmop(NULL,aop,ic,TRUE);
7450 /* we did not allocate which means left
7451 already in a pointer register, then
7452 if size > 0 && this could be used again
7453 we have to point it back to where it
7455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7456 if (AOP_SIZE(result) > 1 &&
7457 !OP_SYMBOL(left)->remat &&
7458 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7460 int size = AOP_SIZE(result) - 1;
7462 pic14_emitcode("dec","%s",rname);
7467 freeAsmop(result,NULL,ic,TRUE);
7471 /*-----------------------------------------------------------------*/
7472 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7473 /*-----------------------------------------------------------------*/
7474 static void genPagedPointerGet (operand *left,
7481 sym_link *rtype, *retype;
7483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7485 rtype = operandType(result);
7486 retype= getSpec(rtype);
7488 aopOp(left,ic,FALSE);
7490 /* if the value is already in a pointer register
7491 then don't need anything more */
7492 if (!AOP_INPREG(AOP(left))) {
7493 /* otherwise get a free pointer register */
7495 preg = getFreePtr(ic,&aop,FALSE);
7496 pic14_emitcode("mov","%s,%s",
7498 aopGet(AOP(left),0,FALSE,TRUE));
7499 rname = preg->name ;
7501 rname = aopGet(AOP(left),0,FALSE,FALSE);
7503 freeAsmop(left,NULL,ic,TRUE);
7504 aopOp (result,ic,FALSE);
7506 /* if bitfield then unpack the bits */
7507 if (IS_BITVAR(retype))
7508 genUnpackBits (result,rname,PPOINTER);
7510 /* we have can just get the values */
7511 int size = AOP_SIZE(result);
7516 pic14_emitcode("movx","a,@%s",rname);
7517 aopPut(AOP(result),"a",offset);
7522 pic14_emitcode("inc","%s",rname);
7526 /* now some housekeeping stuff */
7528 /* we had to allocate for this iCode */
7529 freeAsmop(NULL,aop,ic,TRUE);
7531 /* we did not allocate which means left
7532 already in a pointer register, then
7533 if size > 0 && this could be used again
7534 we have to point it back to where it
7536 if (AOP_SIZE(result) > 1 &&
7537 !OP_SYMBOL(left)->remat &&
7538 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7540 int size = AOP_SIZE(result) - 1;
7542 pic14_emitcode("dec","%s",rname);
7547 freeAsmop(result,NULL,ic,TRUE);
7552 /*-----------------------------------------------------------------*/
7553 /* genFarPointerGet - gget value from far space */
7554 /*-----------------------------------------------------------------*/
7555 static void genFarPointerGet (operand *left,
7556 operand *result, iCode *ic)
7559 sym_link *retype = getSpec(operandType(result));
7561 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7563 aopOp(left,ic,FALSE);
7565 /* if the operand is already in dptr
7566 then we do nothing else we move the value to dptr */
7567 if (AOP_TYPE(left) != AOP_STR) {
7568 /* if this is remateriazable */
7569 if (AOP_TYPE(left) == AOP_IMMD)
7570 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7571 else { /* we need to get it byte by byte */
7572 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7573 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7574 if (options.model == MODEL_FLAT24)
7576 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7580 /* so dptr know contains the address */
7581 freeAsmop(left,NULL,ic,TRUE);
7582 aopOp(result,ic,FALSE);
7584 /* if bit then unpack */
7585 if (IS_BITVAR(retype))
7586 genUnpackBits(result,"dptr",FPOINTER);
7588 size = AOP_SIZE(result);
7592 pic14_emitcode("movx","a,@dptr");
7593 aopPut(AOP(result),"a",offset++);
7595 pic14_emitcode("inc","dptr");
7599 freeAsmop(result,NULL,ic,TRUE);
7602 /*-----------------------------------------------------------------*/
7603 /* pic14_emitcodePointerGet - gget value from code space */
7604 /*-----------------------------------------------------------------*/
7605 static void pic14_emitcodePointerGet (operand *left,
7606 operand *result, iCode *ic)
7609 sym_link *retype = getSpec(operandType(result));
7611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7613 aopOp(left,ic,FALSE);
7615 /* if the operand is already in dptr
7616 then we do nothing else we move the value to dptr */
7617 if (AOP_TYPE(left) != AOP_STR) {
7618 /* if this is remateriazable */
7619 if (AOP_TYPE(left) == AOP_IMMD)
7620 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7621 else { /* we need to get it byte by byte */
7622 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7623 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7624 if (options.model == MODEL_FLAT24)
7626 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7630 /* so dptr know contains the address */
7631 freeAsmop(left,NULL,ic,TRUE);
7632 aopOp(result,ic,FALSE);
7634 /* if bit then unpack */
7635 if (IS_BITVAR(retype))
7636 genUnpackBits(result,"dptr",CPOINTER);
7638 size = AOP_SIZE(result);
7642 pic14_emitcode("clr","a");
7643 pic14_emitcode("movc","a,@a+dptr");
7644 aopPut(AOP(result),"a",offset++);
7646 pic14_emitcode("inc","dptr");
7650 freeAsmop(result,NULL,ic,TRUE);
7653 /*-----------------------------------------------------------------*/
7654 /* genGenPointerGet - gget value from generic pointer space */
7655 /*-----------------------------------------------------------------*/
7656 static void genGenPointerGet (operand *left,
7657 operand *result, iCode *ic)
7660 sym_link *retype = getSpec(operandType(result));
7662 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7663 aopOp(left,ic,FALSE);
7664 aopOp(result,ic,FALSE);
7667 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7669 /* if the operand is already in dptr
7670 then we do nothing else we move the value to dptr */
7671 if (AOP_TYPE(left) != AOP_STR) {
7672 /* if this is remateriazable */
7673 if (AOP_TYPE(left) == AOP_IMMD) {
7674 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7675 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7677 else { /* we need to get it byte by byte */
7679 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7680 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7682 size = AOP_SIZE(result);
7686 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7687 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7689 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7694 /* so dptr know contains the address */
7696 /* if bit then unpack */
7697 if (IS_BITVAR(retype))
7698 genUnpackBits(result,"dptr",GPOINTER);
7701 freeAsmop(left,NULL,ic,TRUE);
7702 freeAsmop(result,NULL,ic,TRUE);
7706 /*-----------------------------------------------------------------*/
7707 /* genPointerGet - generate code for pointer get */
7708 /*-----------------------------------------------------------------*/
7709 static void genPointerGet (iCode *ic)
7711 operand *left, *result ;
7712 sym_link *type, *etype;
7715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7718 result = IC_RESULT(ic) ;
7720 /* depending on the type of pointer we need to
7721 move it to the correct pointer register */
7722 type = operandType(left);
7723 etype = getSpec(type);
7724 /* if left is of type of pointer then it is simple */
7725 if (IS_PTR(type) && !IS_FUNC(type->next))
7726 p_type = DCL_TYPE(type);
7728 /* we have to go by the storage class */
7729 p_type = PTR_TYPE(SPEC_OCLS(etype));
7731 /* if (SPEC_OCLS(etype)->codesp ) { */
7732 /* p_type = CPOINTER ; */
7735 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7736 /* p_type = FPOINTER ; */
7738 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7739 /* p_type = PPOINTER; */
7741 /* if (SPEC_OCLS(etype) == idata ) */
7742 /* p_type = IPOINTER; */
7744 /* p_type = POINTER ; */
7747 /* now that we have the pointer type we assign
7748 the pointer values */
7753 genNearPointerGet (left,result,ic);
7757 genPagedPointerGet(left,result,ic);
7761 genFarPointerGet (left,result,ic);
7765 pic14_emitcodePointerGet (left,result,ic);
7769 genGenPointerGet (left,result,ic);
7775 /*-----------------------------------------------------------------*/
7776 /* genPackBits - generates code for packed bit storage */
7777 /*-----------------------------------------------------------------*/
7778 static void genPackBits (sym_link *etype ,
7780 char *rname, int p_type)
7788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7789 blen = SPEC_BLEN(etype);
7790 bstr = SPEC_BSTR(etype);
7792 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7795 /* if the bit lenth is less than or */
7796 /* it exactly fits a byte then */
7797 if (SPEC_BLEN(etype) <= 8 ) {
7798 shCount = SPEC_BSTR(etype) ;
7800 /* shift left acc */
7803 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7808 pic14_emitcode ("mov","b,a");
7809 pic14_emitcode("mov","a,@%s",rname);
7813 pic14_emitcode ("mov","b,a");
7814 pic14_emitcode("movx","a,@dptr");
7818 pic14_emitcode ("push","b");
7819 pic14_emitcode ("push","acc");
7820 pic14_emitcode ("lcall","__gptrget");
7821 pic14_emitcode ("pop","b");
7825 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7826 ((unsigned char)(0xFF << (blen+bstr)) |
7827 (unsigned char)(0xFF >> (8-bstr)) ) );
7828 pic14_emitcode ("orl","a,b");
7829 if (p_type == GPOINTER)
7830 pic14_emitcode("pop","b");
7836 pic14_emitcode("mov","@%s,a",rname);
7840 pic14_emitcode("movx","@dptr,a");
7844 DEBUGpic14_emitcode(";lcall","__gptrput");
7849 if ( SPEC_BLEN(etype) <= 8 )
7852 pic14_emitcode("inc","%s",rname);
7853 rLen = SPEC_BLEN(etype) ;
7855 /* now generate for lengths greater than one byte */
7858 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7868 pic14_emitcode("mov","@%s,a",rname);
7870 pic14_emitcode("mov","@%s,%s",rname,l);
7875 pic14_emitcode("movx","@dptr,a");
7880 DEBUGpic14_emitcode(";lcall","__gptrput");
7883 pic14_emitcode ("inc","%s",rname);
7888 /* last last was not complete */
7890 /* save the byte & read byte */
7893 pic14_emitcode ("mov","b,a");
7894 pic14_emitcode("mov","a,@%s",rname);
7898 pic14_emitcode ("mov","b,a");
7899 pic14_emitcode("movx","a,@dptr");
7903 pic14_emitcode ("push","b");
7904 pic14_emitcode ("push","acc");
7905 pic14_emitcode ("lcall","__gptrget");
7906 pic14_emitcode ("pop","b");
7910 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7911 pic14_emitcode ("orl","a,b");
7914 if (p_type == GPOINTER)
7915 pic14_emitcode("pop","b");
7920 pic14_emitcode("mov","@%s,a",rname);
7924 pic14_emitcode("movx","@dptr,a");
7928 DEBUGpic14_emitcode(";lcall","__gptrput");
7932 /*-----------------------------------------------------------------*/
7933 /* genDataPointerSet - remat pointer to data space */
7934 /*-----------------------------------------------------------------*/
7935 static void genDataPointerSet(operand *right,
7939 int size, offset = 0 ;
7940 char *l, buffer[256];
7942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7943 aopOp(right,ic,FALSE);
7945 l = aopGet(AOP(result),0,FALSE,TRUE);
7946 size = AOP_SIZE(right);
7947 // tsd, was l+1 - the underline `_' prefix was being stripped
7950 sprintf(buffer,"(%s + %d)",l,offset);
7952 sprintf(buffer,"%s",l);
7954 if (AOP_TYPE(right) == AOP_LIT) {
7955 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7956 lit = lit >> (8*offset);
7958 pic14_emitcode("movlw","%d",lit);
7959 pic14_emitcode("movwf","%s",buffer);
7961 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7962 emitpcode(POC_MOVWF, popRegFromString(buffer));
7965 pic14_emitcode("clrf","%s",buffer);
7966 emitpcode(POC_CLRF, popRegFromString(buffer));
7969 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7970 pic14_emitcode("movwf","%s",buffer);
7972 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7973 emitpcode(POC_MOVWF, popRegFromString(buffer));
7980 freeAsmop(right,NULL,ic,TRUE);
7981 freeAsmop(result,NULL,ic,TRUE);
7984 /*-----------------------------------------------------------------*/
7985 /* genNearPointerSet - pic14_emitcode for near pointer put */
7986 /*-----------------------------------------------------------------*/
7987 static void genNearPointerSet (operand *right,
7994 sym_link *ptype = operandType(result);
7997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7998 retype= getSpec(operandType(right));
8000 aopOp(result,ic,FALSE);
8002 /* if the result is rematerializable &
8003 in data space & not a bit variable */
8004 if (AOP_TYPE(result) == AOP_IMMD &&
8005 DCL_TYPE(ptype) == POINTER &&
8006 !IS_BITVAR(retype)) {
8007 genDataPointerSet (right,result,ic);
8011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8013 /* if the value is already in a pointer register
8014 then don't need anything more */
8015 if (!AOP_INPREG(AOP(result))) {
8016 /* otherwise get a free pointer register */
8017 //aop = newAsmop(0);
8018 //preg = getFreePtr(ic,&aop,FALSE);
8019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8020 //pic14_emitcode("mov","%s,%s",
8022 // aopGet(AOP(result),0,FALSE,TRUE));
8023 //rname = preg->name ;
8024 pic14_emitcode("movwf","fsr");
8026 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8028 freeAsmop(result,NULL,ic,TRUE);
8029 aopOp (right,ic,FALSE);
8030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8032 /* if bitfield then unpack the bits */
8033 if (IS_BITVAR(retype)) {
8034 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8035 "The programmer is obviously confused");
8036 //genPackBits (retype,right,rname,POINTER);
8040 /* we have can just get the values */
8041 int size = AOP_SIZE(right);
8044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8046 l = aopGet(AOP(right),offset,FALSE,TRUE);
8049 //pic14_emitcode("mov","@%s,a",rname);
8050 pic14_emitcode("movf","indf,w ;1");
8053 if (AOP_TYPE(right) == AOP_LIT) {
8054 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8056 pic14_emitcode("movlw","%s",l);
8057 pic14_emitcode("movwf","indf ;2");
8059 pic14_emitcode("clrf","indf");
8061 pic14_emitcode("movf","%s,w",l);
8062 pic14_emitcode("movwf","indf ;2");
8064 //pic14_emitcode("mov","@%s,%s",rname,l);
8067 pic14_emitcode("incf","fsr,f ;3");
8068 //pic14_emitcode("inc","%s",rname);
8073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8074 /* now some housekeeping stuff */
8076 /* we had to allocate for this iCode */
8077 freeAsmop(NULL,aop,ic,TRUE);
8079 /* we did not allocate which means left
8080 already in a pointer register, then
8081 if size > 0 && this could be used again
8082 we have to point it back to where it
8084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8085 if (AOP_SIZE(right) > 1 &&
8086 !OP_SYMBOL(result)->remat &&
8087 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8089 int size = AOP_SIZE(right) - 1;
8091 pic14_emitcode("decf","fsr,f");
8092 //pic14_emitcode("dec","%s",rname);
8096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8098 freeAsmop(right,NULL,ic,TRUE);
8103 /*-----------------------------------------------------------------*/
8104 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8105 /*-----------------------------------------------------------------*/
8106 static void genPagedPointerSet (operand *right,
8115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8117 retype= getSpec(operandType(right));
8119 aopOp(result,ic,FALSE);
8121 /* if the value is already in a pointer register
8122 then don't need anything more */
8123 if (!AOP_INPREG(AOP(result))) {
8124 /* otherwise get a free pointer register */
8126 preg = getFreePtr(ic,&aop,FALSE);
8127 pic14_emitcode("mov","%s,%s",
8129 aopGet(AOP(result),0,FALSE,TRUE));
8130 rname = preg->name ;
8132 rname = aopGet(AOP(result),0,FALSE,FALSE);
8134 freeAsmop(result,NULL,ic,TRUE);
8135 aopOp (right,ic,FALSE);
8137 /* if bitfield then unpack the bits */
8138 if (IS_BITVAR(retype))
8139 genPackBits (retype,right,rname,PPOINTER);
8141 /* we have can just get the values */
8142 int size = AOP_SIZE(right);
8146 l = aopGet(AOP(right),offset,FALSE,TRUE);
8149 pic14_emitcode("movx","@%s,a",rname);
8152 pic14_emitcode("inc","%s",rname);
8158 /* now some housekeeping stuff */
8160 /* we had to allocate for this iCode */
8161 freeAsmop(NULL,aop,ic,TRUE);
8163 /* we did not allocate which means left
8164 already in a pointer register, then
8165 if size > 0 && this could be used again
8166 we have to point it back to where it
8168 if (AOP_SIZE(right) > 1 &&
8169 !OP_SYMBOL(result)->remat &&
8170 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8172 int size = AOP_SIZE(right) - 1;
8174 pic14_emitcode("dec","%s",rname);
8179 freeAsmop(right,NULL,ic,TRUE);
8184 /*-----------------------------------------------------------------*/
8185 /* genFarPointerSet - set value from far space */
8186 /*-----------------------------------------------------------------*/
8187 static void genFarPointerSet (operand *right,
8188 operand *result, iCode *ic)
8191 sym_link *retype = getSpec(operandType(right));
8193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8194 aopOp(result,ic,FALSE);
8196 /* if the operand is already in dptr
8197 then we do nothing else we move the value to dptr */
8198 if (AOP_TYPE(result) != AOP_STR) {
8199 /* if this is remateriazable */
8200 if (AOP_TYPE(result) == AOP_IMMD)
8201 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8202 else { /* we need to get it byte by byte */
8203 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8204 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8205 if (options.model == MODEL_FLAT24)
8207 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8211 /* so dptr know contains the address */
8212 freeAsmop(result,NULL,ic,TRUE);
8213 aopOp(right,ic,FALSE);
8215 /* if bit then unpack */
8216 if (IS_BITVAR(retype))
8217 genPackBits(retype,right,"dptr",FPOINTER);
8219 size = AOP_SIZE(right);
8223 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8225 pic14_emitcode("movx","@dptr,a");
8227 pic14_emitcode("inc","dptr");
8231 freeAsmop(right,NULL,ic,TRUE);
8234 /*-----------------------------------------------------------------*/
8235 /* genGenPointerSet - set value from generic pointer space */
8236 /*-----------------------------------------------------------------*/
8237 static void genGenPointerSet (operand *right,
8238 operand *result, iCode *ic)
8241 sym_link *retype = getSpec(operandType(right));
8243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8245 aopOp(result,ic,FALSE);
8246 aopOp(right,ic,FALSE);
8247 size = AOP_SIZE(right);
8249 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8251 /* if the operand is already in dptr
8252 then we do nothing else we move the value to dptr */
8253 if (AOP_TYPE(result) != AOP_STR) {
8254 /* if this is remateriazable */
8255 if (AOP_TYPE(result) == AOP_IMMD) {
8256 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8257 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8259 else { /* we need to get it byte by byte */
8260 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8261 size = AOP_SIZE(right);
8264 /* hack hack! see if this the FSR. If so don't load W */
8265 if(AOP_TYPE(right) != AOP_ACC) {
8267 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8268 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8271 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8273 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8274 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8278 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8279 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8282 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8289 if(aopIdx(AOP(result),0) != 4) {
8291 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8295 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8300 /* so dptr know contains the address */
8303 /* if bit then unpack */
8304 if (IS_BITVAR(retype))
8305 genPackBits(retype,right,"dptr",GPOINTER);
8307 size = AOP_SIZE(right);
8311 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8313 pic14_emitcode("incf","fsr,f");
8314 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8315 pic14_emitcode("movwf","indf");
8317 //DEBUGpic14_emitcode(";lcall","__gptrput");
8319 // pic14_emitcode("inc","dptr");
8324 freeAsmop(right,NULL,ic,TRUE);
8325 freeAsmop(result,NULL,ic,TRUE);
8328 /*-----------------------------------------------------------------*/
8329 /* genPointerSet - stores the value into a pointer location */
8330 /*-----------------------------------------------------------------*/
8331 static void genPointerSet (iCode *ic)
8333 operand *right, *result ;
8334 sym_link *type, *etype;
8337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8339 right = IC_RIGHT(ic);
8340 result = IC_RESULT(ic) ;
8342 /* depending on the type of pointer we need to
8343 move it to the correct pointer register */
8344 type = operandType(result);
8345 etype = getSpec(type);
8346 /* if left is of type of pointer then it is simple */
8347 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8348 p_type = DCL_TYPE(type);
8351 /* we have to go by the storage class */
8352 p_type = PTR_TYPE(SPEC_OCLS(etype));
8354 /* if (SPEC_OCLS(etype)->codesp ) { */
8355 /* p_type = CPOINTER ; */
8358 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8359 /* p_type = FPOINTER ; */
8361 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8362 /* p_type = PPOINTER ; */
8364 /* if (SPEC_OCLS(etype) == idata ) */
8365 /* p_type = IPOINTER ; */
8367 /* p_type = POINTER ; */
8370 /* now that we have the pointer type we assign
8371 the pointer values */
8376 genNearPointerSet (right,result,ic);
8380 genPagedPointerSet (right,result,ic);
8384 genFarPointerSet (right,result,ic);
8388 genGenPointerSet (right,result,ic);
8394 /*-----------------------------------------------------------------*/
8395 /* genIfx - generate code for Ifx statement */
8396 /*-----------------------------------------------------------------*/
8397 static void genIfx (iCode *ic, iCode *popIc)
8399 operand *cond = IC_COND(ic);
8402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8404 aopOp(cond,ic,FALSE);
8406 /* get the value into acc */
8407 if (AOP_TYPE(cond) != AOP_CRY)
8408 pic14_toBoolean(cond);
8411 /* the result is now in the accumulator */
8412 freeAsmop(cond,NULL,ic,TRUE);
8414 /* if there was something to be popped then do it */
8418 /* if the condition is a bit variable */
8419 if (isbit && IS_ITEMP(cond) &&
8421 genIfxJump(ic,SPIL_LOC(cond)->rname);
8422 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8425 if (isbit && !IS_ITEMP(cond))
8426 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8434 /*-----------------------------------------------------------------*/
8435 /* genAddrOf - generates code for address of */
8436 /*-----------------------------------------------------------------*/
8437 static void genAddrOf (iCode *ic)
8439 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8440 operand *right, *result, *left;
8441 //int size, offset ;
8443 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8446 //aopOp(IC_RESULT(ic),ic,FALSE);
8448 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8449 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8450 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8452 DEBUGpic14_AopType(__LINE__,left,right,result);
8454 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8455 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8458 /* object not on stack then we need the name */
8459 size = AOP_SIZE(IC_RESULT(ic));
8463 char s[SDCC_NAME_MAX];
8465 sprintf(s,"#(%s >> %d)",
8469 sprintf(s,"#%s",sym->rname);
8470 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8475 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8476 freeAsmop(left,NULL,ic,FALSE);
8477 freeAsmop(result,NULL,ic,TRUE);
8482 /*-----------------------------------------------------------------*/
8483 /* genFarFarAssign - assignment when both are in far space */
8484 /*-----------------------------------------------------------------*/
8485 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8487 int size = AOP_SIZE(right);
8490 /* first push the right side on to the stack */
8492 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8494 pic14_emitcode ("push","acc");
8497 freeAsmop(right,NULL,ic,FALSE);
8498 /* now assign DPTR to result */
8499 aopOp(result,ic,FALSE);
8500 size = AOP_SIZE(result);
8502 pic14_emitcode ("pop","acc");
8503 aopPut(AOP(result),"a",--offset);
8505 freeAsmop(result,NULL,ic,FALSE);
8510 /*-----------------------------------------------------------------*/
8511 /* genAssign - generate code for assignment */
8512 /*-----------------------------------------------------------------*/
8513 static void genAssign (iCode *ic)
8515 operand *result, *right;
8516 int size, offset,know_W;
8517 unsigned long lit = 0L;
8519 result = IC_RESULT(ic);
8520 right = IC_RIGHT(ic) ;
8522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8524 /* if they are the same */
8525 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8528 aopOp(right,ic,FALSE);
8529 aopOp(result,ic,TRUE);
8531 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8533 /* if they are the same registers */
8534 if (pic14_sameRegs(AOP(right),AOP(result)))
8537 /* if the result is a bit */
8538 if (AOP_TYPE(result) == AOP_CRY) {
8540 /* if the right size is a literal then
8541 we know what the value is */
8542 if (AOP_TYPE(right) == AOP_LIT) {
8544 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8545 popGet(AOP(result),0));
8547 if (((int) operandLitValue(right)))
8548 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8549 AOP(result)->aopu.aop_dir,
8550 AOP(result)->aopu.aop_dir);
8552 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8553 AOP(result)->aopu.aop_dir,
8554 AOP(result)->aopu.aop_dir);
8558 /* the right is also a bit variable */
8559 if (AOP_TYPE(right) == AOP_CRY) {
8560 emitpcode(POC_BCF, popGet(AOP(result),0));
8561 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8562 emitpcode(POC_BSF, popGet(AOP(result),0));
8564 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8565 AOP(result)->aopu.aop_dir,
8566 AOP(result)->aopu.aop_dir);
8567 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8568 AOP(right)->aopu.aop_dir,
8569 AOP(right)->aopu.aop_dir);
8570 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8571 AOP(result)->aopu.aop_dir,
8572 AOP(result)->aopu.aop_dir);
8577 emitpcode(POC_BCF, popGet(AOP(result),0));
8578 pic14_toBoolean(right);
8580 emitpcode(POC_BSF, popGet(AOP(result),0));
8581 //aopPut(AOP(result),"a",0);
8585 /* bit variables done */
8587 size = AOP_SIZE(result);
8589 if(AOP_TYPE(right) == AOP_LIT)
8590 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8592 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8593 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8594 if(aopIdx(AOP(result),0) == 4) {
8595 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8596 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8597 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8600 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8606 if(AOP_TYPE(right) == AOP_LIT) {
8608 if(know_W != (lit&0xff))
8609 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8611 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8613 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8617 } else if (AOP_TYPE(right) == AOP_CRY) {
8618 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8620 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8621 emitpcode(POC_INCF, popGet(AOP(result),0));
8624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8625 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8626 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8634 freeAsmop (right,NULL,ic,FALSE);
8635 freeAsmop (result,NULL,ic,TRUE);
8638 /*-----------------------------------------------------------------*/
8639 /* genJumpTab - genrates code for jump table */
8640 /*-----------------------------------------------------------------*/
8641 static void genJumpTab (iCode *ic)
8646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8648 aopOp(IC_JTCOND(ic),ic,FALSE);
8649 /* get the condition into accumulator */
8650 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8652 /* multiply by three */
8653 pic14_emitcode("add","a,acc");
8654 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8656 jtab = newiTempLabel(NULL);
8657 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8658 pic14_emitcode("jmp","@a+dptr");
8659 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8661 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8662 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8664 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8665 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8666 emitpLabel(jtab->key);
8668 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8670 /* now generate the jump labels */
8671 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8672 jtab = setNextItem(IC_JTLABELS(ic))) {
8673 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8674 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8680 /*-----------------------------------------------------------------*/
8681 /* genMixedOperation - gen code for operators between mixed types */
8682 /*-----------------------------------------------------------------*/
8684 TSD - Written for the PIC port - but this unfortunately is buggy.
8685 This routine is good in that it is able to efficiently promote
8686 types to different (larger) sizes. Unfortunately, the temporary
8687 variables that are optimized out by this routine are sometimes
8688 used in other places. So until I know how to really parse the
8689 iCode tree, I'm going to not be using this routine :(.
8691 static int genMixedOperation (iCode *ic)
8694 operand *result = IC_RESULT(ic);
8695 sym_link *ctype = operandType(IC_LEFT(ic));
8696 operand *right = IC_RIGHT(ic);
8702 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8704 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8710 nextright = IC_RIGHT(nextic);
8711 nextleft = IC_LEFT(nextic);
8712 nextresult = IC_RESULT(nextic);
8714 aopOp(right,ic,FALSE);
8715 aopOp(result,ic,FALSE);
8716 aopOp(nextright, nextic, FALSE);
8717 aopOp(nextleft, nextic, FALSE);
8718 aopOp(nextresult, nextic, FALSE);
8720 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8726 pic14_emitcode(";remove right +","");
8728 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8734 pic14_emitcode(";remove left +","");
8738 big = AOP_SIZE(nextleft);
8739 small = AOP_SIZE(nextright);
8741 switch(nextic->op) {
8744 pic14_emitcode(";optimize a +","");
8745 /* if unsigned or not an integral type */
8746 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8747 pic14_emitcode(";add a bit to something","");
8750 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8752 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8753 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8754 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8756 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8764 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8765 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8766 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8769 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8771 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8772 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8773 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8774 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8775 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8778 pic14_emitcode("rlf","known_zero,w");
8785 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8786 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8787 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8789 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8799 freeAsmop(right,NULL,ic,TRUE);
8800 freeAsmop(result,NULL,ic,TRUE);
8801 freeAsmop(nextright,NULL,ic,TRUE);
8802 freeAsmop(nextleft,NULL,ic,TRUE);
8804 nextic->generated = 1;
8811 /*-----------------------------------------------------------------*/
8812 /* genCast - gen code for casting */
8813 /*-----------------------------------------------------------------*/
8814 static void genCast (iCode *ic)
8816 operand *result = IC_RESULT(ic);
8817 sym_link *ctype = operandType(IC_LEFT(ic));
8818 sym_link *rtype = operandType(IC_RIGHT(ic));
8819 operand *right = IC_RIGHT(ic);
8822 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8823 /* if they are equivalent then do nothing */
8824 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8827 aopOp(right,ic,FALSE) ;
8828 aopOp(result,ic,FALSE);
8830 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8832 /* if the result is a bit */
8833 if (AOP_TYPE(result) == AOP_CRY) {
8834 /* if the right size is a literal then
8835 we know what the value is */
8836 if (AOP_TYPE(right) == AOP_LIT) {
8838 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8839 popGet(AOP(result),0));
8841 if (((int) operandLitValue(right)))
8842 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8843 AOP(result)->aopu.aop_dir,
8844 AOP(result)->aopu.aop_dir);
8846 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8847 AOP(result)->aopu.aop_dir,
8848 AOP(result)->aopu.aop_dir);
8853 /* the right is also a bit variable */
8854 if (AOP_TYPE(right) == AOP_CRY) {
8857 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8859 pic14_emitcode("clrc","");
8860 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8861 AOP(right)->aopu.aop_dir,
8862 AOP(right)->aopu.aop_dir);
8863 aopPut(AOP(result),"c",0);
8868 if (AOP_TYPE(right) == AOP_REG) {
8869 emitpcode(POC_BCF, popGet(AOP(result),0));
8870 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8871 emitpcode(POC_BSF, popGet(AOP(result),0));
8873 pic14_toBoolean(right);
8874 aopPut(AOP(result),"a",0);
8878 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8880 size = AOP_SIZE(result);
8882 emitpcode(POC_CLRF, popGet(AOP(result),0));
8883 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8884 emitpcode(POC_INCF, popGet(AOP(result),0));
8887 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8892 /* if they are the same size : or less */
8893 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8895 /* if they are in the same place */
8896 if (pic14_sameRegs(AOP(right),AOP(result)))
8899 /* if they in different places then copy */
8900 size = AOP_SIZE(result);
8904 aopGet(AOP(right),offset,FALSE,FALSE),
8912 /* if the result is of type pointer */
8913 if (IS_PTR(ctype)) {
8916 sym_link *type = operandType(right);
8917 sym_link *etype = getSpec(type);
8919 /* pointer to generic pointer */
8920 if (IS_GENPTR(ctype)) {
8924 p_type = DCL_TYPE(type);
8926 /* we have to go by the storage class */
8927 p_type = PTR_TYPE(SPEC_OCLS(etype));
8929 /* if (SPEC_OCLS(etype)->codesp ) */
8930 /* p_type = CPOINTER ; */
8932 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8933 /* p_type = FPOINTER ; */
8935 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8936 /* p_type = PPOINTER; */
8938 /* if (SPEC_OCLS(etype) == idata ) */
8939 /* p_type = IPOINTER ; */
8941 /* p_type = POINTER ; */
8944 /* the first two bytes are known */
8945 size = GPTRSIZE - 1;
8949 aopGet(AOP(right),offset,FALSE,FALSE),
8953 /* the last byte depending on type */
8970 /* this should never happen */
8971 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8972 "got unknown pointer type");
8975 aopPut(AOP(result),l, GPTRSIZE - 1);
8979 /* just copy the pointers */
8980 size = AOP_SIZE(result);
8984 aopGet(AOP(right),offset,FALSE,FALSE),
8993 /* so we now know that the size of destination is greater
8994 than the size of the source.
8995 Now, if the next iCode is an operator then we might be
8996 able to optimize the operation without performing a cast.
8998 if(genMixedOperation(ic))
9002 /* we move to result for the size of source */
9003 size = AOP_SIZE(right);
9006 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9007 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9011 /* now depending on the sign of the destination */
9012 size = AOP_SIZE(result) - AOP_SIZE(right);
9013 /* if unsigned or not an integral type */
9014 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9016 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9018 /* we need to extend the sign :{ */
9021 /* Save one instruction of casting char to int */
9022 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9023 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9024 emitpcode(POC_DECF, popGet(AOP(result),offset));
9026 emitpcodeNULLop(POC_CLRW);
9029 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9031 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9033 emitpcode(POC_MOVLW, popGetLit(0xff));
9036 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9041 freeAsmop(right,NULL,ic,TRUE);
9042 freeAsmop(result,NULL,ic,TRUE);
9046 /*-----------------------------------------------------------------*/
9047 /* genDjnz - generate decrement & jump if not zero instrucion */
9048 /*-----------------------------------------------------------------*/
9049 static int genDjnz (iCode *ic, iCode *ifx)
9052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9057 /* if the if condition has a false label
9058 then we cannot save */
9062 /* if the minus is not of the form
9064 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9065 !IS_OP_LITERAL(IC_RIGHT(ic)))
9068 if (operandLitValue(IC_RIGHT(ic)) != 1)
9071 /* if the size of this greater than one then no
9073 if (getSize(operandType(IC_RESULT(ic))) > 1)
9076 /* otherwise we can save BIG */
9077 lbl = newiTempLabel(NULL);
9078 lbl1= newiTempLabel(NULL);
9080 aopOp(IC_RESULT(ic),ic,FALSE);
9082 if (IS_AOP_PREG(IC_RESULT(ic))) {
9083 pic14_emitcode("dec","%s",
9084 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9085 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9086 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9090 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9091 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9093 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9094 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9097 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9098 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9099 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9100 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9103 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9108 /*-----------------------------------------------------------------*/
9109 /* genReceive - generate code for a receive iCode */
9110 /*-----------------------------------------------------------------*/
9111 static void genReceive (iCode *ic)
9113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9115 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9116 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9117 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9119 int size = getSize(operandType(IC_RESULT(ic)));
9120 int offset = fReturnSizePic - size;
9122 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9123 fReturn[fReturnSizePic - offset - 1] : "acc"));
9126 aopOp(IC_RESULT(ic),ic,FALSE);
9127 size = AOP_SIZE(IC_RESULT(ic));
9130 pic14_emitcode ("pop","acc");
9131 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9136 aopOp(IC_RESULT(ic),ic,FALSE);
9138 assignResultValue(IC_RESULT(ic));
9141 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9144 /*-----------------------------------------------------------------*/
9145 /* genpic14Code - generate code for pic14 based controllers */
9146 /*-----------------------------------------------------------------*/
9148 * At this point, ralloc.c has gone through the iCode and attempted
9149 * to optimize in a way suitable for a PIC. Now we've got to generate
9150 * PIC instructions that correspond to the iCode.
9152 * Once the instructions are generated, we'll pass through both the
9153 * peep hole optimizer and the pCode optimizer.
9154 *-----------------------------------------------------------------*/
9156 void genpic14Code (iCode *lic)
9161 lineHead = lineCurr = NULL;
9163 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9166 /* if debug information required */
9167 if (options.debug && currFunc) {
9169 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9171 if (IS_STATIC(currFunc->etype)) {
9172 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9173 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9175 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9176 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9183 for (ic = lic ; ic ; ic = ic->next ) {
9185 DEBUGpic14_emitcode(";ic","");
9186 if ( cln != ic->lineno ) {
9187 if ( options.debug ) {
9189 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9190 FileBaseName(ic->filename),ic->lineno,
9191 ic->level,ic->block);
9194 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9197 /* if the result is marked as
9198 spilt and rematerializable or code for
9199 this has already been generated then
9201 if (resultRemat(ic) || ic->generated )
9204 /* depending on the operation */
9223 /* IPOP happens only when trying to restore a
9224 spilt live range, if there is an ifx statement
9225 following this pop then the if statement might
9226 be using some of the registers being popped which
9227 would destory the contents of the register so
9228 we need to check for this condition and handle it */
9230 ic->next->op == IFX &&
9231 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9232 genIfx (ic->next,ic);
9250 genEndFunction (ic);
9270 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9287 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9291 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9298 /* note these two are xlated by algebraic equivalence
9299 during parsing SDCC.y */
9300 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9301 "got '>=' or '<=' shouldn't have come here");
9305 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9317 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9321 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9325 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9352 case GET_VALUE_AT_ADDRESS:
9357 if (POINTER_SET(ic))
9384 addSet(&_G.sendSet,ic);
9393 /* now we are ready to call the
9394 peep hole optimizer */
9395 if (!options.nopeep) {
9396 peepHole (&lineHead);
9398 /* now do the actual printing */
9399 printLine (lineHead,codeOutFile);
9402 DFPRINTF((stderr,"printing pBlock\n\n"));
9403 printpBlock(stdout,pb);