1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 static int labelOffset=0;
64 static int debug_verbose=1;
65 static int optimized_for_speed = 0;
67 /* max_key keeps track of the largest label number used in
68 a function. This is then used to adjust the label offset
69 for the next function.
72 static int GpsuedoStkPtr=0;
74 unsigned int pic14aopLiteral (value *val, int offset);
75 const char *AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic14[] = {"FSR","dph","b","a" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic14;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic14_ptrRegReq ;
119 extern int pic14_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
186 sprintf(lb,"%s\t",inst);
188 sprintf(lb,"%s",inst);
189 vsprintf(lb+(strlen(lb)),fmt,ap);
193 while (isspace(*lbp)) lbp++;
196 lineCurr = (lineCurr ?
197 connectLine(lineCurr,newLineNode(lb)) :
198 (lineHead = newLineNode(lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
202 addpCode2pBlock(pb,newpCodeCharP(lb));
208 static void emitpLabel(int key)
210 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
213 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
229 /*-----------------------------------------------------------------*/
230 /* pic14_emitcode - writes the code into a file : for now it is simple */
231 /*-----------------------------------------------------------------*/
232 void pic14_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
242 sprintf(lb,"%s\t",inst);
244 sprintf(lb,"%s",inst);
245 vsprintf(lb+(strlen(lb)),fmt,ap);
249 while (isspace(*lbp)) lbp++;
252 lineCurr = (lineCurr ?
253 connectLine(lineCurr,newLineNode(lb)) :
254 (lineHead = newLineNode(lb)));
255 lineCurr->isInline = _G.inLine;
256 lineCurr->isDebug = _G.debugLine;
259 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
267 /*-----------------------------------------------------------------*/
268 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
270 bool r0iu = FALSE , r1iu = FALSE;
271 bool r0ou = FALSE , r1ou = FALSE;
273 /* the logic: if r0 & r1 used in the instruction
274 then we are in trouble otherwise */
276 /* first check if r0 & r1 are used by this
277 instruction, in which case we are in trouble */
278 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
279 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
284 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
285 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
287 /* if no usage of r0 then return it */
288 if (!r0iu && !r0ou) {
289 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
290 (*aopp)->type = AOP_R0;
292 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
295 /* if no usage of r1 then return it */
296 if (!r1iu && !r1ou) {
297 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
298 (*aopp)->type = AOP_R1;
300 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
303 /* now we know they both have usage */
304 /* if r0 not used in this instruction */
306 /* push it if not already pushed */
308 pic14_emitcode ("push","%s",
309 pic14_regWithIdx(R0_IDX)->dname);
313 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
314 (*aopp)->type = AOP_R0;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
319 /* if r1 not used then */
322 /* push it if not already pushed */
324 pic14_emitcode ("push","%s",
325 pic14_regWithIdx(R1_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
330 (*aopp)->type = AOP_R1;
331 return pic14_regWithIdx(R1_IDX);
335 /* I said end of world but not quite end of world yet */
336 /* if this is a result then we can push it on the stack*/
338 (*aopp)->type = AOP_STK;
342 /* other wise this is true end of the world */
343 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
344 "getFreePtr should never reach here");
348 /*-----------------------------------------------------------------*/
349 /* newAsmop - creates a new asmOp */
350 /*-----------------------------------------------------------------*/
351 asmop *newAsmop (short type)
355 aop = Safe_calloc(1,sizeof(asmop));
360 static void genSetDPTR(int n)
364 pic14_emitcode(";", "Select standard DPTR");
365 pic14_emitcode("mov", "dps, #0x00");
369 pic14_emitcode(";", "Select alternate DPTR");
370 pic14_emitcode("mov", "dps, #0x01");
374 /*-----------------------------------------------------------------*/
375 /* resolveIfx - converts an iCode ifx into a form more useful for */
376 /* generating code */
377 /*-----------------------------------------------------------------*/
378 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
385 resIfx->condition = 1; /* assume that the ifx is true */
386 resIfx->generated = 0; /* indicate that the ifx has not been used */
389 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
390 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
391 __FUNCTION__,__LINE__,resIfx->lbl->key);
394 resIfx->lbl = IC_TRUE(ifx);
396 resIfx->lbl = IC_FALSE(ifx);
397 resIfx->condition = 0;
400 DEBUGpic14_emitcode("; ***","ifx true is non-null");
402 DEBUGpic14_emitcode("; ***","ifx false is non-null");
405 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
408 /*-----------------------------------------------------------------*/
409 /* pointerCode - returns the code for a pointer type */
410 /*-----------------------------------------------------------------*/
411 static int pointerCode (sym_link *etype)
414 return PTR_TYPE(SPEC_OCLS(etype));
418 /*-----------------------------------------------------------------*/
419 /* aopForSym - for a true symbol */
420 /*-----------------------------------------------------------------*/
421 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
424 memmap *space= SPEC_OCLS(sym->etype);
426 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
427 /* if already has one */
431 /* assign depending on the storage class */
432 /* if it is on the stack or indirectly addressable */
433 /* space we need to assign either r0 or r1 to it */
434 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
435 sym->aop = aop = newAsmop(0);
436 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
437 aop->size = getSize(sym->type);
439 /* now assign the address of the variable to
440 the pointer register */
441 if (aop->type != AOP_STK) {
445 pic14_emitcode("push","acc");
447 pic14_emitcode("mov","a,_bp");
448 pic14_emitcode("add","a,#0x%02x",
450 ((char)(sym->stack - _G.nRegsSaved )) :
451 ((char)sym->stack)) & 0xff);
452 pic14_emitcode("mov","%s,a",
453 aop->aopu.aop_ptr->name);
456 pic14_emitcode("pop","acc");
458 pic14_emitcode("mov","%s,#%s",
459 aop->aopu.aop_ptr->name,
461 aop->paged = space->paged;
463 aop->aopu.aop_stk = sym->stack;
467 if (sym->onStack && options.stack10bit)
469 /* It's on the 10 bit stack, which is located in
473 //DEBUGpic14_emitcode(";","%d",__LINE__);
476 pic14_emitcode("push","acc");
478 pic14_emitcode("mov","a,_bp");
479 pic14_emitcode("add","a,#0x%02x",
481 ((char)(sym->stack - _G.nRegsSaved )) :
482 ((char)sym->stack)) & 0xff);
485 pic14_emitcode ("mov","dpx1,#0x40");
486 pic14_emitcode ("mov","dph1,#0x00");
487 pic14_emitcode ("mov","dpl1, a");
491 pic14_emitcode("pop","acc");
493 sym->aop = aop = newAsmop(AOP_DPTR2);
494 aop->size = getSize(sym->type);
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 /* if in bit space */
500 if (IN_BITSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_CRY);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
507 /* if it is in direct space */
508 if (IN_DIRSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_DIR);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
516 /* special case for a function */
517 if (IS_FUNC(sym->type)) {
518 sym->aop = aop = newAsmop(AOP_IMMD);
519 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
520 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
521 strcpy(aop->aopu.aop_immd,sym->rname);
522 aop->size = FPTRSIZE;
527 /* only remaining is far space */
528 /* in which case DPTR gets the address */
529 sym->aop = aop = newAsmop(AOP_DPTR);
530 pic14_emitcode ("mov","dptr,#%s", sym->rname);
531 aop->size = getSize(sym->type);
533 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
534 /* if it is in code space */
535 if (IN_CODESPACE(space))
541 /*-----------------------------------------------------------------*/
542 /* aopForRemat - rematerialzes an object */
543 /*-----------------------------------------------------------------*/
544 static asmop *aopForRemat (symbol *sym)
546 iCode *ic = sym->rematiCode;
547 asmop *aop = newAsmop(AOP_IMMD);
549 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
552 val += (int) operandLitValue(IC_RIGHT(ic));
553 else if (ic->op == '-')
554 val -= (int) operandLitValue(IC_RIGHT(ic));
558 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
562 sprintf(buffer,"(%s %c 0x%04x)",
563 OP_SYMBOL(IC_LEFT(ic))->rname,
564 val >= 0 ? '+' : '-',
567 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
569 //DEBUGpic14_emitcode(";","%s",buffer);
570 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
571 strcpy(aop->aopu.aop_immd,buffer);
575 int aopIdx (asmop *aop, int offset)
580 if(aop->type != AOP_REG)
583 return aop->aopu.aop_reg[offset]->rIdx;
586 /*-----------------------------------------------------------------*/
587 /* regsInCommon - two operands have some registers in common */
588 /*-----------------------------------------------------------------*/
589 static bool regsInCommon (operand *op1, operand *op2)
594 /* if they have registers in common */
595 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
598 sym1 = OP_SYMBOL(op1);
599 sym2 = OP_SYMBOL(op2);
601 if (sym1->nRegs == 0 || sym2->nRegs == 0)
604 for (i = 0 ; i < sym1->nRegs ; i++) {
609 for (j = 0 ; j < sym2->nRegs ;j++ ) {
613 if (sym2->regs[j] == sym1->regs[i])
621 /*-----------------------------------------------------------------*/
622 /* operandsEqu - equivalent */
623 /*-----------------------------------------------------------------*/
624 static bool operandsEqu ( operand *op1, operand *op2)
628 /* if they not symbols */
629 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
632 sym1 = OP_SYMBOL(op1);
633 sym2 = OP_SYMBOL(op2);
635 /* if both are itemps & one is spilt
636 and the other is not then false */
637 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
638 sym1->isspilt != sym2->isspilt )
641 /* if they are the same */
645 if (strcmp(sym1->rname,sym2->rname) == 0)
649 /* if left is a tmp & right is not */
653 (sym1->usl.spillLoc == sym2))
660 (sym2->usl.spillLoc == sym1))
666 /*-----------------------------------------------------------------*/
667 /* pic14_sameRegs - two asmops have the same registers */
668 /*-----------------------------------------------------------------*/
669 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
676 if (aop1->type != AOP_REG ||
677 aop2->type != AOP_REG )
680 if (aop1->size != aop2->size )
683 for (i = 0 ; i < aop1->size ; i++ )
684 if (aop1->aopu.aop_reg[i] !=
685 aop2->aopu.aop_reg[i] )
691 /*-----------------------------------------------------------------*/
692 /* aopOp - allocates an asmop for an operand : */
693 /*-----------------------------------------------------------------*/
694 void aopOp (operand *op, iCode *ic, bool result)
703 // DEBUGpic14_emitcode(";","%d",__LINE__);
704 /* if this a literal */
705 if (IS_OP_LITERAL(op)) {
706 op->aop = aop = newAsmop(AOP_LIT);
707 aop->aopu.aop_lit = op->operand.valOperand;
708 aop->size = getSize(operandType(op));
712 /* if already has a asmop then continue */
716 /* if the underlying symbol has a aop */
717 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
718 DEBUGpic14_emitcode(";","%d",__LINE__);
719 op->aop = OP_SYMBOL(op)->aop;
723 /* if this is a true symbol */
724 if (IS_TRUE_SYMOP(op)) {
725 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
726 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
730 /* this is a temporary : this has
736 e) can be a return use only */
741 /* if the type is a conditional */
742 if (sym->regType == REG_CND) {
743 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
748 /* if it is spilt then two situations
750 b) has a spill location */
751 if (sym->isspilt || sym->nRegs == 0) {
753 DEBUGpic14_emitcode(";","%d",__LINE__);
754 /* rematerialize it NOW */
756 sym->aop = op->aop = aop =
758 aop->size = getSize(sym->type);
764 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
765 aop->size = getSize(sym->type);
766 for ( i = 0 ; i < 2 ; i++ )
767 aop->aopu.aop_str[i] = accUse[i];
768 DEBUGpic14_emitcode(";","%d",__LINE__);
774 aop = op->aop = sym->aop = newAsmop(AOP_STR);
775 aop->size = getSize(sym->type);
776 for ( i = 0 ; i < fReturnSizePic ; i++ )
777 aop->aopu.aop_str[i] = fReturn[i];
778 DEBUGpic14_emitcode(";","%d",__LINE__);
782 /* else spill location */
783 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
784 /* force a new aop if sizes differ */
785 sym->usl.spillLoc->aop = NULL;
787 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
788 sym->aop = op->aop = aop =
789 aopForSym(ic,sym->usl.spillLoc,result);
790 aop->size = getSize(sym->type);
794 /* must be in a register */
795 sym->aop = op->aop = aop = newAsmop(AOP_REG);
796 aop->size = sym->nRegs;
797 for ( i = 0 ; i < sym->nRegs ;i++)
798 aop->aopu.aop_reg[i] = sym->regs[i];
801 /*-----------------------------------------------------------------*/
802 /* freeAsmop - free up the asmop given to an operand */
803 /*----------------------------------------------------------------*/
804 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
821 /* depending on the asmop type only three cases need work AOP_RO
822 , AOP_R1 && AOP_STK */
828 pic14_emitcode ("pop","ar0");
832 bitVectUnSetBit(ic->rUsed,R0_IDX);
838 pic14_emitcode ("pop","ar1");
842 bitVectUnSetBit(ic->rUsed,R1_IDX);
848 int stk = aop->aopu.aop_stk + aop->size;
849 bitVectUnSetBit(ic->rUsed,R0_IDX);
850 bitVectUnSetBit(ic->rUsed,R1_IDX);
852 getFreePtr(ic,&aop,FALSE);
854 if (options.stack10bit)
856 /* I'm not sure what to do here yet... */
859 "*** Warning: probably generating bad code for "
860 "10 bit stack mode.\n");
864 pic14_emitcode ("mov","a,_bp");
865 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
866 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
868 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
872 pic14_emitcode("pop","acc");
873 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
875 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
878 freeAsmop(op,NULL,ic,TRUE);
880 pic14_emitcode("pop","ar0");
885 pic14_emitcode("pop","ar1");
893 /* all other cases just dealloc */
897 OP_SYMBOL(op)->aop = NULL;
898 /* if the symbol has a spill */
900 SPIL_LOC(op)->aop = NULL;
905 /*-----------------------------------------------------------------*/
906 /* aopGet - for fetching value of the aop */
907 /*-----------------------------------------------------------------*/
908 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
913 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
914 /* offset is greater than
916 if (offset > (aop->size - 1) &&
917 aop->type != AOP_LIT)
920 /* depending on type */
925 DEBUGpic14_emitcode(";","%d",__LINE__);
926 /* if we need to increment it */
927 while (offset > aop->coff) {
928 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
932 while (offset < aop->coff) {
933 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
939 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
940 return (dname ? "acc" : "a");
942 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
943 rs = Safe_calloc(1,strlen(s)+1);
949 DEBUGpic14_emitcode(";","%d",__LINE__);
950 if (aop->type == AOP_DPTR2)
955 while (offset > aop->coff) {
956 pic14_emitcode ("inc","dptr");
960 while (offset < aop->coff) {
961 pic14_emitcode("lcall","__decdptr");
967 pic14_emitcode("clr","a");
968 pic14_emitcode("movc","a,@a+dptr");
971 pic14_emitcode("movx","a,@dptr");
974 if (aop->type == AOP_DPTR2)
979 return (dname ? "acc" : "a");
983 DEBUGpic14_emitcode(";","%d",__LINE__);
985 sprintf (s,"%s",aop->aopu.aop_immd);
988 sprintf(s,"(%s >> %d)",
994 rs = Safe_calloc(1,strlen(s)+1);
1000 sprintf(s,"(%s + %d)",
1004 sprintf(s,"%s",aop->aopu.aop_dir);
1005 rs = Safe_calloc(1,strlen(s)+1);
1011 return aop->aopu.aop_reg[offset]->dname;
1013 return aop->aopu.aop_reg[offset]->name;
1016 //pic14_emitcode(";","%d",__LINE__);
1017 return aop->aopu.aop_dir;
1020 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1021 return "AOP_accumulator_bug";
1024 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1025 rs = Safe_calloc(1,strlen(s)+1);
1030 DEBUGpic14_emitcode(";","%d",__LINE__);
1031 aop->coff = offset ;
1032 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1036 return aop->aopu.aop_str[offset];
1040 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1041 "aopget got unsupported aop->type");
1045 /*-----------------------------------------------------------------*/
1046 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1047 /*-----------------------------------------------------------------*/
1048 pCodeOp *popGetLabel(unsigned int key)
1051 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1056 return newpCodeOpLabel(key+100+labelOffset);
1059 /*-----------------------------------------------------------------*/
1060 /* popCopyReg - copy a pcode operator */
1061 /*-----------------------------------------------------------------*/
1062 pCodeOp *popCopyReg(pCodeOpReg *pc)
1066 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1067 pcor->pcop.type = pc->pcop.type;
1068 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1069 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1071 pcor->rIdx = pc->rIdx;
1073 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1078 /*-----------------------------------------------------------------*/
1079 /* popCopy - copy a pcode operator */
1080 /*-----------------------------------------------------------------*/
1081 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1085 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1086 pcop->type = PO_BIT;
1087 if(!(pcop->name = Safe_strdup(pc->name)))
1088 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1089 ((pCodeOpBit *)pcop)->bit = bitval;
1091 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1096 /*-----------------------------------------------------------------*/
1097 /* popGet - asm operator to pcode operator conversion */
1098 /*-----------------------------------------------------------------*/
1099 pCodeOp *popGetLit(unsigned int lit)
1102 return newpCodeOpLit(lit);
1106 /*-----------------------------------------------------------------*/
1107 /* popGet - asm operator to pcode operator conversion */
1108 /*-----------------------------------------------------------------*/
1109 pCodeOp *popGetWithString(char *str)
1115 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1119 pcop = newpCodeOp(str,PO_STR);
1124 pCodeOp *popRegFromString(char *str)
1127 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1128 pcop->type = PO_GPR_REGISTER;
1130 PCOR(pcop)->rIdx = -1;
1131 PCOR(pcop)->r = NULL;
1133 DEBUGpic14_emitcode(";","%d",__LINE__);
1134 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1139 pCodeOp *popRegFromIdx(int rIdx)
1143 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1144 __FUNCTION__,__LINE__,rIdx);
1146 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1148 PCOR(pcop)->rIdx = rIdx;
1149 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1150 PCOR(pcop)->r->isFree = 0;
1151 PCOR(pcop)->r->wasUsed = 1;
1153 pcop->type = PCOR(pcop)->r->pc_type;
1158 /*-----------------------------------------------------------------*/
1159 /* popGet - asm operator to pcode operator conversion */
1160 /*-----------------------------------------------------------------*/
1161 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1168 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1169 /* offset is greater than
1172 if (offset > (aop->size - 1) &&
1173 aop->type != AOP_LIT)
1174 return NULL; //zero;
1176 /* depending on type */
1177 switch (aop->type) {
1184 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1185 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1186 //pcop->type = PO_SFR_REGISTER;
1188 //PCOR(pcop)->rIdx = -1;
1189 //PCOR(pcop)->r = NULL;
1190 // Really nasty hack to check for temporary registers
1192 //pcop->name = Safe_strdup("BAD_REGISTER");
1197 DEBUGpic14_emitcode(";","%d",__LINE__);
1198 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1199 pcop->type = PO_IMMEDIATE;
1201 // sprintf (s,"%s",aop->aopu.aop_immd);
1204 sprintf(s,"(%s >> %d)",
1209 aop->aopu.aop_immd);
1210 pcop->name = Safe_calloc(1,strlen(s)+1);
1211 strcpy(pcop->name,s);
1215 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1216 pcop->type = PO_DIR;
1218 sprintf(s,"(%s + %d)",
1222 sprintf(s,"%s",aop->aopu.aop_dir);
1223 pcop->name = Safe_calloc(1,strlen(s)+1);
1224 strcpy(pcop->name,s);
1229 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1231 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1232 PCOR(pcop)->rIdx = rIdx;
1233 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1234 pcop->type = PCOR(pcop)->r->pc_type;
1235 rs = aop->aopu.aop_reg[offset]->name;
1236 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1241 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1245 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1248 DEBUGpic14_emitcode(";","%d",__LINE__);
1250 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1251 pcop->type = PO_STR;
1253 //aop->coff = offset ;
1254 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1255 // sprintf(s,"%s","acc");
1257 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1258 pcop->name = Safe_calloc(1,strlen(s)+1);
1259 strcpy(pcop->name,s);
1264 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1265 "popGet got unsupported aop->type");
1268 /*-----------------------------------------------------------------*/
1269 /* aopPut - puts a string for a aop */
1270 /*-----------------------------------------------------------------*/
1271 void aopPut (asmop *aop, char *s, int offset)
1276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1278 if (aop->size && offset > ( aop->size - 1)) {
1279 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280 "aopPut got offset > aop->size");
1284 /* will assign value to value */
1285 /* depending on where it is ofcourse */
1286 switch (aop->type) {
1289 sprintf(d,"(%s + %d)",
1290 aop->aopu.aop_dir,offset);
1292 sprintf(d,"%s",aop->aopu.aop_dir);
1295 DEBUGpic14_emitcode(";","%d",__LINE__);
1297 pic14_emitcode("movf","%s,w",s);
1298 pic14_emitcode("movwf","%s",d);
1301 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1302 emitpcode(POC_MOVWF,popGet(aop,offset));
1309 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1310 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1313 strcmp(s,"r0") == 0 ||
1314 strcmp(s,"r1") == 0 ||
1315 strcmp(s,"r2") == 0 ||
1316 strcmp(s,"r3") == 0 ||
1317 strcmp(s,"r4") == 0 ||
1318 strcmp(s,"r5") == 0 ||
1319 strcmp(s,"r6") == 0 ||
1320 strcmp(s,"r7") == 0 )
1321 pic14_emitcode("mov","%s,%s ; %d",
1322 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1327 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1329 pic14_emitcode("movwf","%s",
1330 aop->aopu.aop_reg[offset]->name);
1333 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1334 pcop->type = PO_GPR_REGISTER;
1336 PCOR(pcop)->rIdx = -1;
1337 PCOR(pcop)->r = NULL;
1339 DEBUGpic14_emitcode(";","%d",__LINE__);
1340 pcop->name = Safe_strdup(s);
1341 emitpcode(POC_MOVFW,pcop);
1343 emitpcode(POC_MOVWF,popGet(aop,offset));
1351 if (aop->type == AOP_DPTR2)
1357 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1358 "aopPut writting to code space");
1362 while (offset > aop->coff) {
1364 pic14_emitcode ("inc","dptr");
1367 while (offset < aop->coff) {
1369 pic14_emitcode("lcall","__decdptr");
1374 /* if not in accumulater */
1377 pic14_emitcode ("movx","@dptr,a");
1379 if (aop->type == AOP_DPTR2)
1387 while (offset > aop->coff) {
1389 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1391 while (offset < aop->coff) {
1393 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1399 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1404 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1406 if (strcmp(s,"r0") == 0 ||
1407 strcmp(s,"r1") == 0 ||
1408 strcmp(s,"r2") == 0 ||
1409 strcmp(s,"r3") == 0 ||
1410 strcmp(s,"r4") == 0 ||
1411 strcmp(s,"r5") == 0 ||
1412 strcmp(s,"r6") == 0 ||
1413 strcmp(s,"r7") == 0 ) {
1415 sprintf(buffer,"a%s",s);
1416 pic14_emitcode("mov","@%s,%s",
1417 aop->aopu.aop_ptr->name,buffer);
1419 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1424 if (strcmp(s,"a") == 0)
1425 pic14_emitcode("push","acc");
1427 pic14_emitcode("push","%s",s);
1432 /* if bit variable */
1433 if (!aop->aopu.aop_dir) {
1434 pic14_emitcode("clr","a");
1435 pic14_emitcode("rlc","a");
1438 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1441 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1444 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1446 lbl = newiTempLabel(NULL);
1448 if (strcmp(s,"a")) {
1451 pic14_emitcode("clr","c");
1452 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1453 pic14_emitcode("cpl","c");
1454 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1455 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1462 if (strcmp(aop->aopu.aop_str[offset],s))
1463 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1468 if (!offset && (strcmp(s,"acc") == 0))
1471 if (strcmp(aop->aopu.aop_str[offset],s))
1472 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1476 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1477 "aopPut got unsupported aop->type");
1483 /*-----------------------------------------------------------------*/
1484 /* reAdjustPreg - points a register back to where it should */
1485 /*-----------------------------------------------------------------*/
1486 static void reAdjustPreg (asmop *aop)
1490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1492 if ((size = aop->size) <= 1)
1495 switch (aop->type) {
1499 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1503 if (aop->type == AOP_DPTR2)
1509 pic14_emitcode("lcall","__decdptr");
1512 if (aop->type == AOP_DPTR2)
1522 /*-----------------------------------------------------------------*/
1523 /* genNotFloat - generates not for float operations */
1524 /*-----------------------------------------------------------------*/
1525 static void genNotFloat (operand *op, operand *res)
1531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1532 /* we will put 127 in the first byte of
1534 aopPut(AOP(res),"#127",0);
1535 size = AOP_SIZE(op) - 1;
1538 l = aopGet(op->aop,offset++,FALSE,FALSE);
1542 pic14_emitcode("orl","a,%s",
1544 offset++,FALSE,FALSE));
1546 tlbl = newiTempLabel(NULL);
1548 tlbl = newiTempLabel(NULL);
1549 aopPut(res->aop,one,1);
1550 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1551 aopPut(res->aop,zero,1);
1552 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1554 size = res->aop->size - 2;
1556 /* put zeros in the rest */
1558 aopPut(res->aop,zero,offset++);
1562 /*-----------------------------------------------------------------*/
1563 /* opIsGptr: returns non-zero if the passed operand is */
1564 /* a generic pointer type. */
1565 /*-----------------------------------------------------------------*/
1566 static int opIsGptr(operand *op)
1568 sym_link *type = operandType(op);
1570 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1571 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1579 /*-----------------------------------------------------------------*/
1580 /* pic14_getDataSize - get the operand data size */
1581 /*-----------------------------------------------------------------*/
1582 int pic14_getDataSize(operand *op)
1584 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1587 return AOP_SIZE(op);
1589 // tsd- in the pic port, the genptr size is 1, so this code here
1590 // fails. ( in the 8051 port, the size was 4).
1593 size = AOP_SIZE(op);
1594 if (size == GPTRSIZE)
1596 sym_link *type = operandType(op);
1597 if (IS_GENPTR(type))
1599 /* generic pointer; arithmetic operations
1600 * should ignore the high byte (pointer type).
1603 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1610 /*-----------------------------------------------------------------*/
1611 /* pic14_outAcc - output Acc */
1612 /*-----------------------------------------------------------------*/
1613 void pic14_outAcc(operand *result)
1616 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1617 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1620 size = pic14_getDataSize(result);
1622 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1625 /* unsigned or positive */
1627 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1632 /*-----------------------------------------------------------------*/
1633 /* pic14_outBitC - output a bit C */
1634 /*-----------------------------------------------------------------*/
1635 void pic14_outBitC(operand *result)
1638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1639 /* if the result is bit */
1640 if (AOP_TYPE(result) == AOP_CRY)
1641 aopPut(AOP(result),"c",0);
1643 pic14_emitcode("clr","a ; %d", __LINE__);
1644 pic14_emitcode("rlc","a");
1645 pic14_outAcc(result);
1649 /*-----------------------------------------------------------------*/
1650 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1651 /*-----------------------------------------------------------------*/
1652 void pic14_toBoolean(operand *oper)
1654 int size = AOP_SIZE(oper) - 1;
1657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1659 if ( AOP_TYPE(oper) != AOP_ACC) {
1660 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1663 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1668 /*-----------------------------------------------------------------*/
1669 /* genNot - generate code for ! operation */
1670 /*-----------------------------------------------------------------*/
1671 static void genNot (iCode *ic)
1674 sym_link *optype = operandType(IC_LEFT(ic));
1677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1678 /* assign asmOps to operand & result */
1679 aopOp (IC_LEFT(ic),ic,FALSE);
1680 aopOp (IC_RESULT(ic),ic,TRUE);
1682 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1683 /* if in bit space then a special case */
1684 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1685 pic14_emitcode("movlw","1<<%s");
1686 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1687 //pic14_emitcode("cpl","c");
1688 //pic14_outBitC(IC_RESULT(ic));
1692 /* if type float then do float */
1693 if (IS_FLOAT(optype)) {
1694 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1698 size = AOP_SIZE(IC_RESULT(ic));
1700 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1701 emitpcode(POC_ANDLW,popGetLit(1));
1702 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1705 pic14_toBoolean(IC_LEFT(ic));
1707 tlbl = newiTempLabel(NULL);
1708 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1710 pic14_outBitC(IC_RESULT(ic));
1713 /* release the aops */
1714 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1715 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1719 /*-----------------------------------------------------------------*/
1720 /* genCpl - generate code for complement */
1721 /*-----------------------------------------------------------------*/
1722 static void genCpl (iCode *ic)
1728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 /* assign asmOps to operand & result */
1730 aopOp (IC_LEFT(ic),ic,FALSE);
1731 aopOp (IC_RESULT(ic),ic,TRUE);
1733 /* if both are in bit space then
1735 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1736 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1738 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1739 pic14_emitcode("cpl","c");
1740 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1744 size = AOP_SIZE(IC_RESULT(ic));
1746 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1748 pic14_emitcode("cpl","a");
1749 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1754 /* release the aops */
1755 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1756 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1759 /*-----------------------------------------------------------------*/
1760 /* genUminusFloat - unary minus for floating points */
1761 /*-----------------------------------------------------------------*/
1762 static void genUminusFloat(operand *op,operand *result)
1764 int size ,offset =0 ;
1767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1768 /* for this we just need to flip the
1769 first it then copy the rest in place */
1770 size = AOP_SIZE(op) - 1;
1771 l = aopGet(AOP(op),3,FALSE,FALSE);
1775 pic14_emitcode("cpl","acc.7");
1776 aopPut(AOP(result),"a",3);
1780 aopGet(AOP(op),offset,FALSE,FALSE),
1786 /*-----------------------------------------------------------------*/
1787 /* genUminus - unary minus code generation */
1788 /*-----------------------------------------------------------------*/
1789 static void genUminus (iCode *ic)
1792 sym_link *optype, *rtype;
1795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 aopOp(IC_LEFT(ic),ic,FALSE);
1798 aopOp(IC_RESULT(ic),ic,TRUE);
1800 /* if both in bit space then special
1802 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1803 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1805 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1806 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1807 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1812 optype = operandType(IC_LEFT(ic));
1813 rtype = operandType(IC_RESULT(ic));
1815 /* if float then do float stuff */
1816 if (IS_FLOAT(optype)) {
1817 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1821 /* otherwise subtract from zero by taking the 2's complement */
1822 size = AOP_SIZE(IC_LEFT(ic));
1824 for(i=0; i<size; i++) {
1825 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1826 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1828 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1829 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1833 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1834 for(i=1; i<size; i++) {
1836 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1840 /* release the aops */
1841 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1842 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1845 /*-----------------------------------------------------------------*/
1846 /* saveRegisters - will look for a call and save the registers */
1847 /*-----------------------------------------------------------------*/
1848 static void saveRegisters(iCode *lic)
1855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1857 for (ic = lic ; ic ; ic = ic->next)
1858 if (ic->op == CALL || ic->op == PCALL)
1862 fprintf(stderr,"found parameter push with no function call\n");
1866 /* if the registers have been saved already then
1868 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1871 /* find the registers in use at this time
1872 and push them away to safety */
1873 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1877 if (options.useXstack) {
1878 if (bitVectBitValue(rsave,R0_IDX))
1879 pic14_emitcode("mov","b,r0");
1880 pic14_emitcode("mov","r0,%s",spname);
1881 for (i = 0 ; i < pic14_nRegs ; i++) {
1882 if (bitVectBitValue(rsave,i)) {
1884 pic14_emitcode("mov","a,b");
1886 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1887 pic14_emitcode("movx","@r0,a");
1888 pic14_emitcode("inc","r0");
1891 pic14_emitcode("mov","%s,r0",spname);
1892 if (bitVectBitValue(rsave,R0_IDX))
1893 pic14_emitcode("mov","r0,b");
1895 for (i = 0 ; i < pic14_nRegs ; i++) {
1896 if (bitVectBitValue(rsave,i))
1897 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1900 dtype = operandType(IC_LEFT(ic));
1901 if (currFunc && dtype &&
1902 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1903 IFFUNC_ISISR(currFunc->type) &&
1906 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1909 /*-----------------------------------------------------------------*/
1910 /* unsaveRegisters - pop the pushed registers */
1911 /*-----------------------------------------------------------------*/
1912 static void unsaveRegisters (iCode *ic)
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 /* find the registers in use at this time
1919 and push them away to safety */
1920 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1923 if (options.useXstack) {
1924 pic14_emitcode("mov","r0,%s",spname);
1925 for (i = pic14_nRegs ; i >= 0 ; i--) {
1926 if (bitVectBitValue(rsave,i)) {
1927 pic14_emitcode("dec","r0");
1928 pic14_emitcode("movx","a,@r0");
1930 pic14_emitcode("mov","b,a");
1932 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1936 pic14_emitcode("mov","%s,r0",spname);
1937 if (bitVectBitValue(rsave,R0_IDX))
1938 pic14_emitcode("mov","r0,b");
1940 for (i = pic14_nRegs ; i >= 0 ; i--) {
1941 if (bitVectBitValue(rsave,i))
1942 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1948 /*-----------------------------------------------------------------*/
1950 /*-----------------------------------------------------------------*/
1951 static void pushSide(operand * oper, int size)
1955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1957 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1958 if (AOP_TYPE(oper) != AOP_REG &&
1959 AOP_TYPE(oper) != AOP_DIR &&
1961 pic14_emitcode("mov","a,%s",l);
1962 pic14_emitcode("push","acc");
1964 pic14_emitcode("push","%s",l);
1969 /*-----------------------------------------------------------------*/
1970 /* assignResultValue - */
1971 /*-----------------------------------------------------------------*/
1972 static void assignResultValue(operand * oper)
1974 int size = AOP_SIZE(oper);
1976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1978 if(!GpsuedoStkPtr) {
1979 /* The last byte in the assignment is in W */
1981 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1986 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1988 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1993 /*-----------------------------------------------------------------*/
1994 /* genIpush - genrate code for pushing this gets a little complex */
1995 /*-----------------------------------------------------------------*/
1996 static void genIpush (iCode *ic)
1999 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2001 int size, offset = 0 ;
2005 /* if this is not a parm push : ie. it is spill push
2006 and spill push is always done on the local stack */
2007 if (!ic->parmPush) {
2009 /* and the item is spilt then do nothing */
2010 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2013 aopOp(IC_LEFT(ic),ic,FALSE);
2014 size = AOP_SIZE(IC_LEFT(ic));
2015 /* push it on the stack */
2017 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2022 pic14_emitcode("push","%s",l);
2027 /* this is a paramter push: in this case we call
2028 the routine to find the call and save those
2029 registers that need to be saved */
2032 /* then do the push */
2033 aopOp(IC_LEFT(ic),ic,FALSE);
2036 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2037 size = AOP_SIZE(IC_LEFT(ic));
2040 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2041 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2042 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2044 pic14_emitcode("mov","a,%s",l);
2045 pic14_emitcode("push","acc");
2047 pic14_emitcode("push","%s",l);
2050 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2054 /*-----------------------------------------------------------------*/
2055 /* genIpop - recover the registers: can happen only for spilling */
2056 /*-----------------------------------------------------------------*/
2057 static void genIpop (iCode *ic)
2059 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2064 /* if the temp was not pushed then */
2065 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2068 aopOp(IC_LEFT(ic),ic,FALSE);
2069 size = AOP_SIZE(IC_LEFT(ic));
2072 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2075 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2079 /*-----------------------------------------------------------------*/
2080 /* unsaverbank - restores the resgister bank from stack */
2081 /*-----------------------------------------------------------------*/
2082 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2084 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2092 if (options.useXstack) {
2094 r = getFreePtr(ic,&aop,FALSE);
2097 pic14_emitcode("mov","%s,_spx",r->name);
2098 pic14_emitcode("movx","a,@%s",r->name);
2099 pic14_emitcode("mov","psw,a");
2100 pic14_emitcode("dec","%s",r->name);
2103 pic14_emitcode ("pop","psw");
2106 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2107 if (options.useXstack) {
2108 pic14_emitcode("movx","a,@%s",r->name);
2109 //pic14_emitcode("mov","(%s+%d),a",
2110 // regspic14[i].base,8*bank+regspic14[i].offset);
2111 pic14_emitcode("dec","%s",r->name);
2114 pic14_emitcode("pop",""); //"(%s+%d)",
2115 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2118 if (options.useXstack) {
2120 pic14_emitcode("mov","_spx,%s",r->name);
2121 freeAsmop(NULL,aop,ic,TRUE);
2127 /*-----------------------------------------------------------------*/
2128 /* saverbank - saves an entire register bank on the stack */
2129 /*-----------------------------------------------------------------*/
2130 static void saverbank (int bank, iCode *ic, bool pushPsw)
2132 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2139 if (options.useXstack) {
2142 r = getFreePtr(ic,&aop,FALSE);
2143 pic14_emitcode("mov","%s,_spx",r->name);
2147 for (i = 0 ; i < pic14_nRegs ;i++) {
2148 if (options.useXstack) {
2149 pic14_emitcode("inc","%s",r->name);
2150 //pic14_emitcode("mov","a,(%s+%d)",
2151 // regspic14[i].base,8*bank+regspic14[i].offset);
2152 pic14_emitcode("movx","@%s,a",r->name);
2154 pic14_emitcode("push","");// "(%s+%d)",
2155 //regspic14[i].base,8*bank+regspic14[i].offset);
2159 if (options.useXstack) {
2160 pic14_emitcode("mov","a,psw");
2161 pic14_emitcode("movx","@%s,a",r->name);
2162 pic14_emitcode("inc","%s",r->name);
2163 pic14_emitcode("mov","_spx,%s",r->name);
2164 freeAsmop (NULL,aop,ic,TRUE);
2167 pic14_emitcode("push","psw");
2169 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2175 /*-----------------------------------------------------------------*/
2176 /* genCall - generates a call statement */
2177 /*-----------------------------------------------------------------*/
2178 static void genCall (iCode *ic)
2182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2184 /* if caller saves & we have not saved then */
2188 /* if we are calling a function that is not using
2189 the same register bank then we need to save the
2190 destination registers on the stack */
2191 dtype = operandType(IC_LEFT(ic));
2192 if (currFunc && dtype &&
2193 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2194 IFFUNC_ISISR(currFunc->type) &&
2197 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2199 /* if send set is not empty the assign */
2202 /* For the Pic port, there is no data stack.
2203 * So parameters passed to functions are stored
2204 * in registers. (The pCode optimizer will get
2205 * rid of most of these :).
2207 int psuedoStkPtr=-1;
2208 int firstTimeThruLoop = 1;
2210 _G.sendSet = reverseSet(_G.sendSet);
2212 /* First figure how many parameters are getting passed */
2213 for (sic = setFirstItem(_G.sendSet) ; sic ;
2214 sic = setNextItem(_G.sendSet)) {
2216 aopOp(IC_LEFT(sic),sic,FALSE);
2217 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2218 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2221 for (sic = setFirstItem(_G.sendSet) ; sic ;
2222 sic = setNextItem(_G.sendSet)) {
2223 int size, offset = 0;
2225 aopOp(IC_LEFT(sic),sic,FALSE);
2226 size = AOP_SIZE(IC_LEFT(sic));
2230 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2231 AopType(AOP_TYPE(IC_LEFT(sic))));
2233 if(!firstTimeThruLoop) {
2234 /* If this is not the first time we've been through the loop
2235 * then we need to save the parameter in a temporary
2236 * register. The last byte of the last parameter is
2238 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2241 firstTimeThruLoop=0;
2243 //if (strcmp(l,fReturn[offset])) {
2245 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2246 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2247 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2249 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2254 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2259 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2260 OP_SYMBOL(IC_LEFT(ic))->rname :
2261 OP_SYMBOL(IC_LEFT(ic))->name));
2264 /* if we need assign a result value */
2265 if ((IS_ITEMP(IC_RESULT(ic)) &&
2266 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2267 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2268 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2271 aopOp(IC_RESULT(ic),ic,FALSE);
2274 assignResultValue(IC_RESULT(ic));
2276 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2277 AopType(AOP_TYPE(IC_RESULT(ic))));
2279 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2282 /* adjust the stack for parameters if
2284 if (ic->parmBytes) {
2286 if (ic->parmBytes > 3) {
2287 pic14_emitcode("mov","a,%s",spname);
2288 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2289 pic14_emitcode("mov","%s,a",spname);
2291 for ( i = 0 ; i < ic->parmBytes ;i++)
2292 pic14_emitcode("dec","%s",spname);
2296 /* if register bank was saved then pop them */
2298 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2300 /* if we hade saved some registers then unsave them */
2301 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2302 unsaveRegisters (ic);
2307 /*-----------------------------------------------------------------*/
2308 /* genPcall - generates a call by pointer statement */
2309 /*-----------------------------------------------------------------*/
2310 static void genPcall (iCode *ic)
2313 symbol *rlbl = newiTempLabel(NULL);
2316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 /* if caller saves & we have not saved then */
2321 /* if we are calling a function that is not using
2322 the same register bank then we need to save the
2323 destination registers on the stack */
2324 dtype = operandType(IC_LEFT(ic));
2325 if (currFunc && dtype &&
2326 IFFUNC_ISISR(currFunc->type) &&
2327 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2328 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2331 /* push the return address on to the stack */
2332 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2333 pic14_emitcode("push","acc");
2334 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2335 pic14_emitcode("push","acc");
2337 if (options.model == MODEL_FLAT24)
2339 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2340 pic14_emitcode("push","acc");
2343 /* now push the calling address */
2344 aopOp(IC_LEFT(ic),ic,FALSE);
2346 pushSide(IC_LEFT(ic), FPTRSIZE);
2348 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2350 /* if send set is not empty the assign */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2356 int size, offset = 0;
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 size = AOP_SIZE(IC_LEFT(sic));
2360 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2362 if (strcmp(l,fReturn[offset]))
2363 pic14_emitcode("mov","%s,%s",
2368 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2373 pic14_emitcode("ret","");
2374 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2377 /* if we need assign a result value */
2378 if ((IS_ITEMP(IC_RESULT(ic)) &&
2379 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2380 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2381 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2384 aopOp(IC_RESULT(ic),ic,FALSE);
2387 assignResultValue(IC_RESULT(ic));
2389 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2392 /* adjust the stack for parameters if
2394 if (ic->parmBytes) {
2396 if (ic->parmBytes > 3) {
2397 pic14_emitcode("mov","a,%s",spname);
2398 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2399 pic14_emitcode("mov","%s,a",spname);
2401 for ( i = 0 ; i < ic->parmBytes ;i++)
2402 pic14_emitcode("dec","%s",spname);
2406 /* if register bank was saved then unsave them */
2407 if (currFunc && dtype &&
2408 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2409 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2411 /* if we hade saved some registers then
2414 unsaveRegisters (ic);
2418 /*-----------------------------------------------------------------*/
2419 /* resultRemat - result is rematerializable */
2420 /*-----------------------------------------------------------------*/
2421 static int resultRemat (iCode *ic)
2423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2424 if (SKIP_IC(ic) || ic->op == IFX)
2427 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2428 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2429 if (sym->remat && !POINTER_SET(ic))
2436 #if defined(__BORLANDC__) || defined(_MSC_VER)
2437 #define STRCASECMP stricmp
2439 #define STRCASECMP strcasecmp
2442 /*-----------------------------------------------------------------*/
2443 /* inExcludeList - return 1 if the string is in exclude Reg list */
2444 /*-----------------------------------------------------------------*/
2445 static bool inExcludeList(char *s)
2447 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2452 if (options.excludeRegs[i] &&
2453 STRCASECMP(options.excludeRegs[i],"none") == 0)
2456 for ( i = 0 ; options.excludeRegs[i]; i++) {
2457 if (options.excludeRegs[i] &&
2458 STRCASECMP(s,options.excludeRegs[i]) == 0)
2465 /*-----------------------------------------------------------------*/
2466 /* genFunction - generated code for function entry */
2467 /*-----------------------------------------------------------------*/
2468 static void genFunction (iCode *ic)
2473 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2475 labelOffset += (max_key+4);
2479 /* create the function header */
2480 pic14_emitcode(";","-----------------------------------------");
2481 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2482 pic14_emitcode(";","-----------------------------------------");
2484 pic14_emitcode("","%s:",sym->rname);
2485 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2487 ftype = operandType(IC_LEFT(ic));
2489 /* if critical function then turn interrupts off */
2490 if (IFFUNC_ISCRITICAL(ftype))
2491 pic14_emitcode("clr","ea");
2493 /* here we need to generate the equates for the
2494 register bank if required */
2496 if (FUNC_REGBANK(ftype) != rbank) {
2499 rbank = FUNC_REGBANK(ftype);
2500 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2501 if (strcmp(regspic14[i].base,"0") == 0)
2502 pic14_emitcode("","%s = 0x%02x",
2504 8*rbank+regspic14[i].offset);
2506 pic14_emitcode ("","%s = %s + 0x%02x",
2509 8*rbank+regspic14[i].offset);
2514 /* if this is an interrupt service routine then
2515 save acc, b, dpl, dph */
2516 if (IFFUNC_ISISR(sym->type)) {
2518 if (!inExcludeList("acc"))
2519 pic14_emitcode ("push","acc");
2520 if (!inExcludeList("b"))
2521 pic14_emitcode ("push","b");
2522 if (!inExcludeList("dpl"))
2523 pic14_emitcode ("push","dpl");
2524 if (!inExcludeList("dph"))
2525 pic14_emitcode ("push","dph");
2526 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2528 pic14_emitcode ("push", "dpx");
2529 /* Make sure we're using standard DPTR */
2530 pic14_emitcode ("push", "dps");
2531 pic14_emitcode ("mov", "dps, #0x00");
2532 if (options.stack10bit)
2534 /* This ISR could conceivably use DPTR2. Better save it. */
2535 pic14_emitcode ("push", "dpl1");
2536 pic14_emitcode ("push", "dph1");
2537 pic14_emitcode ("push", "dpx1");
2540 /* if this isr has no bank i.e. is going to
2541 run with bank 0 , then we need to save more
2543 if (!FUNC_REGBANK(sym->type)) {
2545 /* if this function does not call any other
2546 function then we can be economical and
2547 save only those registers that are used */
2548 if (! IFFUNC_HASFCALL(sym->type)) {
2551 /* if any registers used */
2552 if (sym->regsUsed) {
2553 /* save the registers used */
2554 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2555 if (bitVectBitValue(sym->regsUsed,i) ||
2556 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2557 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2562 /* this function has a function call cannot
2563 determines register usage so we will have the
2565 saverbank(0,ic,FALSE);
2569 /* if callee-save to be used for this function
2570 then save the registers being used in this function */
2571 if (IFFUNC_CALLEESAVES(sym->type)) {
2574 /* if any registers used */
2575 if (sym->regsUsed) {
2576 /* save the registers used */
2577 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2578 if (bitVectBitValue(sym->regsUsed,i) ||
2579 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2580 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2588 /* set the register bank to the desired value */
2589 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2590 pic14_emitcode("push","psw");
2591 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2594 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2596 if (options.useXstack) {
2597 pic14_emitcode("mov","r0,%s",spname);
2598 pic14_emitcode("mov","a,_bp");
2599 pic14_emitcode("movx","@r0,a");
2600 pic14_emitcode("inc","%s",spname);
2604 /* set up the stack */
2605 pic14_emitcode ("push","_bp"); /* save the callers stack */
2607 pic14_emitcode ("mov","_bp,%s",spname);
2610 /* adjust the stack for the function */
2615 werror(W_STACK_OVERFLOW,sym->name);
2617 if (i > 3 && sym->recvSize < 4) {
2619 pic14_emitcode ("mov","a,sp");
2620 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2621 pic14_emitcode ("mov","sp,a");
2626 pic14_emitcode("inc","sp");
2631 pic14_emitcode ("mov","a,_spx");
2632 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2633 pic14_emitcode ("mov","_spx,a");
2638 /*-----------------------------------------------------------------*/
2639 /* genEndFunction - generates epilogue for functions */
2640 /*-----------------------------------------------------------------*/
2641 static void genEndFunction (iCode *ic)
2643 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2649 pic14_emitcode ("mov","%s,_bp",spname);
2652 /* if use external stack but some variables were
2653 added to the local stack then decrement the
2655 if (options.useXstack && sym->stack) {
2656 pic14_emitcode("mov","a,sp");
2657 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2658 pic14_emitcode("mov","sp,a");
2662 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2663 if (options.useXstack) {
2664 pic14_emitcode("mov","r0,%s",spname);
2665 pic14_emitcode("movx","a,@r0");
2666 pic14_emitcode("mov","_bp,a");
2667 pic14_emitcode("dec","%s",spname);
2671 pic14_emitcode ("pop","_bp");
2675 /* restore the register bank */
2676 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2677 pic14_emitcode ("pop","psw");
2679 if (IFFUNC_ISISR(sym->type)) {
2681 /* now we need to restore the registers */
2682 /* if this isr has no bank i.e. is going to
2683 run with bank 0 , then we need to save more
2685 if (!FUNC_REGBANK(sym->type)) {
2687 /* if this function does not call any other
2688 function then we can be economical and
2689 save only those registers that are used */
2690 if (! IFFUNC_HASFCALL(sym->type)) {
2693 /* if any registers used */
2694 if (sym->regsUsed) {
2695 /* save the registers used */
2696 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2697 if (bitVectBitValue(sym->regsUsed,i) ||
2698 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2699 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2704 /* this function has a function call cannot
2705 determines register usage so we will have the
2707 unsaverbank(0,ic,FALSE);
2711 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2713 if (options.stack10bit)
2715 pic14_emitcode ("pop", "dpx1");
2716 pic14_emitcode ("pop", "dph1");
2717 pic14_emitcode ("pop", "dpl1");
2719 pic14_emitcode ("pop", "dps");
2720 pic14_emitcode ("pop", "dpx");
2722 if (!inExcludeList("dph"))
2723 pic14_emitcode ("pop","dph");
2724 if (!inExcludeList("dpl"))
2725 pic14_emitcode ("pop","dpl");
2726 if (!inExcludeList("b"))
2727 pic14_emitcode ("pop","b");
2728 if (!inExcludeList("acc"))
2729 pic14_emitcode ("pop","acc");
2731 if (IFFUNC_ISCRITICAL(sym->type))
2732 pic14_emitcode("setb","ea");
2734 /* if debug then send end of function */
2735 /* if (options.debug && currFunc) { */
2738 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2739 FileBaseName(ic->filename),currFunc->lastLine,
2740 ic->level,ic->block);
2741 if (IS_STATIC(currFunc->etype))
2742 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2744 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2748 pic14_emitcode ("reti","");
2751 if (IFFUNC_ISCRITICAL(sym->type))
2752 pic14_emitcode("setb","ea");
2754 if (IFFUNC_CALLEESAVES(sym->type)) {
2757 /* if any registers used */
2758 if (sym->regsUsed) {
2759 /* save the registers used */
2760 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2761 if (bitVectBitValue(sym->regsUsed,i) ||
2762 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2763 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2769 /* if debug then send end of function */
2772 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2773 FileBaseName(ic->filename),currFunc->lastLine,
2774 ic->level,ic->block);
2775 if (IS_STATIC(currFunc->etype))
2776 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2778 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2782 pic14_emitcode ("return","");
2783 emitpcodeNULLop(POC_RETURN);
2785 /* Mark the end of a function */
2786 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2791 /*-----------------------------------------------------------------*/
2792 /* genRet - generate code for return statement */
2793 /*-----------------------------------------------------------------*/
2794 static void genRet (iCode *ic)
2796 int size,offset = 0 , pushed = 0;
2798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2799 /* if we have no return value then
2800 just generate the "ret" */
2804 /* we have something to return then
2805 move the return value into place */
2806 aopOp(IC_LEFT(ic),ic,FALSE);
2807 size = AOP_SIZE(IC_LEFT(ic));
2811 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2813 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2815 pic14_emitcode("push","%s",l);
2818 l = aopGet(AOP(IC_LEFT(ic)),offset,
2820 if (strcmp(fReturn[offset],l)) {
2821 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2822 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2823 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2825 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2828 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2829 pic14_emitcode("movwf","%s",fReturn[offset]);
2839 if (strcmp(fReturn[pushed],"a"))
2840 pic14_emitcode("pop",fReturn[pushed]);
2842 pic14_emitcode("pop","acc");
2845 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2848 /* generate a jump to the return label
2849 if the next is not the return statement */
2850 if (!(ic->next && ic->next->op == LABEL &&
2851 IC_LABEL(ic->next) == returnLabel)) {
2853 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2854 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2859 /*-----------------------------------------------------------------*/
2860 /* genLabel - generates a label */
2861 /*-----------------------------------------------------------------*/
2862 static void genLabel (iCode *ic)
2864 /* special case never generate */
2865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2866 if (IC_LABEL(ic) == entryLabel)
2869 emitpLabel(IC_LABEL(ic)->key);
2870 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2873 /*-----------------------------------------------------------------*/
2874 /* genGoto - generates a goto */
2875 /*-----------------------------------------------------------------*/
2877 static void genGoto (iCode *ic)
2879 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2880 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2884 /*-----------------------------------------------------------------*/
2885 /* genMultbits :- multiplication of bits */
2886 /*-----------------------------------------------------------------*/
2887 static void genMultbits (operand *left,
2891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2893 if(!pic14_sameRegs(AOP(result),AOP(right)))
2894 emitpcode(POC_BSF, popGet(AOP(result),0));
2896 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2897 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2898 emitpcode(POC_BCF, popGet(AOP(result),0));
2903 /*-----------------------------------------------------------------*/
2904 /* genMultOneByte : 8 bit multiplication & division */
2905 /*-----------------------------------------------------------------*/
2906 static void genMultOneByte (operand *left,
2910 sym_link *opetype = operandType(result);
2915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2916 DEBUGpic14_AopType(__LINE__,left,right,result);
2918 /* (if two literals, the value is computed before) */
2919 /* if one literal, literal on the right */
2920 if (AOP_TYPE(left) == AOP_LIT){
2926 size = AOP_SIZE(result);
2927 /* signed or unsigned */
2928 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2929 l = aopGet(AOP(left),0,FALSE,FALSE);
2931 pic14_emitcode("mul","ab");
2932 /* if result size = 1, mul signed = mul unsigned */
2933 aopPut(AOP(result),"a",0);
2935 if (SPEC_USIGN(opetype)){
2936 aopPut(AOP(result),"b",1);
2938 /* for filling the MSBs */
2939 pic14_emitcode("clr","a");
2942 pic14_emitcode("mov","a,b");
2944 /* adjust the MSB if left or right neg */
2946 /* if one literal */
2947 if (AOP_TYPE(right) == AOP_LIT){
2948 /* AND literal negative */
2949 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2950 /* adjust MSB (c==0 after mul) */
2951 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2955 lbl = newiTempLabel(NULL);
2956 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2957 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2958 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2959 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2960 lbl = newiTempLabel(NULL);
2961 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2962 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2963 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2966 lbl = newiTempLabel(NULL);
2967 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2968 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2969 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2970 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2971 lbl = newiTempLabel(NULL);
2972 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2973 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2974 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2976 aopPut(AOP(result),"a",1);
2979 pic14_emitcode("rlc","a");
2980 pic14_emitcode("subb","a,acc");
2987 aopPut(AOP(result),"a",offset++);
2991 /*-----------------------------------------------------------------*/
2992 /* genMult - generates code for multiplication */
2993 /*-----------------------------------------------------------------*/
2994 static void genMult (iCode *ic)
2996 operand *left = IC_LEFT(ic);
2997 operand *right = IC_RIGHT(ic);
2998 operand *result= IC_RESULT(ic);
3000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3001 /* assign the amsops */
3002 aopOp (left,ic,FALSE);
3003 aopOp (right,ic,FALSE);
3004 aopOp (result,ic,TRUE);
3006 DEBUGpic14_AopType(__LINE__,left,right,result);
3008 /* special cases first */
3010 if (AOP_TYPE(left) == AOP_CRY &&
3011 AOP_TYPE(right)== AOP_CRY) {
3012 genMultbits(left,right,result);
3016 /* if both are of size == 1 */
3017 if (AOP_SIZE(left) == 1 &&
3018 AOP_SIZE(right) == 1 ) {
3019 genMultOneByte(left,right,result);
3023 /* should have been converted to function call */
3027 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3028 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3029 freeAsmop(result,NULL,ic,TRUE);
3032 /*-----------------------------------------------------------------*/
3033 /* genDivbits :- division of bits */
3034 /*-----------------------------------------------------------------*/
3035 static void genDivbits (operand *left,
3042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3043 /* the result must be bit */
3044 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3045 l = aopGet(AOP(left),0,FALSE,FALSE);
3049 pic14_emitcode("div","ab");
3050 pic14_emitcode("rrc","a");
3051 aopPut(AOP(result),"c",0);
3054 /*-----------------------------------------------------------------*/
3055 /* genDivOneByte : 8 bit division */
3056 /*-----------------------------------------------------------------*/
3057 static void genDivOneByte (operand *left,
3061 sym_link *opetype = operandType(result);
3066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3067 size = AOP_SIZE(result) - 1;
3069 /* signed or unsigned */
3070 if (SPEC_USIGN(opetype)) {
3071 /* unsigned is easy */
3072 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3073 l = aopGet(AOP(left),0,FALSE,FALSE);
3075 pic14_emitcode("div","ab");
3076 aopPut(AOP(result),"a",0);
3078 aopPut(AOP(result),zero,offset++);
3082 /* signed is a little bit more difficult */
3084 /* save the signs of the operands */
3085 l = aopGet(AOP(left),0,FALSE,FALSE);
3087 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3088 pic14_emitcode("push","acc"); /* save it on the stack */
3090 /* now sign adjust for both left & right */
3091 l = aopGet(AOP(right),0,FALSE,FALSE);
3093 lbl = newiTempLabel(NULL);
3094 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3095 pic14_emitcode("cpl","a");
3096 pic14_emitcode("inc","a");
3097 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3098 pic14_emitcode("mov","b,a");
3100 /* sign adjust left side */
3101 l = aopGet(AOP(left),0,FALSE,FALSE);
3104 lbl = newiTempLabel(NULL);
3105 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3106 pic14_emitcode("cpl","a");
3107 pic14_emitcode("inc","a");
3108 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3110 /* now the division */
3111 pic14_emitcode("div","ab");
3112 /* we are interested in the lower order
3114 pic14_emitcode("mov","b,a");
3115 lbl = newiTempLabel(NULL);
3116 pic14_emitcode("pop","acc");
3117 /* if there was an over flow we don't
3118 adjust the sign of the result */
3119 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3120 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3122 pic14_emitcode("clr","a");
3123 pic14_emitcode("subb","a,b");
3124 pic14_emitcode("mov","b,a");
3125 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3127 /* now we are done */
3128 aopPut(AOP(result),"b",0);
3130 pic14_emitcode("mov","c,b.7");
3131 pic14_emitcode("subb","a,acc");
3134 aopPut(AOP(result),"a",offset++);
3138 /*-----------------------------------------------------------------*/
3139 /* genDiv - generates code for division */
3140 /*-----------------------------------------------------------------*/
3141 static void genDiv (iCode *ic)
3143 operand *left = IC_LEFT(ic);
3144 operand *right = IC_RIGHT(ic);
3145 operand *result= IC_RESULT(ic);
3147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3148 /* assign the amsops */
3149 aopOp (left,ic,FALSE);
3150 aopOp (right,ic,FALSE);
3151 aopOp (result,ic,TRUE);
3153 /* special cases first */
3155 if (AOP_TYPE(left) == AOP_CRY &&
3156 AOP_TYPE(right)== AOP_CRY) {
3157 genDivbits(left,right,result);
3161 /* if both are of size == 1 */
3162 if (AOP_SIZE(left) == 1 &&
3163 AOP_SIZE(right) == 1 ) {
3164 genDivOneByte(left,right,result);
3168 /* should have been converted to function call */
3171 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3172 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3173 freeAsmop(result,NULL,ic,TRUE);
3176 /*-----------------------------------------------------------------*/
3177 /* genModbits :- modulus of bits */
3178 /*-----------------------------------------------------------------*/
3179 static void genModbits (operand *left,
3186 /* the result must be bit */
3187 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3188 l = aopGet(AOP(left),0,FALSE,FALSE);
3192 pic14_emitcode("div","ab");
3193 pic14_emitcode("mov","a,b");
3194 pic14_emitcode("rrc","a");
3195 aopPut(AOP(result),"c",0);
3198 /*-----------------------------------------------------------------*/
3199 /* genModOneByte : 8 bit modulus */
3200 /*-----------------------------------------------------------------*/
3201 static void genModOneByte (operand *left,
3205 sym_link *opetype = operandType(result);
3209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3210 /* signed or unsigned */
3211 if (SPEC_USIGN(opetype)) {
3212 /* unsigned is easy */
3213 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3214 l = aopGet(AOP(left),0,FALSE,FALSE);
3216 pic14_emitcode("div","ab");
3217 aopPut(AOP(result),"b",0);
3221 /* signed is a little bit more difficult */
3223 /* save the signs of the operands */
3224 l = aopGet(AOP(left),0,FALSE,FALSE);
3227 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3228 pic14_emitcode("push","acc"); /* save it on the stack */
3230 /* now sign adjust for both left & right */
3231 l = aopGet(AOP(right),0,FALSE,FALSE);
3234 lbl = newiTempLabel(NULL);
3235 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3236 pic14_emitcode("cpl","a");
3237 pic14_emitcode("inc","a");
3238 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3239 pic14_emitcode("mov","b,a");
3241 /* sign adjust left side */
3242 l = aopGet(AOP(left),0,FALSE,FALSE);
3245 lbl = newiTempLabel(NULL);
3246 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3247 pic14_emitcode("cpl","a");
3248 pic14_emitcode("inc","a");
3249 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251 /* now the multiplication */
3252 pic14_emitcode("div","ab");
3253 /* we are interested in the lower order
3255 lbl = newiTempLabel(NULL);
3256 pic14_emitcode("pop","acc");
3257 /* if there was an over flow we don't
3258 adjust the sign of the result */
3259 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3262 pic14_emitcode("clr","a");
3263 pic14_emitcode("subb","a,b");
3264 pic14_emitcode("mov","b,a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3267 /* now we are done */
3268 aopPut(AOP(result),"b",0);
3272 /*-----------------------------------------------------------------*/
3273 /* genMod - generates code for division */
3274 /*-----------------------------------------------------------------*/
3275 static void genMod (iCode *ic)
3277 operand *left = IC_LEFT(ic);
3278 operand *right = IC_RIGHT(ic);
3279 operand *result= IC_RESULT(ic);
3281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3282 /* assign the amsops */
3283 aopOp (left,ic,FALSE);
3284 aopOp (right,ic,FALSE);
3285 aopOp (result,ic,TRUE);
3287 /* special cases first */
3289 if (AOP_TYPE(left) == AOP_CRY &&
3290 AOP_TYPE(right)== AOP_CRY) {
3291 genModbits(left,right,result);
3295 /* if both are of size == 1 */
3296 if (AOP_SIZE(left) == 1 &&
3297 AOP_SIZE(right) == 1 ) {
3298 genModOneByte(left,right,result);
3302 /* should have been converted to function call */
3306 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3307 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3308 freeAsmop(result,NULL,ic,TRUE);
3311 /*-----------------------------------------------------------------*/
3312 /* genIfxJump :- will create a jump depending on the ifx */
3313 /*-----------------------------------------------------------------*/
3315 note: May need to add parameter to indicate when a variable is in bit space.
3317 static void genIfxJump (iCode *ic, char *jval)
3320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3321 /* if true label then we jump if condition
3323 if ( IC_TRUE(ic) ) {
3325 if(strcmp(jval,"a") == 0)
3327 else if (strcmp(jval,"c") == 0)
3330 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3331 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3334 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3335 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3339 /* false label is present */
3340 if(strcmp(jval,"a") == 0)
3342 else if (strcmp(jval,"c") == 0)
3345 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3346 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3349 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3350 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3355 /* mark the icode as generated */
3359 /*-----------------------------------------------------------------*/
3361 /*-----------------------------------------------------------------*/
3362 static void genSkip(iCode *ifx,int status_bit)
3367 if ( IC_TRUE(ifx) ) {
3368 switch(status_bit) {
3383 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3384 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3388 switch(status_bit) {
3402 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3403 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3409 /*-----------------------------------------------------------------*/
3411 /*-----------------------------------------------------------------*/
3412 static void genSkipc(resolvedIfx *rifx)
3422 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3423 rifx->generated = 1;
3426 /*-----------------------------------------------------------------*/
3428 /*-----------------------------------------------------------------*/
3429 static void genSkipz2(resolvedIfx *rifx)
3439 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3440 rifx->generated = 1;
3443 /*-----------------------------------------------------------------*/
3445 /*-----------------------------------------------------------------*/
3446 static void genSkipz(iCode *ifx, int condition)
3457 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3459 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3462 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3464 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3467 /*-----------------------------------------------------------------*/
3469 /*-----------------------------------------------------------------*/
3470 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3476 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3478 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3481 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3482 rifx->generated = 1;
3484 /*-----------------------------------------------------------------*/
3485 /* genCmp :- greater or less than comparison */
3486 /*-----------------------------------------------------------------*/
3487 static void genCmp (operand *left,operand *right,
3488 operand *result, iCode *ifx, int sign)
3490 int size, offset = 0 ;
3491 unsigned long lit = 0L,i = 0;
3494 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3496 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3497 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3500 resolveIfx(&rIfx,ifx);
3502 /* if left & right are bit variables */
3503 if (AOP_TYPE(left) == AOP_CRY &&
3504 AOP_TYPE(right) == AOP_CRY ) {
3505 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3506 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3508 /* subtract right from left if at the
3509 end the carry flag is set then we know that
3510 left is greater than right */
3511 size = max(AOP_SIZE(left),AOP_SIZE(right));
3513 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3514 if((size == 1) && !sign &&
3515 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3516 symbol *lbl = newiTempLabel(NULL);
3517 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3518 aopGet(AOP(left),offset,FALSE,FALSE),
3519 aopGet(AOP(right),offset,FALSE,FALSE),
3521 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3524 symbol *lbl = newiTempLabel(NULL);
3526 symbol *truelbl = newiTempLabel(NULL);
3529 if(AOP_TYPE(right) == AOP_LIT) {
3531 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3533 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3537 if(lit == 0 && sign == 0) {
3538 /* no need to compare to 0...*/
3539 if(ifx) ifx->generated = 1;
3546 i = (lit >> (size*8)) & 0xff;
3547 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3552 genSkipCond(&rIfx,left,0,7);
3555 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3559 emitpcode(POC_ADDLW, popGetLit(0x80));
3560 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3562 emitpcode(POC_ADDLW, popGetLit(i));
3567 if(ifx) ifx->generated = 1;
3574 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3579 i = (lit >> (size*8)) & 0xff;
3581 /* handle the first byte differently in signed compares */
3583 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3584 emitpcode(POC_ADDLW, popGetLit(0x80));
3585 emitpcode(POC_ADDLW, popGetLit(((-i)&0xff) ^ 0x80));
3588 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3593 emitpcode(POC_MOVLW, popGetLit(i));
3594 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3597 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3601 emitpLabel(lbl->key);
3604 emitpLabel(truelbl->key);
3606 if(ifx) ifx->generated = 1;
3612 if(AOP_TYPE(left) == AOP_LIT) {
3613 //symbol *lbl = newiTempLabel(NULL);
3615 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3617 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3620 if((lit == 0)&& (sign==0)) {
3623 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3625 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3627 if(ifx) ifx->generated = 1;
3634 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3635 emitpcode(POC_ADDLW, popGetLit(0x80));
3636 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3637 rIfx.condition ^= 1;
3640 genSkipCond(&rIfx,right,0,7);
3645 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3646 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3648 rIfx.condition ^= 1;
3651 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3659 i = (lit >> (size*8)) & 0xff;
3662 /* Handle first byte of compare differently */
3664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3667 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3668 emitpcode(POC_ADDLW, popGetLit(0x80));
3669 emitpcode(POC_SUBLW, popGetLit( (i & 0xff) ^ 0x80));
3670 //rIfx.condition ^= 1;
3673 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3675 rIfx.condition ^= 1;
3676 genSkipCond(&rIfx,right,size,7);
3677 rIfx.condition ^= 1;
3684 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3685 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3686 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3688 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3690 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3691 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3692 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3700 emitpLabel(lbl->key);
3702 rIfx.condition ^= 1;
3707 emitpLabel(truelbl->key);
3708 if(ifx) ifx->generated = 1;
3712 /* Compare two variables */
3714 DEBUGpic14_emitcode(";sign","%d",sign);
3718 /* Sigh. thus sucks... */
3720 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3721 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
3722 emitpcode(POC_MOVLW, popGetLit(0x80));
3723 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
3724 emitpcode(POC_XORFW, popGet(AOP(right),size));
3725 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
3727 /* Signed char comparison */
3728 /* Special thanks to Nikolai Golovchenko for this snippet */
3729 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3730 emitpcode(POC_SUBFW, popGet(AOP(left),0));
3731 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
3732 emitpcode(POC_XORFW, popGet(AOP(left),0));
3733 emitpcode(POC_XORFW, popGet(AOP(right),0));
3734 emitpcode(POC_ADDLW, popGetLit(0x80));
3736 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3739 if(ifx) ifx->generated = 1;
3745 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3746 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3750 /* The rest of the bytes of a multi-byte compare */
3754 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3757 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3758 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3763 emitpLabel(lbl->key);
3765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3767 if(ifx) ifx->generated = 1;
3774 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3775 pic14_outBitC(result);
3777 /* if the result is used in the next
3778 ifx conditional branch then generate
3779 code a little differently */
3781 genIfxJump (ifx,"c");
3783 pic14_outBitC(result);
3784 /* leave the result in acc */
3789 /*-----------------------------------------------------------------*/
3790 /* genCmpGt :- greater than comparison */
3791 /*-----------------------------------------------------------------*/
3792 static void genCmpGt (iCode *ic, iCode *ifx)
3794 operand *left, *right, *result;
3795 sym_link *letype , *retype;
3798 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3800 right= IC_RIGHT(ic);
3801 result = IC_RESULT(ic);
3803 letype = getSpec(operandType(left));
3804 retype =getSpec(operandType(right));
3805 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3806 /* assign the amsops */
3807 aopOp (left,ic,FALSE);
3808 aopOp (right,ic,FALSE);
3809 aopOp (result,ic,TRUE);
3811 genCmp(right, left, result, ifx, sign);
3813 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3814 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3815 freeAsmop(result,NULL,ic,TRUE);
3818 /*-----------------------------------------------------------------*/
3819 /* genCmpLt - less than comparisons */
3820 /*-----------------------------------------------------------------*/
3821 static void genCmpLt (iCode *ic, iCode *ifx)
3823 operand *left, *right, *result;
3824 sym_link *letype , *retype;
3827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3829 right= IC_RIGHT(ic);
3830 result = IC_RESULT(ic);
3832 letype = getSpec(operandType(left));
3833 retype =getSpec(operandType(right));
3834 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3836 /* assign the amsops */
3837 aopOp (left,ic,FALSE);
3838 aopOp (right,ic,FALSE);
3839 aopOp (result,ic,TRUE);
3841 genCmp(left, right, result, ifx, sign);
3843 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3844 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3845 freeAsmop(result,NULL,ic,TRUE);
3848 /*-----------------------------------------------------------------*/
3849 /* genc16bit2lit - compare a 16 bit value to a literal */
3850 /*-----------------------------------------------------------------*/
3851 static void genc16bit2lit(operand *op, int lit, int offset)
3855 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3856 if( (lit&0xff) == 0)
3861 switch( BYTEofLONG(lit,i)) {
3863 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3866 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3869 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3872 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3873 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3878 switch( BYTEofLONG(lit,i)) {
3880 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
3884 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3888 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3891 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3893 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
3899 /*-----------------------------------------------------------------*/
3900 /* gencjneshort - compare and jump if not equal */
3901 /*-----------------------------------------------------------------*/
3902 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
3904 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3909 unsigned long lit = 0L;
3910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3911 DEBUGpic14_AopType(__LINE__,left,right,NULL);
3913 resolveIfx(&rIfx,ifx);
3914 lbl = newiTempLabel(NULL);
3917 /* if the left side is a literal or
3918 if the right is in a pointer register and left
3920 if ((AOP_TYPE(left) == AOP_LIT) ||
3921 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3926 if(AOP_TYPE(right) == AOP_LIT)
3927 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3929 /* if the right side is a literal then anything goes */
3930 if (AOP_TYPE(right) == AOP_LIT &&
3931 AOP_TYPE(left) != AOP_DIR ) {
3934 genc16bit2lit(left, lit, 0);
3936 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3941 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3942 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3944 emitpcode(POC_MOVF,popGet(AOP(left),offset));
3948 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3956 /* if the right side is in a register or in direct space or
3957 if the left is a pointer register & right is not */
3958 else if (AOP_TYPE(right) == AOP_REG ||
3959 AOP_TYPE(right) == AOP_DIR ||
3960 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3961 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3964 genc16bit2lit(left, lit, 0);
3966 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3971 if((AOP_TYPE(left) == AOP_DIR) &&
3972 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3974 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3975 emitpcode(POC_XORFW,popGet(AOP(right),offset));
3977 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3979 switch (lit & 0xff) {
3981 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3984 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
3985 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3989 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
3990 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3994 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3995 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4000 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4003 if(AOP_TYPE(result) == AOP_CRY) {
4004 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4009 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4011 /* fix me. probably need to check result size too */
4012 emitpcode(POC_CLRF,popGet(AOP(result),0));
4017 emitpcode(POC_INCF,popGet(AOP(result),0));
4027 } else if(AOP_TYPE(right) == AOP_REG &&
4028 AOP_TYPE(left) != AOP_DIR){
4031 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4032 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4033 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4038 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4043 /* right is a pointer reg need both a & b */
4045 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4047 pic14_emitcode("mov","b,%s",l);
4048 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4049 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4053 emitpLabel(lbl->key);
4060 /*-----------------------------------------------------------------*/
4061 /* gencjne - compare and jump if not equal */
4062 /*-----------------------------------------------------------------*/
4063 static void gencjne(operand *left, operand *right, iCode *ifx)
4065 symbol *tlbl = newiTempLabel(NULL);
4067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4068 gencjneshort(left, right, lbl);
4070 pic14_emitcode("mov","a,%s",one);
4071 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4072 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4073 pic14_emitcode("clr","a");
4074 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4076 emitpLabel(lbl->key);
4077 emitpLabel(tlbl->key);
4082 /*-----------------------------------------------------------------*/
4083 /* genCmpEq - generates code for equal to */
4084 /*-----------------------------------------------------------------*/
4085 static void genCmpEq (iCode *ic, iCode *ifx)
4087 operand *left, *right, *result;
4088 unsigned long lit = 0L;
4091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4094 DEBUGpic14_emitcode ("; ifx is non-null","");
4096 DEBUGpic14_emitcode ("; ifx is null","");
4098 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4099 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4100 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4102 size = max(AOP_SIZE(left),AOP_SIZE(right));
4104 DEBUGpic14_AopType(__LINE__,left,right,result);
4106 /* if literal, literal on the right or
4107 if the right is in a pointer register and left
4109 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4110 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4111 operand *t = IC_RIGHT(ic);
4112 IC_RIGHT(ic) = IC_LEFT(ic);
4116 if(ifx && !AOP_SIZE(result)){
4118 /* if they are both bit variables */
4119 if (AOP_TYPE(left) == AOP_CRY &&
4120 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4121 if(AOP_TYPE(right) == AOP_LIT){
4122 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4124 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4125 pic14_emitcode("cpl","c");
4126 } else if(lit == 1L) {
4127 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4129 pic14_emitcode("clr","c");
4131 /* AOP_TYPE(right) == AOP_CRY */
4133 symbol *lbl = newiTempLabel(NULL);
4134 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4135 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4136 pic14_emitcode("cpl","c");
4137 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4139 /* if true label then we jump if condition
4141 tlbl = newiTempLabel(NULL);
4142 if ( IC_TRUE(ifx) ) {
4143 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4144 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4146 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4147 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4149 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4152 /* They're not both bit variables. Is the right a literal? */
4153 if(AOP_TYPE(right) == AOP_LIT) {
4154 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4160 switch(lit & 0xff) {
4162 if ( IC_TRUE(ifx) ) {
4163 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4165 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4167 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4168 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4172 if ( IC_TRUE(ifx) ) {
4173 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4175 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4177 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4178 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4182 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4184 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4189 /* end of size == 1 */
4193 genc16bit2lit(left,lit,offset);
4196 /* end of size == 2 */
4201 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4202 emitpcode(POC_IORFW,popGet(AOP(left),1));
4203 emitpcode(POC_IORFW,popGet(AOP(left),2));
4204 emitpcode(POC_IORFW,popGet(AOP(left),3));
4208 /* search for patterns that can be optimized */
4210 genc16bit2lit(left,lit,0);
4213 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4215 genc16bit2lit(left,lit,2);
4217 emitpcode(POC_IORFW,popGet(AOP(left),2));
4218 emitpcode(POC_IORFW,popGet(AOP(left),3));
4231 } else if(AOP_TYPE(right) == AOP_CRY ) {
4232 /* we know the left is not a bit, but that the right is */
4233 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4234 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4235 popGet(AOP(right),offset));
4236 emitpcode(POC_XORLW,popGetLit(1));
4238 /* if the two are equal, then W will be 0 and the Z bit is set
4239 * we could test Z now, or go ahead and check the high order bytes if
4240 * the variable we're comparing is larger than a byte. */
4243 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4245 if ( IC_TRUE(ifx) ) {
4247 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4248 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4251 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4252 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4256 /* They're both variables that are larger than bits */
4259 tlbl = newiTempLabel(NULL);
4262 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4263 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4265 if ( IC_TRUE(ifx) ) {
4268 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4269 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4272 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4273 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4277 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4278 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4282 if(s>1 && IC_TRUE(ifx)) {
4283 emitpLabel(tlbl->key);
4284 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4288 /* mark the icode as generated */
4293 /* if they are both bit variables */
4294 if (AOP_TYPE(left) == AOP_CRY &&
4295 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4296 if(AOP_TYPE(right) == AOP_LIT){
4297 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4299 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4300 pic14_emitcode("cpl","c");
4301 } else if(lit == 1L) {
4302 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4304 pic14_emitcode("clr","c");
4306 /* AOP_TYPE(right) == AOP_CRY */
4308 symbol *lbl = newiTempLabel(NULL);
4309 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4310 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4311 pic14_emitcode("cpl","c");
4312 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4315 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4316 pic14_outBitC(result);
4320 genIfxJump (ifx,"c");
4323 /* if the result is used in an arithmetic operation
4324 then put the result in place */
4325 pic14_outBitC(result);
4328 gencjne(left,right,result,ifx);
4331 gencjne(left,right,newiTempLabel(NULL));
4333 if(IC_TRUE(ifx)->key)
4334 gencjne(left,right,IC_TRUE(ifx)->key);
4336 gencjne(left,right,IC_FALSE(ifx)->key);
4340 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4341 aopPut(AOP(result),"a",0);
4346 genIfxJump (ifx,"a");
4350 /* if the result is used in an arithmetic operation
4351 then put the result in place */
4353 if (AOP_TYPE(result) != AOP_CRY)
4354 pic14_outAcc(result);
4356 /* leave the result in acc */
4360 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4361 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4362 freeAsmop(result,NULL,ic,TRUE);
4365 /*-----------------------------------------------------------------*/
4366 /* ifxForOp - returns the icode containing the ifx for operand */
4367 /*-----------------------------------------------------------------*/
4368 static iCode *ifxForOp ( operand *op, iCode *ic )
4370 /* if true symbol then needs to be assigned */
4371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4372 if (IS_TRUE_SYMOP(op))
4375 /* if this has register type condition and
4376 the next instruction is ifx with the same operand
4377 and live to of the operand is upto the ifx only then */
4379 ic->next->op == IFX &&
4380 IC_COND(ic->next)->key == op->key &&
4381 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4385 ic->next->op == IFX &&
4386 IC_COND(ic->next)->key == op->key) {
4387 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4391 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4393 ic->next->op == IFX)
4394 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4397 ic->next->op == IFX &&
4398 IC_COND(ic->next)->key == op->key) {
4399 DEBUGpic14_emitcode ("; "," key is okay");
4400 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4401 OP_SYMBOL(op)->liveTo,
4408 /*-----------------------------------------------------------------*/
4409 /* genAndOp - for && operation */
4410 /*-----------------------------------------------------------------*/
4411 static void genAndOp (iCode *ic)
4413 operand *left,*right, *result;
4416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4417 /* note here that && operations that are in an
4418 if statement are taken away by backPatchLabels
4419 only those used in arthmetic operations remain */
4420 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4421 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4422 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4424 /* if both are bit variables */
4425 if (AOP_TYPE(left) == AOP_CRY &&
4426 AOP_TYPE(right) == AOP_CRY ) {
4427 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4428 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4429 pic14_outBitC(result);
4431 tlbl = newiTempLabel(NULL);
4432 pic14_toBoolean(left);
4433 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4434 pic14_toBoolean(right);
4435 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4436 pic14_outBitAcc(result);
4439 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 freeAsmop(result,NULL,ic,TRUE);
4445 /*-----------------------------------------------------------------*/
4446 /* genOrOp - for || operation */
4447 /*-----------------------------------------------------------------*/
4450 modified this code, but it doesn't appear to ever get called
4453 static void genOrOp (iCode *ic)
4455 operand *left,*right, *result;
4458 /* note here that || operations that are in an
4459 if statement are taken away by backPatchLabels
4460 only those used in arthmetic operations remain */
4461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4462 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4463 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4464 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4466 DEBUGpic14_AopType(__LINE__,left,right,result);
4468 /* if both are bit variables */
4469 if (AOP_TYPE(left) == AOP_CRY &&
4470 AOP_TYPE(right) == AOP_CRY ) {
4471 pic14_emitcode("clrc","");
4472 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4473 AOP(left)->aopu.aop_dir,
4474 AOP(left)->aopu.aop_dir);
4475 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4476 AOP(right)->aopu.aop_dir,
4477 AOP(right)->aopu.aop_dir);
4478 pic14_emitcode("setc","");
4481 tlbl = newiTempLabel(NULL);
4482 pic14_toBoolean(left);
4484 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4485 pic14_toBoolean(right);
4486 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4488 pic14_outBitAcc(result);
4491 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4492 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4493 freeAsmop(result,NULL,ic,TRUE);
4496 /*-----------------------------------------------------------------*/
4497 /* isLiteralBit - test if lit == 2^n */
4498 /*-----------------------------------------------------------------*/
4499 static int isLiteralBit(unsigned long lit)
4501 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4502 0x100L,0x200L,0x400L,0x800L,
4503 0x1000L,0x2000L,0x4000L,0x8000L,
4504 0x10000L,0x20000L,0x40000L,0x80000L,
4505 0x100000L,0x200000L,0x400000L,0x800000L,
4506 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4507 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4510 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4511 for(idx = 0; idx < 32; idx++)
4517 /*-----------------------------------------------------------------*/
4518 /* continueIfTrue - */
4519 /*-----------------------------------------------------------------*/
4520 static void continueIfTrue (iCode *ic)
4522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4524 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4528 /*-----------------------------------------------------------------*/
4530 /*-----------------------------------------------------------------*/
4531 static void jumpIfTrue (iCode *ic)
4533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4535 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4539 /*-----------------------------------------------------------------*/
4540 /* jmpTrueOrFalse - */
4541 /*-----------------------------------------------------------------*/
4542 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4544 // ugly but optimized by peephole
4545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4547 symbol *nlbl = newiTempLabel(NULL);
4548 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4549 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4550 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4551 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4554 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4555 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4560 /*-----------------------------------------------------------------*/
4561 /* genAnd - code for and */
4562 /*-----------------------------------------------------------------*/
4563 static void genAnd (iCode *ic, iCode *ifx)
4565 operand *left, *right, *result;
4567 unsigned long lit = 0L;
4572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4573 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4574 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4575 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4577 resolveIfx(&rIfx,ifx);
4579 /* if left is a literal & right is not then exchange them */
4580 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4581 AOP_NEEDSACC(left)) {
4582 operand *tmp = right ;
4587 /* if result = right then exchange them */
4588 if(pic14_sameRegs(AOP(result),AOP(right))){
4589 operand *tmp = right ;
4594 /* if right is bit then exchange them */
4595 if (AOP_TYPE(right) == AOP_CRY &&
4596 AOP_TYPE(left) != AOP_CRY){
4597 operand *tmp = right ;
4601 if(AOP_TYPE(right) == AOP_LIT)
4602 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4604 size = AOP_SIZE(result);
4606 DEBUGpic14_AopType(__LINE__,left,right,result);
4609 // result = bit & yy;
4610 if (AOP_TYPE(left) == AOP_CRY){
4611 // c = bit & literal;
4612 if(AOP_TYPE(right) == AOP_LIT){
4614 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4617 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4620 if(size && (AOP_TYPE(result) == AOP_CRY)){
4621 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4624 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4628 pic14_emitcode("clr","c");
4631 if (AOP_TYPE(right) == AOP_CRY){
4633 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4634 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4637 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4639 pic14_emitcode("rrc","a");
4640 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4646 pic14_outBitC(result);
4648 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4649 genIfxJump(ifx, "c");
4653 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4654 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4655 if((AOP_TYPE(right) == AOP_LIT) &&
4656 (AOP_TYPE(result) == AOP_CRY) &&
4657 (AOP_TYPE(left) != AOP_CRY)){
4658 int posbit = isLiteralBit(lit);
4662 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4665 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4671 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4672 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4674 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4675 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4678 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4679 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4680 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4687 symbol *tlbl = newiTempLabel(NULL);
4688 int sizel = AOP_SIZE(left);
4690 pic14_emitcode("setb","c");
4692 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4693 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4695 if((posbit = isLiteralBit(bytelit)) != 0)
4696 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4698 if(bytelit != 0x0FFL)
4699 pic14_emitcode("anl","a,%s",
4700 aopGet(AOP(right),offset,FALSE,TRUE));
4701 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4706 // bit = left & literal
4708 pic14_emitcode("clr","c");
4709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4711 // if(left & literal)
4714 jmpTrueOrFalse(ifx, tlbl);
4718 pic14_outBitC(result);
4722 /* if left is same as result */
4723 if(pic14_sameRegs(AOP(result),AOP(left))){
4725 for(;size--; offset++,lit>>=8) {
4726 if(AOP_TYPE(right) == AOP_LIT){
4727 switch(lit & 0xff) {
4729 /* and'ing with 0 has clears the result */
4730 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4731 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4734 /* and'ing with 0xff is a nop when the result and left are the same */
4739 int p = my_powof2( (~lit) & 0xff );
4741 /* only one bit is set in the literal, so use a bcf instruction */
4742 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4743 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4746 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4747 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4748 if(know_W != (lit&0xff))
4749 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4751 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4756 if (AOP_TYPE(left) == AOP_ACC) {
4757 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4759 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4760 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4767 // left & result in different registers
4768 if(AOP_TYPE(result) == AOP_CRY){
4770 // if(size), result in bit
4771 // if(!size && ifx), conditional oper: if(left & right)
4772 symbol *tlbl = newiTempLabel(NULL);
4773 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4775 pic14_emitcode("setb","c");
4777 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4778 pic14_emitcode("anl","a,%s",
4779 aopGet(AOP(left),offset,FALSE,FALSE));
4780 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4785 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4786 pic14_outBitC(result);
4788 jmpTrueOrFalse(ifx, tlbl);
4790 for(;(size--);offset++) {
4792 // result = left & right
4793 if(AOP_TYPE(right) == AOP_LIT){
4794 int t = (lit >> (offset*8)) & 0x0FFL;
4797 pic14_emitcode("clrf","%s",
4798 aopGet(AOP(result),offset,FALSE,FALSE));
4799 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4802 pic14_emitcode("movf","%s,w",
4803 aopGet(AOP(left),offset,FALSE,FALSE));
4804 pic14_emitcode("movwf","%s",
4805 aopGet(AOP(result),offset,FALSE,FALSE));
4806 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4807 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4810 pic14_emitcode("movlw","0x%x",t);
4811 pic14_emitcode("andwf","%s,w",
4812 aopGet(AOP(left),offset,FALSE,FALSE));
4813 pic14_emitcode("movwf","%s",
4814 aopGet(AOP(result),offset,FALSE,FALSE));
4816 emitpcode(POC_MOVLW, popGetLit(t));
4817 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4818 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4823 if (AOP_TYPE(left) == AOP_ACC) {
4824 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4825 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4827 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4828 pic14_emitcode("andwf","%s,w",
4829 aopGet(AOP(left),offset,FALSE,FALSE));
4830 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4831 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4833 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4834 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4840 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4841 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4842 freeAsmop(result,NULL,ic,TRUE);
4845 /*-----------------------------------------------------------------*/
4846 /* genOr - code for or */
4847 /*-----------------------------------------------------------------*/
4848 static void genOr (iCode *ic, iCode *ifx)
4850 operand *left, *right, *result;
4852 unsigned long lit = 0L;
4854 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4856 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4857 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4858 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4860 DEBUGpic14_AopType(__LINE__,left,right,result);
4862 /* if left is a literal & right is not then exchange them */
4863 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4864 AOP_NEEDSACC(left)) {
4865 operand *tmp = right ;
4870 /* if result = right then exchange them */
4871 if(pic14_sameRegs(AOP(result),AOP(right))){
4872 operand *tmp = right ;
4877 /* if right is bit then exchange them */
4878 if (AOP_TYPE(right) == AOP_CRY &&
4879 AOP_TYPE(left) != AOP_CRY){
4880 operand *tmp = right ;
4885 DEBUGpic14_AopType(__LINE__,left,right,result);
4887 if(AOP_TYPE(right) == AOP_LIT)
4888 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4890 size = AOP_SIZE(result);
4894 if (AOP_TYPE(left) == AOP_CRY){
4895 if(AOP_TYPE(right) == AOP_LIT){
4896 // c = bit & literal;
4898 // lit != 0 => result = 1
4899 if(AOP_TYPE(result) == AOP_CRY){
4901 emitpcode(POC_BSF, popGet(AOP(result),0));
4902 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4903 // AOP(result)->aopu.aop_dir,
4904 // AOP(result)->aopu.aop_dir);
4906 continueIfTrue(ifx);
4910 // lit == 0 => result = left
4911 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4913 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4916 if (AOP_TYPE(right) == AOP_CRY){
4917 if(pic14_sameRegs(AOP(result),AOP(left))){
4919 emitpcode(POC_BCF, popGet(AOP(result),0));
4920 emitpcode(POC_BTFSC, popGet(AOP(right),0));
4921 emitpcode(POC_BSF, popGet(AOP(result),0));
4923 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4924 AOP(result)->aopu.aop_dir,
4925 AOP(result)->aopu.aop_dir);
4926 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4927 AOP(right)->aopu.aop_dir,
4928 AOP(right)->aopu.aop_dir);
4929 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4930 AOP(result)->aopu.aop_dir,
4931 AOP(result)->aopu.aop_dir);
4933 if( AOP_TYPE(result) == AOP_ACC) {
4934 emitpcode(POC_MOVLW, popGetLit(0));
4935 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4936 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4937 emitpcode(POC_MOVLW, popGetLit(1));
4941 emitpcode(POC_BCF, popGet(AOP(result),0));
4942 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4943 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4944 emitpcode(POC_BSF, popGet(AOP(result),0));
4946 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4947 AOP(result)->aopu.aop_dir,
4948 AOP(result)->aopu.aop_dir);
4949 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4950 AOP(right)->aopu.aop_dir,
4951 AOP(right)->aopu.aop_dir);
4952 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4953 AOP(left)->aopu.aop_dir,
4954 AOP(left)->aopu.aop_dir);
4955 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4956 AOP(result)->aopu.aop_dir,
4957 AOP(result)->aopu.aop_dir);
4962 symbol *tlbl = newiTempLabel(NULL);
4963 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4966 emitpcode(POC_BCF, popGet(AOP(result),0));
4967 if( AOP_TYPE(right) == AOP_ACC) {
4968 emitpcode(POC_IORLW, popGetLit(0));
4970 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4971 emitpcode(POC_BSF, popGet(AOP(result),0));
4976 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4977 pic14_emitcode(";XXX setb","c");
4978 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4979 AOP(left)->aopu.aop_dir,tlbl->key+100);
4980 pic14_toBoolean(right);
4981 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4982 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4983 jmpTrueOrFalse(ifx, tlbl);
4987 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4994 pic14_outBitC(result);
4996 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4997 genIfxJump(ifx, "c");
5001 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5002 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5003 if((AOP_TYPE(right) == AOP_LIT) &&
5004 (AOP_TYPE(result) == AOP_CRY) &&
5005 (AOP_TYPE(left) != AOP_CRY)){
5007 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5010 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5012 continueIfTrue(ifx);
5015 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5016 // lit = 0, result = boolean(left)
5018 pic14_emitcode(";XXX setb","c");
5019 pic14_toBoolean(right);
5021 symbol *tlbl = newiTempLabel(NULL);
5022 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5024 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5026 genIfxJump (ifx,"a");
5030 pic14_outBitC(result);
5034 /* if left is same as result */
5035 if(pic14_sameRegs(AOP(result),AOP(left))){
5037 for(;size--; offset++,lit>>=8) {
5038 if(AOP_TYPE(right) == AOP_LIT){
5039 if((lit & 0xff) == 0)
5040 /* or'ing with 0 has no effect */
5043 int p = my_powof2(lit & 0xff);
5045 /* only one bit is set in the literal, so use a bsf instruction */
5047 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5049 if(know_W != (lit & 0xff))
5050 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5051 know_W = lit & 0xff;
5052 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5057 if (AOP_TYPE(left) == AOP_ACC) {
5058 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5059 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5061 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5062 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5064 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5065 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5071 // left & result in different registers
5072 if(AOP_TYPE(result) == AOP_CRY){
5074 // if(size), result in bit
5075 // if(!size && ifx), conditional oper: if(left | right)
5076 symbol *tlbl = newiTempLabel(NULL);
5077 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5078 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5082 pic14_emitcode(";XXX setb","c");
5084 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5085 pic14_emitcode(";XXX orl","a,%s",
5086 aopGet(AOP(left),offset,FALSE,FALSE));
5087 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5092 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5093 pic14_outBitC(result);
5095 jmpTrueOrFalse(ifx, tlbl);
5096 } else for(;(size--);offset++){
5098 // result = left & right
5099 if(AOP_TYPE(right) == AOP_LIT){
5100 int t = (lit >> (offset*8)) & 0x0FFL;
5103 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5104 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5106 pic14_emitcode("movf","%s,w",
5107 aopGet(AOP(left),offset,FALSE,FALSE));
5108 pic14_emitcode("movwf","%s",
5109 aopGet(AOP(result),offset,FALSE,FALSE));
5112 emitpcode(POC_MOVLW, popGetLit(t));
5113 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5114 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5116 pic14_emitcode("movlw","0x%x",t);
5117 pic14_emitcode("iorwf","%s,w",
5118 aopGet(AOP(left),offset,FALSE,FALSE));
5119 pic14_emitcode("movwf","%s",
5120 aopGet(AOP(result),offset,FALSE,FALSE));
5126 // faster than result <- left, anl result,right
5127 // and better if result is SFR
5128 if (AOP_TYPE(left) == AOP_ACC) {
5129 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5130 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5132 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5133 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5135 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5136 pic14_emitcode("iorwf","%s,w",
5137 aopGet(AOP(left),offset,FALSE,FALSE));
5139 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5140 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5145 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5146 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5147 freeAsmop(result,NULL,ic,TRUE);
5150 /*-----------------------------------------------------------------*/
5151 /* genXor - code for xclusive or */
5152 /*-----------------------------------------------------------------*/
5153 static void genXor (iCode *ic, iCode *ifx)
5155 operand *left, *right, *result;
5157 unsigned long lit = 0L;
5159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5161 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5162 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5163 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5165 /* if left is a literal & right is not ||
5166 if left needs acc & right does not */
5167 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5168 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5169 operand *tmp = right ;
5174 /* if result = right then exchange them */
5175 if(pic14_sameRegs(AOP(result),AOP(right))){
5176 operand *tmp = right ;
5181 /* if right is bit then exchange them */
5182 if (AOP_TYPE(right) == AOP_CRY &&
5183 AOP_TYPE(left) != AOP_CRY){
5184 operand *tmp = right ;
5188 if(AOP_TYPE(right) == AOP_LIT)
5189 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5191 size = AOP_SIZE(result);
5195 if (AOP_TYPE(left) == AOP_CRY){
5196 if(AOP_TYPE(right) == AOP_LIT){
5197 // c = bit & literal;
5199 // lit>>1 != 0 => result = 1
5200 if(AOP_TYPE(result) == AOP_CRY){
5202 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5204 continueIfTrue(ifx);
5207 pic14_emitcode("setb","c");
5211 // lit == 0, result = left
5212 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5214 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5216 // lit == 1, result = not(left)
5217 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5218 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5221 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5222 pic14_emitcode("cpl","c");
5229 symbol *tlbl = newiTempLabel(NULL);
5230 if (AOP_TYPE(right) == AOP_CRY){
5232 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5235 int sizer = AOP_SIZE(right);
5237 // if val>>1 != 0, result = 1
5238 pic14_emitcode("setb","c");
5240 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5242 // test the msb of the lsb
5243 pic14_emitcode("anl","a,#0xfe");
5244 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5248 pic14_emitcode("rrc","a");
5250 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5251 pic14_emitcode("cpl","c");
5252 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5257 pic14_outBitC(result);
5259 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5260 genIfxJump(ifx, "c");
5264 if(pic14_sameRegs(AOP(result),AOP(left))){
5265 /* if left is same as result */
5266 for(;size--; offset++) {
5267 if(AOP_TYPE(right) == AOP_LIT){
5268 int t = (lit >> (offset*8)) & 0x0FFL;
5272 if (IS_AOP_PREG(left)) {
5273 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5274 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5275 aopPut(AOP(result),"a",offset);
5277 emitpcode(POC_MOVLW, popGetLit(t));
5278 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5279 pic14_emitcode("xrl","%s,%s",
5280 aopGet(AOP(left),offset,FALSE,TRUE),
5281 aopGet(AOP(right),offset,FALSE,FALSE));
5284 if (AOP_TYPE(left) == AOP_ACC)
5285 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5287 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5288 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5290 if (IS_AOP_PREG(left)) {
5291 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5292 aopPut(AOP(result),"a",offset);
5294 pic14_emitcode("xrl","%s,a",
5295 aopGet(AOP(left),offset,FALSE,TRUE));
5301 // left & result in different registers
5302 if(AOP_TYPE(result) == AOP_CRY){
5304 // if(size), result in bit
5305 // if(!size && ifx), conditional oper: if(left ^ right)
5306 symbol *tlbl = newiTempLabel(NULL);
5307 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5309 pic14_emitcode("setb","c");
5311 if((AOP_TYPE(right) == AOP_LIT) &&
5312 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5313 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5315 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5316 pic14_emitcode("xrl","a,%s",
5317 aopGet(AOP(left),offset,FALSE,FALSE));
5319 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5324 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5325 pic14_outBitC(result);
5327 jmpTrueOrFalse(ifx, tlbl);
5328 } else for(;(size--);offset++){
5330 // result = left & right
5331 if(AOP_TYPE(right) == AOP_LIT){
5332 int t = (lit >> (offset*8)) & 0x0FFL;
5335 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5336 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5337 pic14_emitcode("movf","%s,w",
5338 aopGet(AOP(left),offset,FALSE,FALSE));
5339 pic14_emitcode("movwf","%s",
5340 aopGet(AOP(result),offset,FALSE,FALSE));
5343 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5344 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5345 pic14_emitcode("comf","%s,w",
5346 aopGet(AOP(left),offset,FALSE,FALSE));
5347 pic14_emitcode("movwf","%s",
5348 aopGet(AOP(result),offset,FALSE,FALSE));
5351 emitpcode(POC_MOVLW, popGetLit(t));
5352 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5353 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5354 pic14_emitcode("movlw","0x%x",t);
5355 pic14_emitcode("xorwf","%s,w",
5356 aopGet(AOP(left),offset,FALSE,FALSE));
5357 pic14_emitcode("movwf","%s",
5358 aopGet(AOP(result),offset,FALSE,FALSE));
5364 // faster than result <- left, anl result,right
5365 // and better if result is SFR
5366 if (AOP_TYPE(left) == AOP_ACC) {
5367 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5368 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5370 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5371 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5372 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5373 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5375 if ( AOP_TYPE(result) != AOP_ACC){
5376 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5377 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5383 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5384 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5385 freeAsmop(result,NULL,ic,TRUE);
5388 /*-----------------------------------------------------------------*/
5389 /* genInline - write the inline code out */
5390 /*-----------------------------------------------------------------*/
5391 static void genInline (iCode *ic)
5393 char *buffer, *bp, *bp1;
5395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5397 _G.inLine += (!options.asmpeep);
5399 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5400 strcpy(buffer,IC_INLINE(ic));
5402 /* emit each line as a code */
5406 pic14_emitcode(bp1,"");
5413 pic14_emitcode(bp1,"");
5420 pic14_emitcode(bp1,"");
5421 /* pic14_emitcode("",buffer); */
5422 _G.inLine -= (!options.asmpeep);
5425 /*-----------------------------------------------------------------*/
5426 /* genRRC - rotate right with carry */
5427 /*-----------------------------------------------------------------*/
5428 static void genRRC (iCode *ic)
5430 operand *left , *result ;
5431 int size, offset = 0, same;
5433 /* rotate right with carry */
5435 result=IC_RESULT(ic);
5436 aopOp (left,ic,FALSE);
5437 aopOp (result,ic,FALSE);
5439 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5441 same = pic14_sameRegs(AOP(result),AOP(left));
5443 size = AOP_SIZE(result);
5445 /* get the lsb and put it into the carry */
5446 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5453 emitpcode(POC_RRF, popGet(AOP(left),offset));
5455 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5456 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5462 freeAsmop(left,NULL,ic,TRUE);
5463 freeAsmop(result,NULL,ic,TRUE);
5466 /*-----------------------------------------------------------------*/
5467 /* genRLC - generate code for rotate left with carry */
5468 /*-----------------------------------------------------------------*/
5469 static void genRLC (iCode *ic)
5471 operand *left , *result ;
5472 int size, offset = 0;
5475 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5476 /* rotate right with carry */
5478 result=IC_RESULT(ic);
5479 aopOp (left,ic,FALSE);
5480 aopOp (result,ic,FALSE);
5482 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5484 same = pic14_sameRegs(AOP(result),AOP(left));
5486 /* move it to the result */
5487 size = AOP_SIZE(result);
5489 /* get the msb and put it into the carry */
5490 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5497 emitpcode(POC_RLF, popGet(AOP(left),offset));
5499 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5500 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5507 freeAsmop(left,NULL,ic,TRUE);
5508 freeAsmop(result,NULL,ic,TRUE);
5511 /*-----------------------------------------------------------------*/
5512 /* genGetHbit - generates code get highest order bit */
5513 /*-----------------------------------------------------------------*/
5514 static void genGetHbit (iCode *ic)
5516 operand *left, *result;
5518 result=IC_RESULT(ic);
5519 aopOp (left,ic,FALSE);
5520 aopOp (result,ic,FALSE);
5522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5523 /* get the highest order byte into a */
5524 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5525 if(AOP_TYPE(result) == AOP_CRY){
5526 pic14_emitcode("rlc","a");
5527 pic14_outBitC(result);
5530 pic14_emitcode("rl","a");
5531 pic14_emitcode("anl","a,#0x01");
5532 pic14_outAcc(result);
5536 freeAsmop(left,NULL,ic,TRUE);
5537 freeAsmop(result,NULL,ic,TRUE);
5540 /*-----------------------------------------------------------------*/
5541 /* AccRol - rotate left accumulator by known count */
5542 /*-----------------------------------------------------------------*/
5543 static void AccRol (int shCount)
5545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5546 shCount &= 0x0007; // shCount : 0..7
5551 pic14_emitcode("rl","a");
5554 pic14_emitcode("rl","a");
5555 pic14_emitcode("rl","a");
5558 pic14_emitcode("swap","a");
5559 pic14_emitcode("rr","a");
5562 pic14_emitcode("swap","a");
5565 pic14_emitcode("swap","a");
5566 pic14_emitcode("rl","a");
5569 pic14_emitcode("rr","a");
5570 pic14_emitcode("rr","a");
5573 pic14_emitcode("rr","a");
5578 /*-----------------------------------------------------------------*/
5579 /* AccLsh - left shift accumulator by known count */
5580 /*-----------------------------------------------------------------*/
5581 static void AccLsh (int shCount)
5583 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5586 pic14_emitcode("add","a,acc");
5589 pic14_emitcode("add","a,acc");
5590 pic14_emitcode("add","a,acc");
5592 /* rotate left accumulator */
5594 /* and kill the lower order bits */
5595 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5600 /*-----------------------------------------------------------------*/
5601 /* AccRsh - right shift accumulator by known count */
5602 /*-----------------------------------------------------------------*/
5603 static void AccRsh (int shCount)
5605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5609 pic14_emitcode("rrc","a");
5611 /* rotate right accumulator */
5612 AccRol(8 - shCount);
5613 /* and kill the higher order bits */
5614 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5620 /*-----------------------------------------------------------------*/
5621 /* AccSRsh - signed right shift accumulator by known count */
5622 /*-----------------------------------------------------------------*/
5623 static void AccSRsh (int shCount)
5626 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5629 pic14_emitcode("mov","c,acc.7");
5630 pic14_emitcode("rrc","a");
5631 } else if(shCount == 2){
5632 pic14_emitcode("mov","c,acc.7");
5633 pic14_emitcode("rrc","a");
5634 pic14_emitcode("mov","c,acc.7");
5635 pic14_emitcode("rrc","a");
5637 tlbl = newiTempLabel(NULL);
5638 /* rotate right accumulator */
5639 AccRol(8 - shCount);
5640 /* and kill the higher order bits */
5641 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5642 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5643 pic14_emitcode("orl","a,#0x%02x",
5644 (unsigned char)~SRMask[shCount]);
5645 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5650 /*-----------------------------------------------------------------*/
5651 /* shiftR1Left2Result - shift right one byte from left to result */
5652 /*-----------------------------------------------------------------*/
5653 static void shiftR1Left2ResultSigned (operand *left, int offl,
5654 operand *result, int offr,
5659 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5661 same = (left == result) || (AOP(left) == AOP(result));
5665 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5667 emitpcode(POC_RRF, popGet(AOP(result),offr));
5669 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5670 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5680 /*-----------------------------------------------------------------*/
5681 /* shiftR1Left2Result - shift right one byte from left to result */
5682 /*-----------------------------------------------------------------*/
5683 static void shiftR1Left2Result (operand *left, int offl,
5684 operand *result, int offr,
5685 int shCount, int sign)
5689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5691 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5693 /* Copy the msb into the carry if signed. */
5695 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5705 emitpcode(POC_RRF, popGet(AOP(result),offr));
5707 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5708 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5714 emitpcode(POC_RRF, popGet(AOP(result),offr));
5716 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5717 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5720 emitpcode(POC_RRF, popGet(AOP(result),offr));
5725 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5727 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5728 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5731 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5732 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5733 emitpcode(POC_ANDLW, popGetLit(0x1f));
5734 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5738 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5739 emitpcode(POC_ANDLW, popGetLit(0x0f));
5740 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5744 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5745 emitpcode(POC_ANDLW, popGetLit(0x0f));
5746 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5748 emitpcode(POC_RRF, popGet(AOP(result),offr));
5753 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5754 emitpcode(POC_ANDLW, popGetLit(0x80));
5755 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5756 emitpcode(POC_RLF, popGet(AOP(result),offr));
5757 emitpcode(POC_RLF, popGet(AOP(result),offr));
5762 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5763 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5764 emitpcode(POC_RLF, popGet(AOP(result),offr));
5775 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5777 /* shift right accumulator */
5782 aopPut(AOP(result),"a",offr);
5786 /*-----------------------------------------------------------------*/
5787 /* shiftL1Left2Result - shift left one byte from left to result */
5788 /*-----------------------------------------------------------------*/
5789 static void shiftL1Left2Result (operand *left, int offl,
5790 operand *result, int offr, int shCount)
5795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5797 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5798 DEBUGpic14_emitcode ("; ***","same = %d",same);
5799 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5801 /* shift left accumulator */
5802 //AccLsh(shCount); // don't comment out just yet...
5803 // aopPut(AOP(result),"a",offr);
5807 /* Shift left 1 bit position */
5808 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5810 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
5812 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
5813 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5817 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5818 emitpcode(POC_ANDLW,popGetLit(0x7e));
5819 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5820 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5823 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5824 emitpcode(POC_ANDLW,popGetLit(0x3e));
5825 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5826 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5827 emitpcode(POC_RLF, popGet(AOP(result),offr));
5830 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5831 emitpcode(POC_ANDLW, popGetLit(0xf0));
5832 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5835 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5836 emitpcode(POC_ANDLW, popGetLit(0xf0));
5837 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5838 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5841 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5842 emitpcode(POC_ANDLW, popGetLit(0x30));
5843 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5844 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5845 emitpcode(POC_RLF, popGet(AOP(result),offr));
5848 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5849 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5850 emitpcode(POC_RRF, popGet(AOP(result),offr));
5854 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5859 /*-----------------------------------------------------------------*/
5860 /* movLeft2Result - move byte from left to result */
5861 /*-----------------------------------------------------------------*/
5862 static void movLeft2Result (operand *left, int offl,
5863 operand *result, int offr, int sign)
5866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5867 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5868 l = aopGet(AOP(left),offl,FALSE,FALSE);
5870 if (*l == '@' && (IS_AOP_PREG(result))) {
5871 pic14_emitcode("mov","a,%s",l);
5872 aopPut(AOP(result),"a",offr);
5875 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5876 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5878 //aopPut(AOP(result),l,offr);
5880 /* MSB sign in acc.7 ! */
5881 if(pic14_getDataSize(left) == offl+1){
5882 pic14_emitcode("mov","a,%s",l);
5883 aopPut(AOP(result),"a",offr);
5890 /*-----------------------------------------------------------------*/
5891 /* shiftL2Left2Result - shift left two bytes from left to result */
5892 /*-----------------------------------------------------------------*/
5893 static void shiftL2Left2Result (operand *left, int offl,
5894 operand *result, int offr, int shCount)
5898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5900 if(pic14_sameRegs(AOP(result), AOP(left))) {
5908 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
5909 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5910 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5914 emitpcode(POC_RLF, popGet(AOP(result),offr));
5915 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5921 emitpcode(POC_MOVLW, popGetLit(0x0f));
5922 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
5923 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
5924 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5925 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
5926 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5927 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5929 emitpcode(POC_RLF, popGet(AOP(result),offr));
5930 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5934 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5935 emitpcode(POC_RRF, popGet(AOP(result),offr));
5936 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5937 emitpcode(POC_RRF, popGet(AOP(result),offr));
5938 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5939 emitpcode(POC_ANDLW,popGetLit(0xc0));
5940 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5941 emitpcode(POC_XORWF,popGet(AOP(result),offr));
5942 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5943 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5946 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5947 emitpcode(POC_RRFW, popGet(AOP(result),offr));
5948 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5949 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5950 emitpcode(POC_RRF, popGet(AOP(result),offr));
5960 /* note, use a mov/add for the shift since the mov has a
5961 chance of getting optimized out */
5962 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5963 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5964 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
5965 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
5966 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5970 emitpcode(POC_RLF, popGet(AOP(result),offr));
5971 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5977 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
5978 emitpcode(POC_ANDLW, popGetLit(0xF0));
5979 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5980 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5981 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5982 emitpcode(POC_ANDLW, popGetLit(0xF0));
5983 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5984 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5988 emitpcode(POC_RLF, popGet(AOP(result),offr));
5989 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5993 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
5994 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5995 emitpcode(POC_RRFW, popGet(AOP(result),offl));
5996 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5998 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5999 emitpcode(POC_RRF, popGet(AOP(result),offr));
6000 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6001 emitpcode(POC_ANDLW,popGetLit(0xc0));
6002 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6003 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6004 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6005 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6008 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6009 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6010 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6011 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6012 emitpcode(POC_RRF, popGet(AOP(result),offr));
6017 /*-----------------------------------------------------------------*/
6018 /* shiftR2Left2Result - shift right two bytes from left to result */
6019 /*-----------------------------------------------------------------*/
6020 static void shiftR2Left2Result (operand *left, int offl,
6021 operand *result, int offr,
6022 int shCount, int sign)
6026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6027 same = pic14_sameRegs(AOP(result), AOP(left));
6029 if(same && ((offl + MSB16) == offr)){
6031 /* don't crash result[offr] */
6032 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6033 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6035 movLeft2Result(left,offl, result, offr, 0);
6036 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6038 /* a:x >> shCount (x = lsb(result))*/
6041 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6043 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6053 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6054 emitpcode(POC_RRF,popGet(AOP(result),offr));
6057 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6058 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6059 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6060 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6065 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6066 emitpcode(POC_RRF,popGet(AOP(result),offr));
6073 emitpcode(POC_MOVLW, popGetLit(0xf0));
6074 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6075 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6077 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6078 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6079 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6080 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6082 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6083 emitpcode(POC_ANDLW, popGetLit(0x0f));
6084 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6086 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6087 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6088 emitpcode(POC_ANDLW, popGetLit(0xf0));
6089 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6090 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6094 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6095 emitpcode(POC_RRF, popGet(AOP(result),offr));
6103 emitpcode(POC_RLF, popGet(AOP(result),offr));
6104 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6106 emitpcode(POC_RLF, popGet(AOP(result),offr));
6107 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6108 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6109 emitpcode(POC_ANDLW,popGetLit(0x03));
6110 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6111 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6112 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6113 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6115 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6116 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6117 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6118 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6119 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6120 emitpcode(POC_RLF, popGet(AOP(result),offr));
6121 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6122 emitpcode(POC_ANDLW,popGetLit(0x03));
6123 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6128 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6129 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6130 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6131 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6132 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6137 /*-----------------------------------------------------------------*/
6138 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6139 /*-----------------------------------------------------------------*/
6140 static void shiftLLeftOrResult (operand *left, int offl,
6141 operand *result, int offr, int shCount)
6143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6144 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6145 /* shift left accumulator */
6147 /* or with result */
6148 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6149 /* back to result */
6150 aopPut(AOP(result),"a",offr);
6153 /*-----------------------------------------------------------------*/
6154 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6155 /*-----------------------------------------------------------------*/
6156 static void shiftRLeftOrResult (operand *left, int offl,
6157 operand *result, int offr, int shCount)
6159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6160 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6161 /* shift right accumulator */
6163 /* or with result */
6164 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6165 /* back to result */
6166 aopPut(AOP(result),"a",offr);
6169 /*-----------------------------------------------------------------*/
6170 /* genlshOne - left shift a one byte quantity by known count */
6171 /*-----------------------------------------------------------------*/
6172 static void genlshOne (operand *result, operand *left, int shCount)
6174 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6175 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6178 /*-----------------------------------------------------------------*/
6179 /* genlshTwo - left shift two bytes by known amount != 0 */
6180 /*-----------------------------------------------------------------*/
6181 static void genlshTwo (operand *result,operand *left, int shCount)
6185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6186 size = pic14_getDataSize(result);
6188 /* if shCount >= 8 */
6194 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6196 movLeft2Result(left, LSB, result, MSB16, 0);
6198 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6201 /* 1 <= shCount <= 7 */
6204 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6206 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6210 /*-----------------------------------------------------------------*/
6211 /* shiftLLong - shift left one long from left to result */
6212 /* offl = LSB or MSB16 */
6213 /*-----------------------------------------------------------------*/
6214 static void shiftLLong (operand *left, operand *result, int offr )
6217 int size = AOP_SIZE(result);
6219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6220 if(size >= LSB+offr){
6221 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6223 pic14_emitcode("add","a,acc");
6224 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6225 size >= MSB16+offr && offr != LSB )
6226 pic14_emitcode("xch","a,%s",
6227 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6229 aopPut(AOP(result),"a",LSB+offr);
6232 if(size >= MSB16+offr){
6233 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6234 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6237 pic14_emitcode("rlc","a");
6238 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6239 size >= MSB24+offr && offr != LSB)
6240 pic14_emitcode("xch","a,%s",
6241 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6243 aopPut(AOP(result),"a",MSB16+offr);
6246 if(size >= MSB24+offr){
6247 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6248 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6251 pic14_emitcode("rlc","a");
6252 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6253 size >= MSB32+offr && offr != LSB )
6254 pic14_emitcode("xch","a,%s",
6255 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6257 aopPut(AOP(result),"a",MSB24+offr);
6260 if(size > MSB32+offr){
6261 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6262 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6265 pic14_emitcode("rlc","a");
6266 aopPut(AOP(result),"a",MSB32+offr);
6269 aopPut(AOP(result),zero,LSB);
6272 /*-----------------------------------------------------------------*/
6273 /* genlshFour - shift four byte by a known amount != 0 */
6274 /*-----------------------------------------------------------------*/
6275 static void genlshFour (operand *result, operand *left, int shCount)
6279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 size = AOP_SIZE(result);
6282 /* if shifting more that 3 bytes */
6283 if (shCount >= 24 ) {
6286 /* lowest order of left goes to the highest
6287 order of the destination */
6288 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6290 movLeft2Result(left, LSB, result, MSB32, 0);
6291 aopPut(AOP(result),zero,LSB);
6292 aopPut(AOP(result),zero,MSB16);
6293 aopPut(AOP(result),zero,MSB32);
6297 /* more than two bytes */
6298 else if ( shCount >= 16 ) {
6299 /* lower order two bytes goes to higher order two bytes */
6301 /* if some more remaining */
6303 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6305 movLeft2Result(left, MSB16, result, MSB32, 0);
6306 movLeft2Result(left, LSB, result, MSB24, 0);
6308 aopPut(AOP(result),zero,MSB16);
6309 aopPut(AOP(result),zero,LSB);
6313 /* if more than 1 byte */
6314 else if ( shCount >= 8 ) {
6315 /* lower order three bytes goes to higher order three bytes */
6319 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6321 movLeft2Result(left, LSB, result, MSB16, 0);
6323 else{ /* size = 4 */
6325 movLeft2Result(left, MSB24, result, MSB32, 0);
6326 movLeft2Result(left, MSB16, result, MSB24, 0);
6327 movLeft2Result(left, LSB, result, MSB16, 0);
6328 aopPut(AOP(result),zero,LSB);
6330 else if(shCount == 1)
6331 shiftLLong(left, result, MSB16);
6333 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6334 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6335 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6336 aopPut(AOP(result),zero,LSB);
6341 /* 1 <= shCount <= 7 */
6342 else if(shCount <= 2){
6343 shiftLLong(left, result, LSB);
6345 shiftLLong(result, result, LSB);
6347 /* 3 <= shCount <= 7, optimize */
6349 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6350 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6351 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6355 /*-----------------------------------------------------------------*/
6356 /* genLeftShiftLiteral - left shifting by known count */
6357 /*-----------------------------------------------------------------*/
6358 static void genLeftShiftLiteral (operand *left,
6363 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6367 freeAsmop(right,NULL,ic,TRUE);
6369 aopOp(left,ic,FALSE);
6370 aopOp(result,ic,FALSE);
6372 size = getSize(operandType(result));
6375 pic14_emitcode("; shift left ","result %d, left %d",size,
6379 /* I suppose that the left size >= result size */
6382 movLeft2Result(left, size, result, size, 0);
6386 else if(shCount >= (size * 8))
6388 aopPut(AOP(result),zero,size);
6392 genlshOne (result,left,shCount);
6397 genlshTwo (result,left,shCount);
6401 genlshFour (result,left,shCount);
6405 freeAsmop(left,NULL,ic,TRUE);
6406 freeAsmop(result,NULL,ic,TRUE);
6409 /*-----------------------------------------------------------------*/
6410 /* genLeftShift - generates code for left shifting */
6411 /*-----------------------------------------------------------------*/
6412 static void genLeftShift (iCode *ic)
6414 operand *left,*right, *result;
6417 symbol *tlbl , *tlbl1;
6419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6421 right = IC_RIGHT(ic);
6423 result = IC_RESULT(ic);
6425 aopOp(right,ic,FALSE);
6427 /* if the shift count is known then do it
6428 as efficiently as possible */
6429 if (AOP_TYPE(right) == AOP_LIT) {
6430 genLeftShiftLiteral (left,right,result,ic);
6434 /* shift count is unknown then we have to form
6435 a loop get the loop count in B : Note: we take
6436 only the lower order byte since shifting
6437 more that 32 bits make no sense anyway, ( the
6438 largest size of an object can be only 32 bits ) */
6441 aopOp(left,ic,FALSE);
6442 aopOp(result,ic,FALSE);
6444 /* now move the left to the result if they are not the
6446 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6447 AOP_SIZE(result) > 1) {
6449 size = AOP_SIZE(result);
6452 l = aopGet(AOP(left),offset,FALSE,TRUE);
6453 if (*l == '@' && (IS_AOP_PREG(result))) {
6455 pic14_emitcode("mov","a,%s",l);
6456 aopPut(AOP(result),"a",offset);
6458 aopPut(AOP(result),l,offset);
6463 size = AOP_SIZE(result);
6465 /* if it is only one byte then */
6467 if(optimized_for_speed) {
6468 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6469 emitpcode(POC_ANDLW, popGetLit(0xf0));
6470 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6471 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6472 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6473 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6474 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6475 emitpcode(POC_RLFW, popGet(AOP(result),0));
6476 emitpcode(POC_ANDLW, popGetLit(0xfe));
6477 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6478 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6479 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6482 tlbl = newiTempLabel(NULL);
6483 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6484 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6485 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6488 emitpcode(POC_COMFW, popGet(AOP(right),0));
6489 emitpcode(POC_RRF, popGet(AOP(result),0));
6490 emitpLabel(tlbl->key);
6491 emitpcode(POC_RLF, popGet(AOP(result),0));
6492 emitpcode(POC_ADDLW, popGetLit(1));
6494 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6500 tlbl = newiTempLabel(NULL);
6502 tlbl1 = newiTempLabel(NULL);
6504 reAdjustPreg(AOP(result));
6506 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6507 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6508 l = aopGet(AOP(result),offset,FALSE,FALSE);
6510 pic14_emitcode("add","a,acc");
6511 aopPut(AOP(result),"a",offset++);
6513 l = aopGet(AOP(result),offset,FALSE,FALSE);
6515 pic14_emitcode("rlc","a");
6516 aopPut(AOP(result),"a",offset++);
6518 reAdjustPreg(AOP(result));
6520 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6521 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6523 freeAsmop (right,NULL,ic,TRUE);
6524 freeAsmop(left,NULL,ic,TRUE);
6525 freeAsmop(result,NULL,ic,TRUE);
6528 /*-----------------------------------------------------------------*/
6529 /* genrshOne - right shift a one byte quantity by known count */
6530 /*-----------------------------------------------------------------*/
6531 static void genrshOne (operand *result, operand *left,
6532 int shCount, int sign)
6534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6535 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6538 /*-----------------------------------------------------------------*/
6539 /* genrshTwo - right shift two bytes by known amount != 0 */
6540 /*-----------------------------------------------------------------*/
6541 static void genrshTwo (operand *result,operand *left,
6542 int shCount, int sign)
6544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6545 /* if shCount >= 8 */
6549 shiftR1Left2Result(left, MSB16, result, LSB,
6552 movLeft2Result(left, MSB16, result, LSB, sign);
6554 addSign(result, MSB16, sign);
6556 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6560 /* 1 <= shCount <= 7 */
6562 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6565 /*-----------------------------------------------------------------*/
6566 /* shiftRLong - shift right one long from left to result */
6567 /* offl = LSB or MSB16 */
6568 /*-----------------------------------------------------------------*/
6569 static void shiftRLong (operand *left, int offl,
6570 operand *result, int sign)
6572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6574 pic14_emitcode("clr","c");
6575 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6577 pic14_emitcode("mov","c,acc.7");
6578 pic14_emitcode("rrc","a");
6579 aopPut(AOP(result),"a",MSB32-offl);
6581 /* add sign of "a" */
6582 addSign(result, MSB32, sign);
6584 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6585 pic14_emitcode("rrc","a");
6586 aopPut(AOP(result),"a",MSB24-offl);
6588 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6589 pic14_emitcode("rrc","a");
6590 aopPut(AOP(result),"a",MSB16-offl);
6593 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6594 pic14_emitcode("rrc","a");
6595 aopPut(AOP(result),"a",LSB);
6599 /*-----------------------------------------------------------------*/
6600 /* genrshFour - shift four byte by a known amount != 0 */
6601 /*-----------------------------------------------------------------*/
6602 static void genrshFour (operand *result, operand *left,
6603 int shCount, int sign)
6605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6606 /* if shifting more that 3 bytes */
6607 if(shCount >= 24 ) {
6610 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6612 movLeft2Result(left, MSB32, result, LSB, sign);
6613 addSign(result, MSB16, sign);
6615 else if(shCount >= 16){
6618 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6620 movLeft2Result(left, MSB24, result, LSB, 0);
6621 movLeft2Result(left, MSB32, result, MSB16, sign);
6623 addSign(result, MSB24, sign);
6625 else if(shCount >= 8){
6628 shiftRLong(left, MSB16, result, sign);
6629 else if(shCount == 0){
6630 movLeft2Result(left, MSB16, result, LSB, 0);
6631 movLeft2Result(left, MSB24, result, MSB16, 0);
6632 movLeft2Result(left, MSB32, result, MSB24, sign);
6633 addSign(result, MSB32, sign);
6636 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6637 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6638 /* the last shift is signed */
6639 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6640 addSign(result, MSB32, sign);
6643 else{ /* 1 <= shCount <= 7 */
6645 shiftRLong(left, LSB, result, sign);
6647 shiftRLong(result, LSB, result, sign);
6650 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6651 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6652 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6657 /*-----------------------------------------------------------------*/
6658 /* genRightShiftLiteral - right shifting by known count */
6659 /*-----------------------------------------------------------------*/
6660 static void genRightShiftLiteral (operand *left,
6666 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6670 freeAsmop(right,NULL,ic,TRUE);
6672 aopOp(left,ic,FALSE);
6673 aopOp(result,ic,FALSE);
6676 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6680 size = pic14_getDataSize(left);
6681 /* test the LEFT size !!! */
6683 /* I suppose that the left size >= result size */
6685 size = pic14_getDataSize(result);
6687 movLeft2Result(left, size, result, size, 0);
6690 else if(shCount >= (size * 8)){
6692 /* get sign in acc.7 */
6693 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6694 addSign(result, LSB, sign);
6698 genrshOne (result,left,shCount,sign);
6702 genrshTwo (result,left,shCount,sign);
6706 genrshFour (result,left,shCount,sign);
6712 freeAsmop(left,NULL,ic,TRUE);
6713 freeAsmop(result,NULL,ic,TRUE);
6717 /*-----------------------------------------------------------------*/
6718 /* genSignedRightShift - right shift of signed number */
6719 /*-----------------------------------------------------------------*/
6720 static void genSignedRightShift (iCode *ic)
6722 operand *right, *left, *result;
6725 symbol *tlbl, *tlbl1 ;
6727 /* we do it the hard way put the shift count in b
6728 and loop thru preserving the sign */
6729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6731 right = IC_RIGHT(ic);
6733 result = IC_RESULT(ic);
6735 aopOp(right,ic,FALSE);
6738 if ( AOP_TYPE(right) == AOP_LIT) {
6739 genRightShiftLiteral (left,right,result,ic,1);
6742 /* shift count is unknown then we have to form
6743 a loop get the loop count in B : Note: we take
6744 only the lower order byte since shifting
6745 more that 32 bits make no sense anyway, ( the
6746 largest size of an object can be only 32 bits ) */
6748 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6749 pic14_emitcode("inc","b");
6750 freeAsmop (right,NULL,ic,TRUE);
6751 aopOp(left,ic,FALSE);
6752 aopOp(result,ic,FALSE);
6754 /* now move the left to the result if they are not the
6756 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6757 AOP_SIZE(result) > 1) {
6759 size = AOP_SIZE(result);
6762 l = aopGet(AOP(left),offset,FALSE,TRUE);
6763 if (*l == '@' && IS_AOP_PREG(result)) {
6765 pic14_emitcode("mov","a,%s",l);
6766 aopPut(AOP(result),"a",offset);
6768 aopPut(AOP(result),l,offset);
6773 /* mov the highest order bit to OVR */
6774 tlbl = newiTempLabel(NULL);
6775 tlbl1= newiTempLabel(NULL);
6777 size = AOP_SIZE(result);
6779 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6780 pic14_emitcode("rlc","a");
6781 pic14_emitcode("mov","ov,c");
6782 /* if it is only one byte then */
6784 l = aopGet(AOP(left),0,FALSE,FALSE);
6786 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6787 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6788 pic14_emitcode("mov","c,ov");
6789 pic14_emitcode("rrc","a");
6790 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6791 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6792 aopPut(AOP(result),"a",0);
6796 reAdjustPreg(AOP(result));
6797 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6798 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6799 pic14_emitcode("mov","c,ov");
6801 l = aopGet(AOP(result),offset,FALSE,FALSE);
6803 pic14_emitcode("rrc","a");
6804 aopPut(AOP(result),"a",offset--);
6806 reAdjustPreg(AOP(result));
6807 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6808 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6811 freeAsmop(left,NULL,ic,TRUE);
6812 freeAsmop(result,NULL,ic,TRUE);
6815 /*-----------------------------------------------------------------*/
6816 /* genRightShift - generate code for right shifting */
6817 /*-----------------------------------------------------------------*/
6818 static void genRightShift (iCode *ic)
6820 operand *right, *left, *result;
6824 symbol *tlbl, *tlbl1 ;
6826 /* if signed then we do it the hard way preserve the
6827 sign bit moving it inwards */
6828 retype = getSpec(operandType(IC_RESULT(ic)));
6829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6831 if (!SPEC_USIGN(retype)) {
6832 genSignedRightShift (ic);
6836 /* signed & unsigned types are treated the same : i.e. the
6837 signed is NOT propagated inwards : quoting from the
6838 ANSI - standard : "for E1 >> E2, is equivalent to division
6839 by 2**E2 if unsigned or if it has a non-negative value,
6840 otherwise the result is implementation defined ", MY definition
6841 is that the sign does not get propagated */
6843 right = IC_RIGHT(ic);
6845 result = IC_RESULT(ic);
6847 aopOp(right,ic,FALSE);
6849 /* if the shift count is known then do it
6850 as efficiently as possible */
6851 if (AOP_TYPE(right) == AOP_LIT) {
6852 genRightShiftLiteral (left,right,result,ic, 0);
6856 /* shift count is unknown then we have to form
6857 a loop get the loop count in B : Note: we take
6858 only the lower order byte since shifting
6859 more that 32 bits make no sense anyway, ( the
6860 largest size of an object can be only 32 bits ) */
6862 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6863 pic14_emitcode("inc","b");
6864 aopOp(left,ic,FALSE);
6865 aopOp(result,ic,FALSE);
6867 /* now move the left to the result if they are not the
6869 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6870 AOP_SIZE(result) > 1) {
6872 size = AOP_SIZE(result);
6875 l = aopGet(AOP(left),offset,FALSE,TRUE);
6876 if (*l == '@' && IS_AOP_PREG(result)) {
6878 pic14_emitcode("mov","a,%s",l);
6879 aopPut(AOP(result),"a",offset);
6881 aopPut(AOP(result),l,offset);
6886 tlbl = newiTempLabel(NULL);
6887 tlbl1= newiTempLabel(NULL);
6888 size = AOP_SIZE(result);
6891 /* if it is only one byte then */
6894 l = aopGet(AOP(left),0,FALSE,FALSE);
6896 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6897 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6899 pic14_emitcode("rrc","a");
6900 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6901 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6902 aopPut(AOP(result),"a",0);
6904 tlbl = newiTempLabel(NULL);
6905 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6906 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6907 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6910 emitpcode(POC_COMFW, popGet(AOP(right),0));
6911 emitpcode(POC_RLF, popGet(AOP(result),0));
6912 emitpLabel(tlbl->key);
6913 emitpcode(POC_RRF, popGet(AOP(result),0));
6914 emitpcode(POC_ADDLW, popGetLit(1));
6916 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6921 reAdjustPreg(AOP(result));
6922 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6923 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6926 l = aopGet(AOP(result),offset,FALSE,FALSE);
6928 pic14_emitcode("rrc","a");
6929 aopPut(AOP(result),"a",offset--);
6931 reAdjustPreg(AOP(result));
6933 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6934 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6937 freeAsmop(left,NULL,ic,TRUE);
6938 freeAsmop (right,NULL,ic,TRUE);
6939 freeAsmop(result,NULL,ic,TRUE);
6942 /*-----------------------------------------------------------------*/
6943 /* genUnpackBits - generates code for unpacking bits */
6944 /*-----------------------------------------------------------------*/
6945 static void genUnpackBits (operand *result, char *rname, int ptype)
6952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6953 etype = getSpec(operandType(result));
6955 /* read the first byte */
6960 pic14_emitcode("mov","a,@%s",rname);
6964 pic14_emitcode("movx","a,@%s",rname);
6968 pic14_emitcode("movx","a,@dptr");
6972 pic14_emitcode("clr","a");
6973 pic14_emitcode("movc","a","@a+dptr");
6977 pic14_emitcode("lcall","__gptrget");
6981 /* if we have bitdisplacement then it fits */
6982 /* into this byte completely or if length is */
6983 /* less than a byte */
6984 if ((shCnt = SPEC_BSTR(etype)) ||
6985 (SPEC_BLEN(etype) <= 8)) {
6987 /* shift right acc */
6990 pic14_emitcode("anl","a,#0x%02x",
6991 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6992 aopPut(AOP(result),"a",offset);
6996 /* bit field did not fit in a byte */
6997 rlen = SPEC_BLEN(etype) - 8;
6998 aopPut(AOP(result),"a",offset++);
7005 pic14_emitcode("inc","%s",rname);
7006 pic14_emitcode("mov","a,@%s",rname);
7010 pic14_emitcode("inc","%s",rname);
7011 pic14_emitcode("movx","a,@%s",rname);
7015 pic14_emitcode("inc","dptr");
7016 pic14_emitcode("movx","a,@dptr");
7020 pic14_emitcode("clr","a");
7021 pic14_emitcode("inc","dptr");
7022 pic14_emitcode("movc","a","@a+dptr");
7026 pic14_emitcode("inc","dptr");
7027 pic14_emitcode("lcall","__gptrget");
7032 /* if we are done */
7036 aopPut(AOP(result),"a",offset++);
7041 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7042 aopPut(AOP(result),"a",offset);
7049 /*-----------------------------------------------------------------*/
7050 /* genDataPointerGet - generates code when ptr offset is known */
7051 /*-----------------------------------------------------------------*/
7052 static void genDataPointerGet (operand *left,
7056 int size , offset = 0;
7059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7062 /* optimization - most of the time, left and result are the same
7063 * address, but different types. for the pic code, we could omit
7067 aopOp(result,ic,TRUE);
7069 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7071 size = AOP_SIZE(result);
7074 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7078 freeAsmop(left,NULL,ic,TRUE);
7079 freeAsmop(result,NULL,ic,TRUE);
7082 /*-----------------------------------------------------------------*/
7083 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7084 /*-----------------------------------------------------------------*/
7085 static void genNearPointerGet (operand *left,
7092 sym_link *rtype, *retype;
7093 sym_link *ltype = operandType(left);
7096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7098 rtype = operandType(result);
7099 retype= getSpec(rtype);
7101 aopOp(left,ic,FALSE);
7103 /* if left is rematerialisable and
7104 result is not bit variable type and
7105 the left is pointer to data space i.e
7106 lower 128 bytes of space */
7107 if (AOP_TYPE(left) == AOP_IMMD &&
7108 !IS_BITVAR(retype) &&
7109 DCL_TYPE(ltype) == POINTER) {
7110 genDataPointerGet (left,result,ic);
7114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7116 /* if the value is already in a pointer register
7117 then don't need anything more */
7118 if (!AOP_INPREG(AOP(left))) {
7119 /* otherwise get a free pointer register */
7120 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7122 preg = getFreePtr(ic,&aop,FALSE);
7123 pic14_emitcode("mov","%s,%s",
7125 aopGet(AOP(left),0,FALSE,TRUE));
7126 rname = preg->name ;
7128 rname = aopGet(AOP(left),0,FALSE,FALSE);
7130 freeAsmop(left,NULL,ic,TRUE);
7131 aopOp (result,ic,FALSE);
7133 /* if bitfield then unpack the bits */
7134 if (IS_BITVAR(retype))
7135 genUnpackBits (result,rname,POINTER);
7137 /* we have can just get the values */
7138 int size = AOP_SIZE(result);
7141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7143 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7145 pic14_emitcode("mov","a,@%s",rname);
7146 aopPut(AOP(result),"a",offset);
7148 sprintf(buffer,"@%s",rname);
7149 aopPut(AOP(result),buffer,offset);
7153 pic14_emitcode("inc","%s",rname);
7157 /* now some housekeeping stuff */
7159 /* we had to allocate for this iCode */
7160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7161 freeAsmop(NULL,aop,ic,TRUE);
7163 /* we did not allocate which means left
7164 already in a pointer register, then
7165 if size > 0 && this could be used again
7166 we have to point it back to where it
7168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7169 if (AOP_SIZE(result) > 1 &&
7170 !OP_SYMBOL(left)->remat &&
7171 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7173 int size = AOP_SIZE(result) - 1;
7175 pic14_emitcode("dec","%s",rname);
7180 freeAsmop(result,NULL,ic,TRUE);
7184 /*-----------------------------------------------------------------*/
7185 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7186 /*-----------------------------------------------------------------*/
7187 static void genPagedPointerGet (operand *left,
7194 sym_link *rtype, *retype;
7196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7198 rtype = operandType(result);
7199 retype= getSpec(rtype);
7201 aopOp(left,ic,FALSE);
7203 /* if the value is already in a pointer register
7204 then don't need anything more */
7205 if (!AOP_INPREG(AOP(left))) {
7206 /* otherwise get a free pointer register */
7208 preg = getFreePtr(ic,&aop,FALSE);
7209 pic14_emitcode("mov","%s,%s",
7211 aopGet(AOP(left),0,FALSE,TRUE));
7212 rname = preg->name ;
7214 rname = aopGet(AOP(left),0,FALSE,FALSE);
7216 freeAsmop(left,NULL,ic,TRUE);
7217 aopOp (result,ic,FALSE);
7219 /* if bitfield then unpack the bits */
7220 if (IS_BITVAR(retype))
7221 genUnpackBits (result,rname,PPOINTER);
7223 /* we have can just get the values */
7224 int size = AOP_SIZE(result);
7229 pic14_emitcode("movx","a,@%s",rname);
7230 aopPut(AOP(result),"a",offset);
7235 pic14_emitcode("inc","%s",rname);
7239 /* now some housekeeping stuff */
7241 /* we had to allocate for this iCode */
7242 freeAsmop(NULL,aop,ic,TRUE);
7244 /* we did not allocate which means left
7245 already in a pointer register, then
7246 if size > 0 && this could be used again
7247 we have to point it back to where it
7249 if (AOP_SIZE(result) > 1 &&
7250 !OP_SYMBOL(left)->remat &&
7251 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7253 int size = AOP_SIZE(result) - 1;
7255 pic14_emitcode("dec","%s",rname);
7260 freeAsmop(result,NULL,ic,TRUE);
7265 /*-----------------------------------------------------------------*/
7266 /* genFarPointerGet - gget value from far space */
7267 /*-----------------------------------------------------------------*/
7268 static void genFarPointerGet (operand *left,
7269 operand *result, iCode *ic)
7272 sym_link *retype = getSpec(operandType(result));
7274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7276 aopOp(left,ic,FALSE);
7278 /* if the operand is already in dptr
7279 then we do nothing else we move the value to dptr */
7280 if (AOP_TYPE(left) != AOP_STR) {
7281 /* if this is remateriazable */
7282 if (AOP_TYPE(left) == AOP_IMMD)
7283 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7284 else { /* we need to get it byte by byte */
7285 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7286 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7287 if (options.model == MODEL_FLAT24)
7289 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7293 /* so dptr know contains the address */
7294 freeAsmop(left,NULL,ic,TRUE);
7295 aopOp(result,ic,FALSE);
7297 /* if bit then unpack */
7298 if (IS_BITVAR(retype))
7299 genUnpackBits(result,"dptr",FPOINTER);
7301 size = AOP_SIZE(result);
7305 pic14_emitcode("movx","a,@dptr");
7306 aopPut(AOP(result),"a",offset++);
7308 pic14_emitcode("inc","dptr");
7312 freeAsmop(result,NULL,ic,TRUE);
7315 /*-----------------------------------------------------------------*/
7316 /* pic14_emitcodePointerGet - gget value from code space */
7317 /*-----------------------------------------------------------------*/
7318 static void pic14_emitcodePointerGet (operand *left,
7319 operand *result, iCode *ic)
7322 sym_link *retype = getSpec(operandType(result));
7324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7326 aopOp(left,ic,FALSE);
7328 /* if the operand is already in dptr
7329 then we do nothing else we move the value to dptr */
7330 if (AOP_TYPE(left) != AOP_STR) {
7331 /* if this is remateriazable */
7332 if (AOP_TYPE(left) == AOP_IMMD)
7333 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7334 else { /* we need to get it byte by byte */
7335 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7336 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7337 if (options.model == MODEL_FLAT24)
7339 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7343 /* so dptr know contains the address */
7344 freeAsmop(left,NULL,ic,TRUE);
7345 aopOp(result,ic,FALSE);
7347 /* if bit then unpack */
7348 if (IS_BITVAR(retype))
7349 genUnpackBits(result,"dptr",CPOINTER);
7351 size = AOP_SIZE(result);
7355 pic14_emitcode("clr","a");
7356 pic14_emitcode("movc","a,@a+dptr");
7357 aopPut(AOP(result),"a",offset++);
7359 pic14_emitcode("inc","dptr");
7363 freeAsmop(result,NULL,ic,TRUE);
7366 /*-----------------------------------------------------------------*/
7367 /* genGenPointerGet - gget value from generic pointer space */
7368 /*-----------------------------------------------------------------*/
7369 static void genGenPointerGet (operand *left,
7370 operand *result, iCode *ic)
7373 sym_link *retype = getSpec(operandType(result));
7375 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7376 aopOp(left,ic,FALSE);
7377 aopOp(result,ic,FALSE);
7380 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7382 /* if the operand is already in dptr
7383 then we do nothing else we move the value to dptr */
7384 if (AOP_TYPE(left) != AOP_STR) {
7385 /* if this is remateriazable */
7386 if (AOP_TYPE(left) == AOP_IMMD) {
7387 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7388 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7390 else { /* we need to get it byte by byte */
7392 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7393 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7395 size = AOP_SIZE(result);
7399 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7400 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7402 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7407 /* so dptr know contains the address */
7409 /* if bit then unpack */
7410 if (IS_BITVAR(retype))
7411 genUnpackBits(result,"dptr",GPOINTER);
7414 freeAsmop(left,NULL,ic,TRUE);
7415 freeAsmop(result,NULL,ic,TRUE);
7419 /*-----------------------------------------------------------------*/
7420 /* genPointerGet - generate code for pointer get */
7421 /*-----------------------------------------------------------------*/
7422 static void genPointerGet (iCode *ic)
7424 operand *left, *result ;
7425 sym_link *type, *etype;
7428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7431 result = IC_RESULT(ic) ;
7433 /* depending on the type of pointer we need to
7434 move it to the correct pointer register */
7435 type = operandType(left);
7436 etype = getSpec(type);
7437 /* if left is of type of pointer then it is simple */
7438 if (IS_PTR(type) && !IS_FUNC(type->next))
7439 p_type = DCL_TYPE(type);
7441 /* we have to go by the storage class */
7442 p_type = PTR_TYPE(SPEC_OCLS(etype));
7444 /* if (SPEC_OCLS(etype)->codesp ) { */
7445 /* p_type = CPOINTER ; */
7448 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7449 /* p_type = FPOINTER ; */
7451 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7452 /* p_type = PPOINTER; */
7454 /* if (SPEC_OCLS(etype) == idata ) */
7455 /* p_type = IPOINTER; */
7457 /* p_type = POINTER ; */
7460 /* now that we have the pointer type we assign
7461 the pointer values */
7466 genNearPointerGet (left,result,ic);
7470 genPagedPointerGet(left,result,ic);
7474 genFarPointerGet (left,result,ic);
7478 pic14_emitcodePointerGet (left,result,ic);
7482 genGenPointerGet (left,result,ic);
7488 /*-----------------------------------------------------------------*/
7489 /* genPackBits - generates code for packed bit storage */
7490 /*-----------------------------------------------------------------*/
7491 static void genPackBits (sym_link *etype ,
7493 char *rname, int p_type)
7501 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7502 blen = SPEC_BLEN(etype);
7503 bstr = SPEC_BSTR(etype);
7505 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7508 /* if the bit lenth is less than or */
7509 /* it exactly fits a byte then */
7510 if (SPEC_BLEN(etype) <= 8 ) {
7511 shCount = SPEC_BSTR(etype) ;
7513 /* shift left acc */
7516 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7521 pic14_emitcode ("mov","b,a");
7522 pic14_emitcode("mov","a,@%s",rname);
7526 pic14_emitcode ("mov","b,a");
7527 pic14_emitcode("movx","a,@dptr");
7531 pic14_emitcode ("push","b");
7532 pic14_emitcode ("push","acc");
7533 pic14_emitcode ("lcall","__gptrget");
7534 pic14_emitcode ("pop","b");
7538 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7539 ((unsigned char)(0xFF << (blen+bstr)) |
7540 (unsigned char)(0xFF >> (8-bstr)) ) );
7541 pic14_emitcode ("orl","a,b");
7542 if (p_type == GPOINTER)
7543 pic14_emitcode("pop","b");
7549 pic14_emitcode("mov","@%s,a",rname);
7553 pic14_emitcode("movx","@dptr,a");
7557 DEBUGpic14_emitcode(";lcall","__gptrput");
7562 if ( SPEC_BLEN(etype) <= 8 )
7565 pic14_emitcode("inc","%s",rname);
7566 rLen = SPEC_BLEN(etype) ;
7568 /* now generate for lengths greater than one byte */
7571 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7581 pic14_emitcode("mov","@%s,a",rname);
7583 pic14_emitcode("mov","@%s,%s",rname,l);
7588 pic14_emitcode("movx","@dptr,a");
7593 DEBUGpic14_emitcode(";lcall","__gptrput");
7596 pic14_emitcode ("inc","%s",rname);
7601 /* last last was not complete */
7603 /* save the byte & read byte */
7606 pic14_emitcode ("mov","b,a");
7607 pic14_emitcode("mov","a,@%s",rname);
7611 pic14_emitcode ("mov","b,a");
7612 pic14_emitcode("movx","a,@dptr");
7616 pic14_emitcode ("push","b");
7617 pic14_emitcode ("push","acc");
7618 pic14_emitcode ("lcall","__gptrget");
7619 pic14_emitcode ("pop","b");
7623 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7624 pic14_emitcode ("orl","a,b");
7627 if (p_type == GPOINTER)
7628 pic14_emitcode("pop","b");
7633 pic14_emitcode("mov","@%s,a",rname);
7637 pic14_emitcode("movx","@dptr,a");
7641 DEBUGpic14_emitcode(";lcall","__gptrput");
7645 /*-----------------------------------------------------------------*/
7646 /* genDataPointerSet - remat pointer to data space */
7647 /*-----------------------------------------------------------------*/
7648 static void genDataPointerSet(operand *right,
7652 int size, offset = 0 ;
7653 char *l, buffer[256];
7655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7656 aopOp(right,ic,FALSE);
7658 l = aopGet(AOP(result),0,FALSE,TRUE);
7659 size = AOP_SIZE(right);
7660 // tsd, was l+1 - the underline `_' prefix was being stripped
7663 sprintf(buffer,"(%s + %d)",l,offset);
7665 sprintf(buffer,"%s",l);
7667 if (AOP_TYPE(right) == AOP_LIT) {
7668 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7669 lit = lit >> (8*offset);
7671 pic14_emitcode("movlw","%d",lit);
7672 pic14_emitcode("movwf","%s",buffer);
7674 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7675 emitpcode(POC_MOVWF, popRegFromString(buffer));
7678 pic14_emitcode("clrf","%s",buffer);
7679 emitpcode(POC_CLRF, popRegFromString(buffer));
7682 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7683 pic14_emitcode("movwf","%s",buffer);
7685 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7686 emitpcode(POC_MOVWF, popRegFromString(buffer));
7693 freeAsmop(right,NULL,ic,TRUE);
7694 freeAsmop(result,NULL,ic,TRUE);
7697 /*-----------------------------------------------------------------*/
7698 /* genNearPointerSet - pic14_emitcode for near pointer put */
7699 /*-----------------------------------------------------------------*/
7700 static void genNearPointerSet (operand *right,
7707 sym_link *ptype = operandType(result);
7710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7711 retype= getSpec(operandType(right));
7713 aopOp(result,ic,FALSE);
7715 /* if the result is rematerializable &
7716 in data space & not a bit variable */
7717 if (AOP_TYPE(result) == AOP_IMMD &&
7718 DCL_TYPE(ptype) == POINTER &&
7719 !IS_BITVAR(retype)) {
7720 genDataPointerSet (right,result,ic);
7724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7726 /* if the value is already in a pointer register
7727 then don't need anything more */
7728 if (!AOP_INPREG(AOP(result))) {
7729 /* otherwise get a free pointer register */
7730 //aop = newAsmop(0);
7731 //preg = getFreePtr(ic,&aop,FALSE);
7732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7733 //pic14_emitcode("mov","%s,%s",
7735 // aopGet(AOP(result),0,FALSE,TRUE));
7736 //rname = preg->name ;
7737 pic14_emitcode("movwf","fsr");
7739 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7741 freeAsmop(result,NULL,ic,TRUE);
7742 aopOp (right,ic,FALSE);
7743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7745 /* if bitfield then unpack the bits */
7746 if (IS_BITVAR(retype)) {
7747 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7748 "The programmer is obviously confused");
7749 //genPackBits (retype,right,rname,POINTER);
7753 /* we have can just get the values */
7754 int size = AOP_SIZE(right);
7757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7759 l = aopGet(AOP(right),offset,FALSE,TRUE);
7762 //pic14_emitcode("mov","@%s,a",rname);
7763 pic14_emitcode("movf","indf,w ;1");
7766 if (AOP_TYPE(right) == AOP_LIT) {
7767 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7769 pic14_emitcode("movlw","%s",l);
7770 pic14_emitcode("movwf","indf ;2");
7772 pic14_emitcode("clrf","indf");
7774 pic14_emitcode("movf","%s,w",l);
7775 pic14_emitcode("movwf","indf ;2");
7777 //pic14_emitcode("mov","@%s,%s",rname,l);
7780 pic14_emitcode("incf","fsr,f ;3");
7781 //pic14_emitcode("inc","%s",rname);
7786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7787 /* now some housekeeping stuff */
7789 /* we had to allocate for this iCode */
7790 freeAsmop(NULL,aop,ic,TRUE);
7792 /* we did not allocate which means left
7793 already in a pointer register, then
7794 if size > 0 && this could be used again
7795 we have to point it back to where it
7797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7798 if (AOP_SIZE(right) > 1 &&
7799 !OP_SYMBOL(result)->remat &&
7800 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7802 int size = AOP_SIZE(right) - 1;
7804 pic14_emitcode("decf","fsr,f");
7805 //pic14_emitcode("dec","%s",rname);
7809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7811 freeAsmop(right,NULL,ic,TRUE);
7816 /*-----------------------------------------------------------------*/
7817 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7818 /*-----------------------------------------------------------------*/
7819 static void genPagedPointerSet (operand *right,
7828 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7830 retype= getSpec(operandType(right));
7832 aopOp(result,ic,FALSE);
7834 /* if the value is already in a pointer register
7835 then don't need anything more */
7836 if (!AOP_INPREG(AOP(result))) {
7837 /* otherwise get a free pointer register */
7839 preg = getFreePtr(ic,&aop,FALSE);
7840 pic14_emitcode("mov","%s,%s",
7842 aopGet(AOP(result),0,FALSE,TRUE));
7843 rname = preg->name ;
7845 rname = aopGet(AOP(result),0,FALSE,FALSE);
7847 freeAsmop(result,NULL,ic,TRUE);
7848 aopOp (right,ic,FALSE);
7850 /* if bitfield then unpack the bits */
7851 if (IS_BITVAR(retype))
7852 genPackBits (retype,right,rname,PPOINTER);
7854 /* we have can just get the values */
7855 int size = AOP_SIZE(right);
7859 l = aopGet(AOP(right),offset,FALSE,TRUE);
7862 pic14_emitcode("movx","@%s,a",rname);
7865 pic14_emitcode("inc","%s",rname);
7871 /* now some housekeeping stuff */
7873 /* we had to allocate for this iCode */
7874 freeAsmop(NULL,aop,ic,TRUE);
7876 /* we did not allocate which means left
7877 already in a pointer register, then
7878 if size > 0 && this could be used again
7879 we have to point it back to where it
7881 if (AOP_SIZE(right) > 1 &&
7882 !OP_SYMBOL(result)->remat &&
7883 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7885 int size = AOP_SIZE(right) - 1;
7887 pic14_emitcode("dec","%s",rname);
7892 freeAsmop(right,NULL,ic,TRUE);
7897 /*-----------------------------------------------------------------*/
7898 /* genFarPointerSet - set value from far space */
7899 /*-----------------------------------------------------------------*/
7900 static void genFarPointerSet (operand *right,
7901 operand *result, iCode *ic)
7904 sym_link *retype = getSpec(operandType(right));
7906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7907 aopOp(result,ic,FALSE);
7909 /* if the operand is already in dptr
7910 then we do nothing else we move the value to dptr */
7911 if (AOP_TYPE(result) != AOP_STR) {
7912 /* if this is remateriazable */
7913 if (AOP_TYPE(result) == AOP_IMMD)
7914 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7915 else { /* we need to get it byte by byte */
7916 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7917 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7918 if (options.model == MODEL_FLAT24)
7920 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7924 /* so dptr know contains the address */
7925 freeAsmop(result,NULL,ic,TRUE);
7926 aopOp(right,ic,FALSE);
7928 /* if bit then unpack */
7929 if (IS_BITVAR(retype))
7930 genPackBits(retype,right,"dptr",FPOINTER);
7932 size = AOP_SIZE(right);
7936 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7938 pic14_emitcode("movx","@dptr,a");
7940 pic14_emitcode("inc","dptr");
7944 freeAsmop(right,NULL,ic,TRUE);
7947 /*-----------------------------------------------------------------*/
7948 /* genGenPointerSet - set value from generic pointer space */
7949 /*-----------------------------------------------------------------*/
7950 static void genGenPointerSet (operand *right,
7951 operand *result, iCode *ic)
7954 sym_link *retype = getSpec(operandType(right));
7956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 aopOp(result,ic,FALSE);
7959 aopOp(right,ic,FALSE);
7960 size = AOP_SIZE(right);
7962 DEBUGpic14_AopType(__LINE__,NULL,right,result);
7964 /* if the operand is already in dptr
7965 then we do nothing else we move the value to dptr */
7966 if (AOP_TYPE(result) != AOP_STR) {
7967 /* if this is remateriazable */
7968 if (AOP_TYPE(result) == AOP_IMMD) {
7969 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7970 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7972 else { /* we need to get it byte by byte */
7973 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
7974 size = AOP_SIZE(right);
7977 /* hack hack! see if this the FSR. If so don't load W */
7978 if(AOP_TYPE(right) != AOP_ACC) {
7980 emitpcode(POC_MOVFW,popGet(AOP(result),0));
7981 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7984 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
7986 // emitpcode(POC_MOVLW,popGetLit(0xfd));
7987 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
7991 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
7992 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7995 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8002 if(aopIdx(AOP(result),0) != 4) {
8004 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8008 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8013 /* so dptr know contains the address */
8016 /* if bit then unpack */
8017 if (IS_BITVAR(retype))
8018 genPackBits(retype,right,"dptr",GPOINTER);
8020 size = AOP_SIZE(right);
8024 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8026 pic14_emitcode("incf","fsr,f");
8027 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8028 pic14_emitcode("movwf","indf");
8030 //DEBUGpic14_emitcode(";lcall","__gptrput");
8032 // pic14_emitcode("inc","dptr");
8037 freeAsmop(right,NULL,ic,TRUE);
8038 freeAsmop(result,NULL,ic,TRUE);
8041 /*-----------------------------------------------------------------*/
8042 /* genPointerSet - stores the value into a pointer location */
8043 /*-----------------------------------------------------------------*/
8044 static void genPointerSet (iCode *ic)
8046 operand *right, *result ;
8047 sym_link *type, *etype;
8050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8052 right = IC_RIGHT(ic);
8053 result = IC_RESULT(ic) ;
8055 /* depending on the type of pointer we need to
8056 move it to the correct pointer register */
8057 type = operandType(result);
8058 etype = getSpec(type);
8059 /* if left is of type of pointer then it is simple */
8060 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8061 p_type = DCL_TYPE(type);
8064 /* we have to go by the storage class */
8065 p_type = PTR_TYPE(SPEC_OCLS(etype));
8067 /* if (SPEC_OCLS(etype)->codesp ) { */
8068 /* p_type = CPOINTER ; */
8071 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8072 /* p_type = FPOINTER ; */
8074 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8075 /* p_type = PPOINTER ; */
8077 /* if (SPEC_OCLS(etype) == idata ) */
8078 /* p_type = IPOINTER ; */
8080 /* p_type = POINTER ; */
8083 /* now that we have the pointer type we assign
8084 the pointer values */
8089 genNearPointerSet (right,result,ic);
8093 genPagedPointerSet (right,result,ic);
8097 genFarPointerSet (right,result,ic);
8101 genGenPointerSet (right,result,ic);
8107 /*-----------------------------------------------------------------*/
8108 /* genIfx - generate code for Ifx statement */
8109 /*-----------------------------------------------------------------*/
8110 static void genIfx (iCode *ic, iCode *popIc)
8112 operand *cond = IC_COND(ic);
8115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8117 aopOp(cond,ic,FALSE);
8119 /* get the value into acc */
8120 if (AOP_TYPE(cond) != AOP_CRY)
8121 pic14_toBoolean(cond);
8124 /* the result is now in the accumulator */
8125 freeAsmop(cond,NULL,ic,TRUE);
8127 /* if there was something to be popped then do it */
8131 /* if the condition is a bit variable */
8132 if (isbit && IS_ITEMP(cond) &&
8134 genIfxJump(ic,SPIL_LOC(cond)->rname);
8135 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8138 if (isbit && !IS_ITEMP(cond))
8139 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8147 /*-----------------------------------------------------------------*/
8148 /* genAddrOf - generates code for address of */
8149 /*-----------------------------------------------------------------*/
8150 static void genAddrOf (iCode *ic)
8152 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8153 operand *right, *result, *left;
8154 //int size, offset ;
8156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 //aopOp(IC_RESULT(ic),ic,FALSE);
8161 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8162 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8163 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8165 DEBUGpic14_AopType(__LINE__,left,right,result);
8167 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8168 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8171 /* object not on stack then we need the name */
8172 size = AOP_SIZE(IC_RESULT(ic));
8176 char s[SDCC_NAME_MAX];
8178 sprintf(s,"#(%s >> %d)",
8182 sprintf(s,"#%s",sym->rname);
8183 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8188 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8189 freeAsmop(left,NULL,ic,FALSE);
8190 freeAsmop(result,NULL,ic,TRUE);
8195 /*-----------------------------------------------------------------*/
8196 /* genFarFarAssign - assignment when both are in far space */
8197 /*-----------------------------------------------------------------*/
8198 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8200 int size = AOP_SIZE(right);
8203 /* first push the right side on to the stack */
8205 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8207 pic14_emitcode ("push","acc");
8210 freeAsmop(right,NULL,ic,FALSE);
8211 /* now assign DPTR to result */
8212 aopOp(result,ic,FALSE);
8213 size = AOP_SIZE(result);
8215 pic14_emitcode ("pop","acc");
8216 aopPut(AOP(result),"a",--offset);
8218 freeAsmop(result,NULL,ic,FALSE);
8223 /*-----------------------------------------------------------------*/
8224 /* genAssign - generate code for assignment */
8225 /*-----------------------------------------------------------------*/
8226 static void genAssign (iCode *ic)
8228 operand *result, *right;
8229 int size, offset,know_W;
8230 unsigned long lit = 0L;
8232 result = IC_RESULT(ic);
8233 right = IC_RIGHT(ic) ;
8235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8237 /* if they are the same */
8238 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8241 aopOp(right,ic,FALSE);
8242 aopOp(result,ic,TRUE);
8244 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8246 /* if they are the same registers */
8247 if (pic14_sameRegs(AOP(right),AOP(result)))
8250 /* if the result is a bit */
8251 if (AOP_TYPE(result) == AOP_CRY) {
8253 /* if the right size is a literal then
8254 we know what the value is */
8255 if (AOP_TYPE(right) == AOP_LIT) {
8257 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8258 popGet(AOP(result),0));
8260 if (((int) operandLitValue(right)))
8261 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8262 AOP(result)->aopu.aop_dir,
8263 AOP(result)->aopu.aop_dir);
8265 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8266 AOP(result)->aopu.aop_dir,
8267 AOP(result)->aopu.aop_dir);
8271 /* the right is also a bit variable */
8272 if (AOP_TYPE(right) == AOP_CRY) {
8273 emitpcode(POC_BCF, popGet(AOP(result),0));
8274 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8275 emitpcode(POC_BSF, popGet(AOP(result),0));
8277 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8278 AOP(result)->aopu.aop_dir,
8279 AOP(result)->aopu.aop_dir);
8280 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8281 AOP(right)->aopu.aop_dir,
8282 AOP(right)->aopu.aop_dir);
8283 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8284 AOP(result)->aopu.aop_dir,
8285 AOP(result)->aopu.aop_dir);
8290 emitpcode(POC_BCF, popGet(AOP(result),0));
8291 pic14_toBoolean(right);
8293 emitpcode(POC_BSF, popGet(AOP(result),0));
8294 //aopPut(AOP(result),"a",0);
8298 /* bit variables done */
8300 size = AOP_SIZE(result);
8302 if(AOP_TYPE(right) == AOP_LIT)
8303 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8305 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8307 if(aopIdx(AOP(result),0) == 4) {
8308 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8309 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8310 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8313 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8319 if(AOP_TYPE(right) == AOP_LIT) {
8321 if(know_W != (lit&0xff))
8322 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8324 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8326 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8330 } else if (AOP_TYPE(right) == AOP_CRY) {
8331 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8333 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8334 emitpcode(POC_INCF, popGet(AOP(result),0));
8337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8338 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8339 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8347 freeAsmop (right,NULL,ic,FALSE);
8348 freeAsmop (result,NULL,ic,TRUE);
8351 /*-----------------------------------------------------------------*/
8352 /* genJumpTab - genrates code for jump table */
8353 /*-----------------------------------------------------------------*/
8354 static void genJumpTab (iCode *ic)
8359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8361 aopOp(IC_JTCOND(ic),ic,FALSE);
8362 /* get the condition into accumulator */
8363 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8365 /* multiply by three */
8366 pic14_emitcode("add","a,acc");
8367 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8369 jtab = newiTempLabel(NULL);
8370 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8371 pic14_emitcode("jmp","@a+dptr");
8372 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8374 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8375 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8377 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8378 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8379 emitpLabel(jtab->key);
8381 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8383 /* now generate the jump labels */
8384 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8385 jtab = setNextItem(IC_JTLABELS(ic))) {
8386 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8387 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8393 /*-----------------------------------------------------------------*/
8394 /* genMixedOperation - gen code for operators between mixed types */
8395 /*-----------------------------------------------------------------*/
8397 TSD - Written for the PIC port - but this unfortunately is buggy.
8398 This routine is good in that it is able to efficiently promote
8399 types to different (larger) sizes. Unfortunately, the temporary
8400 variables that are optimized out by this routine are sometimes
8401 used in other places. So until I know how to really parse the
8402 iCode tree, I'm going to not be using this routine :(.
8404 static int genMixedOperation (iCode *ic)
8407 operand *result = IC_RESULT(ic);
8408 sym_link *ctype = operandType(IC_LEFT(ic));
8409 operand *right = IC_RIGHT(ic);
8415 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8417 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8423 nextright = IC_RIGHT(nextic);
8424 nextleft = IC_LEFT(nextic);
8425 nextresult = IC_RESULT(nextic);
8427 aopOp(right,ic,FALSE);
8428 aopOp(result,ic,FALSE);
8429 aopOp(nextright, nextic, FALSE);
8430 aopOp(nextleft, nextic, FALSE);
8431 aopOp(nextresult, nextic, FALSE);
8433 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8439 pic14_emitcode(";remove right +","");
8441 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8447 pic14_emitcode(";remove left +","");
8451 big = AOP_SIZE(nextleft);
8452 small = AOP_SIZE(nextright);
8454 switch(nextic->op) {
8457 pic14_emitcode(";optimize a +","");
8458 /* if unsigned or not an integral type */
8459 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8460 pic14_emitcode(";add a bit to something","");
8463 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8465 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8466 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8467 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8469 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8477 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8478 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8479 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8482 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8484 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8485 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8486 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8487 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8488 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8491 pic14_emitcode("rlf","known_zero,w");
8498 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8499 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8500 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8502 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8512 freeAsmop(right,NULL,ic,TRUE);
8513 freeAsmop(result,NULL,ic,TRUE);
8514 freeAsmop(nextright,NULL,ic,TRUE);
8515 freeAsmop(nextleft,NULL,ic,TRUE);
8517 nextic->generated = 1;
8524 /*-----------------------------------------------------------------*/
8525 /* genCast - gen code for casting */
8526 /*-----------------------------------------------------------------*/
8527 static void genCast (iCode *ic)
8529 operand *result = IC_RESULT(ic);
8530 sym_link *ctype = operandType(IC_LEFT(ic));
8531 operand *right = IC_RIGHT(ic);
8534 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8535 /* if they are equivalent then do nothing */
8536 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8539 aopOp(right,ic,FALSE) ;
8540 aopOp(result,ic,FALSE);
8542 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8544 /* if the result is a bit */
8545 if (AOP_TYPE(result) == AOP_CRY) {
8546 /* if the right size is a literal then
8547 we know what the value is */
8548 if (AOP_TYPE(right) == AOP_LIT) {
8550 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8551 popGet(AOP(result),0));
8553 if (((int) operandLitValue(right)))
8554 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8555 AOP(result)->aopu.aop_dir,
8556 AOP(result)->aopu.aop_dir);
8558 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8559 AOP(result)->aopu.aop_dir,
8560 AOP(result)->aopu.aop_dir);
8565 /* the right is also a bit variable */
8566 if (AOP_TYPE(right) == AOP_CRY) {
8569 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8571 pic14_emitcode("clrc","");
8572 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8573 AOP(right)->aopu.aop_dir,
8574 AOP(right)->aopu.aop_dir);
8575 aopPut(AOP(result),"c",0);
8580 if (AOP_TYPE(right) == AOP_REG) {
8581 emitpcode(POC_BCF, popGet(AOP(result),0));
8582 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8583 emitpcode(POC_BSF, popGet(AOP(result),0));
8585 pic14_toBoolean(right);
8586 aopPut(AOP(result),"a",0);
8590 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8592 size = AOP_SIZE(result);
8594 emitpcode(POC_CLRF, popGet(AOP(result),0));
8595 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8596 emitpcode(POC_INCF, popGet(AOP(result),0));
8599 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8604 /* if they are the same size : or less */
8605 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8607 /* if they are in the same place */
8608 if (pic14_sameRegs(AOP(right),AOP(result)))
8611 /* if they in different places then copy */
8612 size = AOP_SIZE(result);
8616 aopGet(AOP(right),offset,FALSE,FALSE),
8624 /* if the result is of type pointer */
8625 if (IS_PTR(ctype)) {
8628 sym_link *type = operandType(right);
8629 sym_link *etype = getSpec(type);
8631 /* pointer to generic pointer */
8632 if (IS_GENPTR(ctype)) {
8636 p_type = DCL_TYPE(type);
8638 /* we have to go by the storage class */
8639 p_type = PTR_TYPE(SPEC_OCLS(etype));
8641 /* if (SPEC_OCLS(etype)->codesp ) */
8642 /* p_type = CPOINTER ; */
8644 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8645 /* p_type = FPOINTER ; */
8647 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8648 /* p_type = PPOINTER; */
8650 /* if (SPEC_OCLS(etype) == idata ) */
8651 /* p_type = IPOINTER ; */
8653 /* p_type = POINTER ; */
8656 /* the first two bytes are known */
8657 size = GPTRSIZE - 1;
8661 aopGet(AOP(right),offset,FALSE,FALSE),
8665 /* the last byte depending on type */
8682 /* this should never happen */
8683 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8684 "got unknown pointer type");
8687 aopPut(AOP(result),l, GPTRSIZE - 1);
8691 /* just copy the pointers */
8692 size = AOP_SIZE(result);
8696 aopGet(AOP(right),offset,FALSE,FALSE),
8705 /* so we now know that the size of destination is greater
8706 than the size of the source.
8707 Now, if the next iCode is an operator then we might be
8708 able to optimize the operation without performing a cast.
8710 if(genMixedOperation(ic))
8714 /* we move to result for the size of source */
8715 size = AOP_SIZE(right);
8718 pic14_emitcode(";","%d",__LINE__);
8719 /* aopPut(AOP(result),
8720 aopGet(AOP(right),offset,FALSE,FALSE),
8722 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8723 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8727 /* now depending on the sign of the destination */
8728 size = AOP_SIZE(result) - AOP_SIZE(right);
8729 /* if unsigned or not an integral type */
8730 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8732 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8733 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8737 /* we need to extend the sign :{ */
8739 emitpcodeNULLop(POC_CLRW);
8742 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8744 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8746 emitpcode(POC_MOVLW, popGetLit(0xff));
8748 pic14_emitcode("clrw","");
8749 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8750 AOP(right)->aopu.aop_dir,
8751 AOP(right)->aopu.aop_dir);
8752 pic14_emitcode("movlw","0xff");
8754 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8755 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8757 // aopPut(AOP(result),"a",offset++);
8762 /* we are done hurray !!!! */
8765 freeAsmop(right,NULL,ic,TRUE);
8766 freeAsmop(result,NULL,ic,TRUE);
8770 /*-----------------------------------------------------------------*/
8771 /* genDjnz - generate decrement & jump if not zero instrucion */
8772 /*-----------------------------------------------------------------*/
8773 static int genDjnz (iCode *ic, iCode *ifx)
8776 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8781 /* if the if condition has a false label
8782 then we cannot save */
8786 /* if the minus is not of the form
8788 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8789 !IS_OP_LITERAL(IC_RIGHT(ic)))
8792 if (operandLitValue(IC_RIGHT(ic)) != 1)
8795 /* if the size of this greater than one then no
8797 if (getSize(operandType(IC_RESULT(ic))) > 1)
8800 /* otherwise we can save BIG */
8801 lbl = newiTempLabel(NULL);
8802 lbl1= newiTempLabel(NULL);
8804 aopOp(IC_RESULT(ic),ic,FALSE);
8806 if (IS_AOP_PREG(IC_RESULT(ic))) {
8807 pic14_emitcode("dec","%s",
8808 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8809 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8810 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8814 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
8815 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8817 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8818 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8821 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8822 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8823 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8824 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8827 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8832 /*-----------------------------------------------------------------*/
8833 /* genReceive - generate code for a receive iCode */
8834 /*-----------------------------------------------------------------*/
8835 static void genReceive (iCode *ic)
8837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8839 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8840 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8841 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8843 int size = getSize(operandType(IC_RESULT(ic)));
8844 int offset = fReturnSizePic - size;
8846 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8847 fReturn[fReturnSizePic - offset - 1] : "acc"));
8850 aopOp(IC_RESULT(ic),ic,FALSE);
8851 size = AOP_SIZE(IC_RESULT(ic));
8854 pic14_emitcode ("pop","acc");
8855 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8860 aopOp(IC_RESULT(ic),ic,FALSE);
8862 assignResultValue(IC_RESULT(ic));
8865 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8868 /*-----------------------------------------------------------------*/
8869 /* genpic14Code - generate code for pic14 based controllers */
8870 /*-----------------------------------------------------------------*/
8872 * At this point, ralloc.c has gone through the iCode and attempted
8873 * to optimize in a way suitable for a PIC. Now we've got to generate
8874 * PIC instructions that correspond to the iCode.
8876 * Once the instructions are generated, we'll pass through both the
8877 * peep hole optimizer and the pCode optimizer.
8878 *-----------------------------------------------------------------*/
8880 void genpic14Code (iCode *lic)
8885 lineHead = lineCurr = NULL;
8887 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8890 /* if debug information required */
8891 /* if (options.debug && currFunc) { */
8893 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8895 if (IS_STATIC(currFunc->etype)) {
8896 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8897 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8899 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8900 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8906 for (ic = lic ; ic ; ic = ic->next ) {
8908 DEBUGpic14_emitcode(";ic","");
8909 if ( cln != ic->lineno ) {
8910 if ( options.debug ) {
8912 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8913 FileBaseName(ic->filename),ic->lineno,
8914 ic->level,ic->block);
8917 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
8920 /* if the result is marked as
8921 spilt and rematerializable or code for
8922 this has already been generated then
8924 if (resultRemat(ic) || ic->generated )
8927 /* depending on the operation */
8946 /* IPOP happens only when trying to restore a
8947 spilt live range, if there is an ifx statement
8948 following this pop then the if statement might
8949 be using some of the registers being popped which
8950 would destory the contents of the register so
8951 we need to check for this condition and handle it */
8953 ic->next->op == IFX &&
8954 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8955 genIfx (ic->next,ic);
8973 genEndFunction (ic);
8993 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9010 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9014 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9021 /* note these two are xlated by algebraic equivalence
9022 during parsing SDCC.y */
9023 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9024 "got '>=' or '<=' shouldn't have come here");
9028 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9040 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9044 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9048 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9075 case GET_VALUE_AT_ADDRESS:
9080 if (POINTER_SET(ic))
9107 addSet(&_G.sendSet,ic);
9116 /* now we are ready to call the
9117 peep hole optimizer */
9118 if (!options.nopeep) {
9119 printf("peep hole optimizing\n");
9120 peepHole (&lineHead);
9122 /* now do the actual printing */
9123 printLine (lineHead,codeOutFile);
9125 printf("printing pBlock\n\n");
9126 printpBlock(stdout,pb);