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 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
784 sym->aop = op->aop = aop =
785 aopForSym(ic,sym->usl.spillLoc,result);
786 aop->size = getSize(sym->type);
790 /* must be in a register */
791 sym->aop = op->aop = aop = newAsmop(AOP_REG);
792 aop->size = sym->nRegs;
793 for ( i = 0 ; i < sym->nRegs ;i++)
794 aop->aopu.aop_reg[i] = sym->regs[i];
797 /*-----------------------------------------------------------------*/
798 /* freeAsmop - free up the asmop given to an operand */
799 /*----------------------------------------------------------------*/
800 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
817 /* depending on the asmop type only three cases need work AOP_RO
818 , AOP_R1 && AOP_STK */
824 pic14_emitcode ("pop","ar0");
828 bitVectUnSetBit(ic->rUsed,R0_IDX);
834 pic14_emitcode ("pop","ar1");
838 bitVectUnSetBit(ic->rUsed,R1_IDX);
844 int stk = aop->aopu.aop_stk + aop->size;
845 bitVectUnSetBit(ic->rUsed,R0_IDX);
846 bitVectUnSetBit(ic->rUsed,R1_IDX);
848 getFreePtr(ic,&aop,FALSE);
850 if (options.stack10bit)
852 /* I'm not sure what to do here yet... */
855 "*** Warning: probably generating bad code for "
856 "10 bit stack mode.\n");
860 pic14_emitcode ("mov","a,_bp");
861 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
862 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
864 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
868 pic14_emitcode("pop","acc");
869 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
871 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
874 freeAsmop(op,NULL,ic,TRUE);
876 pic14_emitcode("pop","ar0");
881 pic14_emitcode("pop","ar1");
889 /* all other cases just dealloc */
893 OP_SYMBOL(op)->aop = NULL;
894 /* if the symbol has a spill */
896 SPIL_LOC(op)->aop = NULL;
901 /*-----------------------------------------------------------------*/
902 /* aopGet - for fetching value of the aop */
903 /*-----------------------------------------------------------------*/
904 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
909 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
910 /* offset is greater than
912 if (offset > (aop->size - 1) &&
913 aop->type != AOP_LIT)
916 /* depending on type */
921 DEBUGpic14_emitcode(";","%d",__LINE__);
922 /* if we need to increment it */
923 while (offset > aop->coff) {
924 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
928 while (offset < aop->coff) {
929 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
935 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
936 return (dname ? "acc" : "a");
938 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
939 rs = Safe_calloc(1,strlen(s)+1);
945 DEBUGpic14_emitcode(";","%d",__LINE__);
946 if (aop->type == AOP_DPTR2)
951 while (offset > aop->coff) {
952 pic14_emitcode ("inc","dptr");
956 while (offset < aop->coff) {
957 pic14_emitcode("lcall","__decdptr");
963 pic14_emitcode("clr","a");
964 pic14_emitcode("movc","a,@a+dptr");
967 pic14_emitcode("movx","a,@dptr");
970 if (aop->type == AOP_DPTR2)
975 return (dname ? "acc" : "a");
979 DEBUGpic14_emitcode(";","%d",__LINE__);
981 sprintf (s,"%s",aop->aopu.aop_immd);
984 sprintf(s,"(%s >> %d)",
990 rs = Safe_calloc(1,strlen(s)+1);
996 sprintf(s,"(%s + %d)",
1000 sprintf(s,"%s",aop->aopu.aop_dir);
1001 rs = Safe_calloc(1,strlen(s)+1);
1007 return aop->aopu.aop_reg[offset]->dname;
1009 return aop->aopu.aop_reg[offset]->name;
1012 //pic14_emitcode(";","%d",__LINE__);
1013 return aop->aopu.aop_dir;
1016 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1017 return "AOP_accumulator_bug";
1020 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1021 rs = Safe_calloc(1,strlen(s)+1);
1026 DEBUGpic14_emitcode(";","%d",__LINE__);
1027 aop->coff = offset ;
1028 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1032 return aop->aopu.aop_str[offset];
1036 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1037 "aopget got unsupported aop->type");
1041 /*-----------------------------------------------------------------*/
1042 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1043 /*-----------------------------------------------------------------*/
1044 pCodeOp *popGetLabel(unsigned int key)
1047 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1052 return newpCodeOpLabel(key+100+labelOffset);
1055 /*-----------------------------------------------------------------*/
1056 /* popCopyReg - copy a pcode operator */
1057 /*-----------------------------------------------------------------*/
1058 pCodeOp *popCopyReg(pCodeOpReg *pc)
1062 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1063 pcor->pcop.type = pc->pcop.type;
1064 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1065 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1067 pcor->rIdx = pc->rIdx;
1069 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1074 /*-----------------------------------------------------------------*/
1075 /* popCopy - copy a pcode operator */
1076 /*-----------------------------------------------------------------*/
1077 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1081 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1082 pcop->type = PO_BIT;
1083 if(!(pcop->name = Safe_strdup(pc->name)))
1084 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1085 ((pCodeOpBit *)pcop)->bit = bitval;
1087 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1092 /*-----------------------------------------------------------------*/
1093 /* popGet - asm operator to pcode operator conversion */
1094 /*-----------------------------------------------------------------*/
1095 pCodeOp *popGetLit(unsigned int lit)
1098 return newpCodeOpLit(lit);
1102 /*-----------------------------------------------------------------*/
1103 /* popGet - asm operator to pcode operator conversion */
1104 /*-----------------------------------------------------------------*/
1105 pCodeOp *popGetWithString(char *str)
1111 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1115 pcop = newpCodeOp(str,PO_STR);
1120 pCodeOp *popRegFromString(char *str)
1123 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1124 pcop->type = PO_GPR_REGISTER;
1126 PCOR(pcop)->rIdx = -1;
1127 PCOR(pcop)->r = NULL;
1129 DEBUGpic14_emitcode(";","%d",__LINE__);
1130 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1135 pCodeOp *popRegFromIdx(int rIdx)
1139 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1140 __FUNCTION__,__LINE__,rIdx);
1142 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1144 PCOR(pcop)->rIdx = rIdx;
1145 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1146 PCOR(pcop)->r->isFree = 0;
1147 PCOR(pcop)->r->wasUsed = 1;
1149 pcop->type = PCOR(pcop)->r->pc_type;
1154 /*-----------------------------------------------------------------*/
1155 /* popGet - asm operator to pcode operator conversion */
1156 /*-----------------------------------------------------------------*/
1157 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1164 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1165 /* offset is greater than
1168 if (offset > (aop->size - 1) &&
1169 aop->type != AOP_LIT)
1170 return NULL; //zero;
1172 /* depending on type */
1173 switch (aop->type) {
1180 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1181 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1182 //pcop->type = PO_SFR_REGISTER;
1184 //PCOR(pcop)->rIdx = -1;
1185 //PCOR(pcop)->r = NULL;
1186 // Really nasty hack to check for temporary registers
1188 //pcop->name = Safe_strdup("BAD_REGISTER");
1193 DEBUGpic14_emitcode(";","%d",__LINE__);
1194 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1195 pcop->type = PO_IMMEDIATE;
1197 // sprintf (s,"%s",aop->aopu.aop_immd);
1200 sprintf(s,"(%s >> %d)",
1205 aop->aopu.aop_immd);
1206 pcop->name = Safe_calloc(1,strlen(s)+1);
1207 strcpy(pcop->name,s);
1211 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1212 pcop->type = PO_DIR;
1214 sprintf(s,"(%s + %d)",
1218 sprintf(s,"%s",aop->aopu.aop_dir);
1219 pcop->name = Safe_calloc(1,strlen(s)+1);
1220 strcpy(pcop->name,s);
1225 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1227 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1228 PCOR(pcop)->rIdx = rIdx;
1229 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1230 pcop->type = PCOR(pcop)->r->pc_type;
1231 rs = aop->aopu.aop_reg[offset]->name;
1232 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1237 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1241 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1244 DEBUGpic14_emitcode(";","%d",__LINE__);
1246 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1247 pcop->type = PO_STR;
1249 //aop->coff = offset ;
1250 //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1251 // sprintf(s,"%s","acc");
1253 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1254 pcop->name = Safe_calloc(1,strlen(s)+1);
1255 strcpy(pcop->name,s);
1260 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1261 "popGet got unsupported aop->type");
1264 /*-----------------------------------------------------------------*/
1265 /* aopPut - puts a string for a aop */
1266 /*-----------------------------------------------------------------*/
1267 void aopPut (asmop *aop, char *s, int offset)
1272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1274 if (aop->size && offset > ( aop->size - 1)) {
1275 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1276 "aopPut got offset > aop->size");
1280 /* will assign value to value */
1281 /* depending on where it is ofcourse */
1282 switch (aop->type) {
1285 sprintf(d,"(%s + %d)",
1286 aop->aopu.aop_dir,offset);
1288 sprintf(d,"%s",aop->aopu.aop_dir);
1291 DEBUGpic14_emitcode(";","%d",__LINE__);
1293 pic14_emitcode("movf","%s,w",s);
1294 pic14_emitcode("movwf","%s",d);
1297 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1298 emitpcode(POC_MOVWF,popGet(aop,offset));
1305 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1306 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1309 strcmp(s,"r0") == 0 ||
1310 strcmp(s,"r1") == 0 ||
1311 strcmp(s,"r2") == 0 ||
1312 strcmp(s,"r3") == 0 ||
1313 strcmp(s,"r4") == 0 ||
1314 strcmp(s,"r5") == 0 ||
1315 strcmp(s,"r6") == 0 ||
1316 strcmp(s,"r7") == 0 )
1317 pic14_emitcode("mov","%s,%s ; %d",
1318 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1323 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1325 pic14_emitcode("movwf","%s",
1326 aop->aopu.aop_reg[offset]->name);
1329 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1330 pcop->type = PO_GPR_REGISTER;
1332 PCOR(pcop)->rIdx = -1;
1333 PCOR(pcop)->r = NULL;
1335 DEBUGpic14_emitcode(";","%d",__LINE__);
1336 pcop->name = Safe_strdup(s);
1337 emitpcode(POC_MOVFW,pcop);
1339 emitpcode(POC_MOVWF,popGet(aop,offset));
1347 if (aop->type == AOP_DPTR2)
1353 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1354 "aopPut writting to code space");
1358 while (offset > aop->coff) {
1360 pic14_emitcode ("inc","dptr");
1363 while (offset < aop->coff) {
1365 pic14_emitcode("lcall","__decdptr");
1370 /* if not in accumulater */
1373 pic14_emitcode ("movx","@dptr,a");
1375 if (aop->type == AOP_DPTR2)
1383 while (offset > aop->coff) {
1385 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1387 while (offset < aop->coff) {
1389 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1395 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1400 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1402 if (strcmp(s,"r0") == 0 ||
1403 strcmp(s,"r1") == 0 ||
1404 strcmp(s,"r2") == 0 ||
1405 strcmp(s,"r3") == 0 ||
1406 strcmp(s,"r4") == 0 ||
1407 strcmp(s,"r5") == 0 ||
1408 strcmp(s,"r6") == 0 ||
1409 strcmp(s,"r7") == 0 ) {
1411 sprintf(buffer,"a%s",s);
1412 pic14_emitcode("mov","@%s,%s",
1413 aop->aopu.aop_ptr->name,buffer);
1415 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1420 if (strcmp(s,"a") == 0)
1421 pic14_emitcode("push","acc");
1423 pic14_emitcode("push","%s",s);
1428 /* if bit variable */
1429 if (!aop->aopu.aop_dir) {
1430 pic14_emitcode("clr","a");
1431 pic14_emitcode("rlc","a");
1434 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1437 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1440 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1442 lbl = newiTempLabel(NULL);
1444 if (strcmp(s,"a")) {
1447 pic14_emitcode("clr","c");
1448 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1449 pic14_emitcode("cpl","c");
1450 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1451 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1458 if (strcmp(aop->aopu.aop_str[offset],s))
1459 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1464 if (!offset && (strcmp(s,"acc") == 0))
1467 if (strcmp(aop->aopu.aop_str[offset],s))
1468 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1472 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1473 "aopPut got unsupported aop->type");
1479 /*-----------------------------------------------------------------*/
1480 /* reAdjustPreg - points a register back to where it should */
1481 /*-----------------------------------------------------------------*/
1482 static void reAdjustPreg (asmop *aop)
1486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1488 if ((size = aop->size) <= 1)
1491 switch (aop->type) {
1495 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1499 if (aop->type == AOP_DPTR2)
1505 pic14_emitcode("lcall","__decdptr");
1508 if (aop->type == AOP_DPTR2)
1518 /*-----------------------------------------------------------------*/
1519 /* genNotFloat - generates not for float operations */
1520 /*-----------------------------------------------------------------*/
1521 static void genNotFloat (operand *op, operand *res)
1527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1528 /* we will put 127 in the first byte of
1530 aopPut(AOP(res),"#127",0);
1531 size = AOP_SIZE(op) - 1;
1534 l = aopGet(op->aop,offset++,FALSE,FALSE);
1538 pic14_emitcode("orl","a,%s",
1540 offset++,FALSE,FALSE));
1542 tlbl = newiTempLabel(NULL);
1544 tlbl = newiTempLabel(NULL);
1545 aopPut(res->aop,one,1);
1546 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1547 aopPut(res->aop,zero,1);
1548 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1550 size = res->aop->size - 2;
1552 /* put zeros in the rest */
1554 aopPut(res->aop,zero,offset++);
1558 /*-----------------------------------------------------------------*/
1559 /* opIsGptr: returns non-zero if the passed operand is */
1560 /* a generic pointer type. */
1561 /*-----------------------------------------------------------------*/
1562 static int opIsGptr(operand *op)
1564 sym_link *type = operandType(op);
1566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1567 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1575 /*-----------------------------------------------------------------*/
1576 /* pic14_getDataSize - get the operand data size */
1577 /*-----------------------------------------------------------------*/
1578 int pic14_getDataSize(operand *op)
1580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1583 return AOP_SIZE(op);
1585 // tsd- in the pic port, the genptr size is 1, so this code here
1586 // fails. ( in the 8051 port, the size was 4).
1589 size = AOP_SIZE(op);
1590 if (size == GPTRSIZE)
1592 sym_link *type = operandType(op);
1593 if (IS_GENPTR(type))
1595 /* generic pointer; arithmetic operations
1596 * should ignore the high byte (pointer type).
1599 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1606 /*-----------------------------------------------------------------*/
1607 /* pic14_outAcc - output Acc */
1608 /*-----------------------------------------------------------------*/
1609 void pic14_outAcc(operand *result)
1612 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1613 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1616 size = pic14_getDataSize(result);
1618 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1621 /* unsigned or positive */
1623 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1628 /*-----------------------------------------------------------------*/
1629 /* pic14_outBitC - output a bit C */
1630 /*-----------------------------------------------------------------*/
1631 void pic14_outBitC(operand *result)
1634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1635 /* if the result is bit */
1636 if (AOP_TYPE(result) == AOP_CRY)
1637 aopPut(AOP(result),"c",0);
1639 pic14_emitcode("clr","a ; %d", __LINE__);
1640 pic14_emitcode("rlc","a");
1641 pic14_outAcc(result);
1645 /*-----------------------------------------------------------------*/
1646 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1647 /*-----------------------------------------------------------------*/
1648 void pic14_toBoolean(operand *oper)
1650 int size = AOP_SIZE(oper) - 1;
1653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1655 if ( AOP_TYPE(oper) != AOP_ACC) {
1656 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1659 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1664 /*-----------------------------------------------------------------*/
1665 /* genNot - generate code for ! operation */
1666 /*-----------------------------------------------------------------*/
1667 static void genNot (iCode *ic)
1670 sym_link *optype = operandType(IC_LEFT(ic));
1673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 /* assign asmOps to operand & result */
1675 aopOp (IC_LEFT(ic),ic,FALSE);
1676 aopOp (IC_RESULT(ic),ic,TRUE);
1678 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1679 /* if in bit space then a special case */
1680 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1681 pic14_emitcode("movlw","1<<%s");
1682 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1683 //pic14_emitcode("cpl","c");
1684 //pic14_outBitC(IC_RESULT(ic));
1688 /* if type float then do float */
1689 if (IS_FLOAT(optype)) {
1690 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1694 size = AOP_SIZE(IC_RESULT(ic));
1696 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1697 emitpcode(POC_ANDLW,popGetLit(1));
1698 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1701 pic14_toBoolean(IC_LEFT(ic));
1703 tlbl = newiTempLabel(NULL);
1704 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1706 pic14_outBitC(IC_RESULT(ic));
1709 /* release the aops */
1710 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1711 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1715 /*-----------------------------------------------------------------*/
1716 /* genCpl - generate code for complement */
1717 /*-----------------------------------------------------------------*/
1718 static void genCpl (iCode *ic)
1724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1725 /* assign asmOps to operand & result */
1726 aopOp (IC_LEFT(ic),ic,FALSE);
1727 aopOp (IC_RESULT(ic),ic,TRUE);
1729 /* if both are in bit space then
1731 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1732 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1734 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1735 pic14_emitcode("cpl","c");
1736 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1740 size = AOP_SIZE(IC_RESULT(ic));
1742 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1744 pic14_emitcode("cpl","a");
1745 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1750 /* release the aops */
1751 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1752 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1755 /*-----------------------------------------------------------------*/
1756 /* genUminusFloat - unary minus for floating points */
1757 /*-----------------------------------------------------------------*/
1758 static void genUminusFloat(operand *op,operand *result)
1760 int size ,offset =0 ;
1763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1764 /* for this we just need to flip the
1765 first it then copy the rest in place */
1766 size = AOP_SIZE(op) - 1;
1767 l = aopGet(AOP(op),3,FALSE,FALSE);
1771 pic14_emitcode("cpl","acc.7");
1772 aopPut(AOP(result),"a",3);
1776 aopGet(AOP(op),offset,FALSE,FALSE),
1782 /*-----------------------------------------------------------------*/
1783 /* genUminus - unary minus code generation */
1784 /*-----------------------------------------------------------------*/
1785 static void genUminus (iCode *ic)
1788 sym_link *optype, *rtype;
1791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1793 aopOp(IC_LEFT(ic),ic,FALSE);
1794 aopOp(IC_RESULT(ic),ic,TRUE);
1796 /* if both in bit space then special
1798 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1799 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1801 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1802 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1803 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1808 optype = operandType(IC_LEFT(ic));
1809 rtype = operandType(IC_RESULT(ic));
1811 /* if float then do float stuff */
1812 if (IS_FLOAT(optype)) {
1813 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1817 /* otherwise subtract from zero by taking the 2's complement */
1818 size = AOP_SIZE(IC_LEFT(ic));
1820 for(i=0; i<size; i++) {
1821 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1822 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1824 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1825 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1829 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1830 for(i=1; i<size; i++) {
1832 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1836 /* release the aops */
1837 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1838 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1841 /*-----------------------------------------------------------------*/
1842 /* saveRegisters - will look for a call and save the registers */
1843 /*-----------------------------------------------------------------*/
1844 static void saveRegisters(iCode *lic)
1851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1853 for (ic = lic ; ic ; ic = ic->next)
1854 if (ic->op == CALL || ic->op == PCALL)
1858 fprintf(stderr,"found parameter push with no function call\n");
1862 /* if the registers have been saved already then
1864 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1867 /* find the registers in use at this time
1868 and push them away to safety */
1869 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1873 if (options.useXstack) {
1874 if (bitVectBitValue(rsave,R0_IDX))
1875 pic14_emitcode("mov","b,r0");
1876 pic14_emitcode("mov","r0,%s",spname);
1877 for (i = 0 ; i < pic14_nRegs ; i++) {
1878 if (bitVectBitValue(rsave,i)) {
1880 pic14_emitcode("mov","a,b");
1882 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1883 pic14_emitcode("movx","@r0,a");
1884 pic14_emitcode("inc","r0");
1887 pic14_emitcode("mov","%s,r0",spname);
1888 if (bitVectBitValue(rsave,R0_IDX))
1889 pic14_emitcode("mov","r0,b");
1891 for (i = 0 ; i < pic14_nRegs ; i++) {
1892 if (bitVectBitValue(rsave,i))
1893 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1896 dtype = operandType(IC_LEFT(ic));
1898 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1899 IFFUNC_ISISR(currFunc->type) &&
1902 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1905 /*-----------------------------------------------------------------*/
1906 /* unsaveRegisters - pop the pushed registers */
1907 /*-----------------------------------------------------------------*/
1908 static void unsaveRegisters (iCode *ic)
1913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1914 /* find the registers in use at this time
1915 and push them away to safety */
1916 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1919 if (options.useXstack) {
1920 pic14_emitcode("mov","r0,%s",spname);
1921 for (i = pic14_nRegs ; i >= 0 ; i--) {
1922 if (bitVectBitValue(rsave,i)) {
1923 pic14_emitcode("dec","r0");
1924 pic14_emitcode("movx","a,@r0");
1926 pic14_emitcode("mov","b,a");
1928 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1932 pic14_emitcode("mov","%s,r0",spname);
1933 if (bitVectBitValue(rsave,R0_IDX))
1934 pic14_emitcode("mov","r0,b");
1936 for (i = pic14_nRegs ; i >= 0 ; i--) {
1937 if (bitVectBitValue(rsave,i))
1938 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1944 /*-----------------------------------------------------------------*/
1946 /*-----------------------------------------------------------------*/
1947 static void pushSide(operand * oper, int size)
1951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1953 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1954 if (AOP_TYPE(oper) != AOP_REG &&
1955 AOP_TYPE(oper) != AOP_DIR &&
1957 pic14_emitcode("mov","a,%s",l);
1958 pic14_emitcode("push","acc");
1960 pic14_emitcode("push","%s",l);
1965 /*-----------------------------------------------------------------*/
1966 /* assignResultValue - */
1967 /*-----------------------------------------------------------------*/
1968 static void assignResultValue(operand * oper)
1970 int size = AOP_SIZE(oper);
1972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1974 if(!GpsuedoStkPtr) {
1975 /* The last byte in the assignment is in W */
1977 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1982 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1984 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1989 /*-----------------------------------------------------------------*/
1990 /* genIpush - genrate code for pushing this gets a little complex */
1991 /*-----------------------------------------------------------------*/
1992 static void genIpush (iCode *ic)
1995 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
1997 int size, offset = 0 ;
2001 /* if this is not a parm push : ie. it is spill push
2002 and spill push is always done on the local stack */
2003 if (!ic->parmPush) {
2005 /* and the item is spilt then do nothing */
2006 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2009 aopOp(IC_LEFT(ic),ic,FALSE);
2010 size = AOP_SIZE(IC_LEFT(ic));
2011 /* push it on the stack */
2013 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2018 pic14_emitcode("push","%s",l);
2023 /* this is a paramter push: in this case we call
2024 the routine to find the call and save those
2025 registers that need to be saved */
2028 /* then do the push */
2029 aopOp(IC_LEFT(ic),ic,FALSE);
2032 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2033 size = AOP_SIZE(IC_LEFT(ic));
2036 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2037 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2038 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2040 pic14_emitcode("mov","a,%s",l);
2041 pic14_emitcode("push","acc");
2043 pic14_emitcode("push","%s",l);
2046 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2050 /*-----------------------------------------------------------------*/
2051 /* genIpop - recover the registers: can happen only for spilling */
2052 /*-----------------------------------------------------------------*/
2053 static void genIpop (iCode *ic)
2055 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2060 /* if the temp was not pushed then */
2061 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2064 aopOp(IC_LEFT(ic),ic,FALSE);
2065 size = AOP_SIZE(IC_LEFT(ic));
2068 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2071 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2075 /*-----------------------------------------------------------------*/
2076 /* unsaverbank - restores the resgister bank from stack */
2077 /*-----------------------------------------------------------------*/
2078 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2080 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2088 if (options.useXstack) {
2090 r = getFreePtr(ic,&aop,FALSE);
2093 pic14_emitcode("mov","%s,_spx",r->name);
2094 pic14_emitcode("movx","a,@%s",r->name);
2095 pic14_emitcode("mov","psw,a");
2096 pic14_emitcode("dec","%s",r->name);
2099 pic14_emitcode ("pop","psw");
2102 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2103 if (options.useXstack) {
2104 pic14_emitcode("movx","a,@%s",r->name);
2105 //pic14_emitcode("mov","(%s+%d),a",
2106 // regspic14[i].base,8*bank+regspic14[i].offset);
2107 pic14_emitcode("dec","%s",r->name);
2110 pic14_emitcode("pop",""); //"(%s+%d)",
2111 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2114 if (options.useXstack) {
2116 pic14_emitcode("mov","_spx,%s",r->name);
2117 freeAsmop(NULL,aop,ic,TRUE);
2123 /*-----------------------------------------------------------------*/
2124 /* saverbank - saves an entire register bank on the stack */
2125 /*-----------------------------------------------------------------*/
2126 static void saverbank (int bank, iCode *ic, bool pushPsw)
2128 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2134 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2135 if (options.useXstack) {
2138 r = getFreePtr(ic,&aop,FALSE);
2139 pic14_emitcode("mov","%s,_spx",r->name);
2143 for (i = 0 ; i < pic14_nRegs ;i++) {
2144 if (options.useXstack) {
2145 pic14_emitcode("inc","%s",r->name);
2146 //pic14_emitcode("mov","a,(%s+%d)",
2147 // regspic14[i].base,8*bank+regspic14[i].offset);
2148 pic14_emitcode("movx","@%s,a",r->name);
2150 pic14_emitcode("push","");// "(%s+%d)",
2151 //regspic14[i].base,8*bank+regspic14[i].offset);
2155 if (options.useXstack) {
2156 pic14_emitcode("mov","a,psw");
2157 pic14_emitcode("movx","@%s,a",r->name);
2158 pic14_emitcode("inc","%s",r->name);
2159 pic14_emitcode("mov","_spx,%s",r->name);
2160 freeAsmop (NULL,aop,ic,TRUE);
2163 pic14_emitcode("push","psw");
2165 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2171 /*-----------------------------------------------------------------*/
2172 /* genCall - generates a call statement */
2173 /*-----------------------------------------------------------------*/
2174 static void genCall (iCode *ic)
2178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2180 /* if caller saves & we have not saved then */
2184 /* if we are calling a function that is not using
2185 the same register bank then we need to save the
2186 destination registers on the stack */
2187 dtype = operandType(IC_LEFT(ic));
2189 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2190 IFFUNC_ISISR(currFunc->type) &&
2193 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2195 /* if send set is not empty the assign */
2198 /* For the Pic port, there is no data stack.
2199 * So parameters passed to functions are stored
2200 * in registers. (The pCode optimizer will get
2201 * rid of most of these :).
2203 int psuedoStkPtr=-1;
2204 int firstTimeThruLoop = 1;
2206 _G.sendSet = reverseSet(_G.sendSet);
2208 /* First figure how many parameters are getting passed */
2209 for (sic = setFirstItem(_G.sendSet) ; sic ;
2210 sic = setNextItem(_G.sendSet)) {
2212 aopOp(IC_LEFT(sic),sic,FALSE);
2213 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2214 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2217 for (sic = setFirstItem(_G.sendSet) ; sic ;
2218 sic = setNextItem(_G.sendSet)) {
2219 int size, offset = 0;
2221 aopOp(IC_LEFT(sic),sic,FALSE);
2222 size = AOP_SIZE(IC_LEFT(sic));
2226 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2227 AopType(AOP_TYPE(IC_LEFT(sic))));
2229 if(!firstTimeThruLoop) {
2230 /* If this is not the first time we've been through the loop
2231 * then we need to save the parameter in a temporary
2232 * register. The last byte of the last parameter is
2234 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2237 firstTimeThruLoop=0;
2239 //if (strcmp(l,fReturn[offset])) {
2241 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2242 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2243 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2245 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2250 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2255 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2256 OP_SYMBOL(IC_LEFT(ic))->rname :
2257 OP_SYMBOL(IC_LEFT(ic))->name));
2260 /* if we need assign a result value */
2261 if ((IS_ITEMP(IC_RESULT(ic)) &&
2262 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2263 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2264 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2267 aopOp(IC_RESULT(ic),ic,FALSE);
2270 assignResultValue(IC_RESULT(ic));
2272 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2273 AopType(AOP_TYPE(IC_RESULT(ic))));
2275 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2278 /* adjust the stack for parameters if
2280 if (ic->parmBytes) {
2282 if (ic->parmBytes > 3) {
2283 pic14_emitcode("mov","a,%s",spname);
2284 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2285 pic14_emitcode("mov","%s,a",spname);
2287 for ( i = 0 ; i < ic->parmBytes ;i++)
2288 pic14_emitcode("dec","%s",spname);
2292 /* if register bank was saved then pop them */
2294 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2296 /* if we hade saved some registers then unsave them */
2297 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2298 unsaveRegisters (ic);
2303 /*-----------------------------------------------------------------*/
2304 /* genPcall - generates a call by pointer statement */
2305 /*-----------------------------------------------------------------*/
2306 static void genPcall (iCode *ic)
2309 symbol *rlbl = newiTempLabel(NULL);
2312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2313 /* if caller saves & we have not saved then */
2317 /* if we are calling a function that is not using
2318 the same register bank then we need to save the
2319 destination registers on the stack */
2320 dtype = operandType(IC_LEFT(ic));
2322 IFFUNC_ISISR(currFunc->type) &&
2323 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2324 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2327 /* push the return address on to the stack */
2328 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2329 pic14_emitcode("push","acc");
2330 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2331 pic14_emitcode("push","acc");
2333 if (options.model == MODEL_FLAT24)
2335 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2336 pic14_emitcode("push","acc");
2339 /* now push the calling address */
2340 aopOp(IC_LEFT(ic),ic,FALSE);
2342 pushSide(IC_LEFT(ic), FPTRSIZE);
2344 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2346 /* if send set is not empty the assign */
2350 for (sic = setFirstItem(_G.sendSet) ; sic ;
2351 sic = setNextItem(_G.sendSet)) {
2352 int size, offset = 0;
2353 aopOp(IC_LEFT(sic),sic,FALSE);
2354 size = AOP_SIZE(IC_LEFT(sic));
2356 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2358 if (strcmp(l,fReturn[offset]))
2359 pic14_emitcode("mov","%s,%s",
2364 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2369 pic14_emitcode("ret","");
2370 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2373 /* if we need assign a result value */
2374 if ((IS_ITEMP(IC_RESULT(ic)) &&
2375 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2376 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2377 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2380 aopOp(IC_RESULT(ic),ic,FALSE);
2383 assignResultValue(IC_RESULT(ic));
2385 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2388 /* adjust the stack for parameters if
2390 if (ic->parmBytes) {
2392 if (ic->parmBytes > 3) {
2393 pic14_emitcode("mov","a,%s",spname);
2394 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2395 pic14_emitcode("mov","%s,a",spname);
2397 for ( i = 0 ; i < ic->parmBytes ;i++)
2398 pic14_emitcode("dec","%s",spname);
2402 /* if register bank was saved then unsave them */
2404 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2405 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2407 /* if we hade saved some registers then
2410 unsaveRegisters (ic);
2414 /*-----------------------------------------------------------------*/
2415 /* resultRemat - result is rematerializable */
2416 /*-----------------------------------------------------------------*/
2417 static int resultRemat (iCode *ic)
2419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2420 if (SKIP_IC(ic) || ic->op == IFX)
2423 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2424 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2425 if (sym->remat && !POINTER_SET(ic))
2432 #if defined(__BORLANDC__) || defined(_MSC_VER)
2433 #define STRCASECMP stricmp
2435 #define STRCASECMP strcasecmp
2438 /*-----------------------------------------------------------------*/
2439 /* inExcludeList - return 1 if the string is in exclude Reg list */
2440 /*-----------------------------------------------------------------*/
2441 static bool inExcludeList(char *s)
2443 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2448 if (options.excludeRegs[i] &&
2449 STRCASECMP(options.excludeRegs[i],"none") == 0)
2452 for ( i = 0 ; options.excludeRegs[i]; i++) {
2453 if (options.excludeRegs[i] &&
2454 STRCASECMP(s,options.excludeRegs[i]) == 0)
2461 /*-----------------------------------------------------------------*/
2462 /* genFunction - generated code for function entry */
2463 /*-----------------------------------------------------------------*/
2464 static void genFunction (iCode *ic)
2469 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2471 labelOffset += (max_key+4);
2475 /* create the function header */
2476 pic14_emitcode(";","-----------------------------------------");
2477 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2478 pic14_emitcode(";","-----------------------------------------");
2480 pic14_emitcode("","%s:",sym->rname);
2481 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2483 ftype = operandType(IC_LEFT(ic));
2485 /* if critical function then turn interrupts off */
2486 if (IFFUNC_ISCRITICAL(ftype))
2487 pic14_emitcode("clr","ea");
2489 /* here we need to generate the equates for the
2490 register bank if required */
2492 if (FUNC_REGBANK(ftype) != rbank) {
2495 rbank = FUNC_REGBANK(ftype);
2496 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2497 if (strcmp(regspic14[i].base,"0") == 0)
2498 pic14_emitcode("","%s = 0x%02x",
2500 8*rbank+regspic14[i].offset);
2502 pic14_emitcode ("","%s = %s + 0x%02x",
2505 8*rbank+regspic14[i].offset);
2510 /* if this is an interrupt service routine then
2511 save acc, b, dpl, dph */
2512 if (IFFUNC_ISISR(sym->type)) {
2514 if (!inExcludeList("acc"))
2515 pic14_emitcode ("push","acc");
2516 if (!inExcludeList("b"))
2517 pic14_emitcode ("push","b");
2518 if (!inExcludeList("dpl"))
2519 pic14_emitcode ("push","dpl");
2520 if (!inExcludeList("dph"))
2521 pic14_emitcode ("push","dph");
2522 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2524 pic14_emitcode ("push", "dpx");
2525 /* Make sure we're using standard DPTR */
2526 pic14_emitcode ("push", "dps");
2527 pic14_emitcode ("mov", "dps, #0x00");
2528 if (options.stack10bit)
2530 /* This ISR could conceivably use DPTR2. Better save it. */
2531 pic14_emitcode ("push", "dpl1");
2532 pic14_emitcode ("push", "dph1");
2533 pic14_emitcode ("push", "dpx1");
2536 /* if this isr has no bank i.e. is going to
2537 run with bank 0 , then we need to save more
2539 if (!FUNC_REGBANK(sym->type)) {
2541 /* if this function does not call any other
2542 function then we can be economical and
2543 save only those registers that are used */
2544 if (! IFFUNC_HASFCALL(sym->type)) {
2547 /* if any registers used */
2548 if (sym->regsUsed) {
2549 /* save the registers used */
2550 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2551 if (bitVectBitValue(sym->regsUsed,i) ||
2552 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2553 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2558 /* this function has a function call cannot
2559 determines register usage so we will have the
2561 saverbank(0,ic,FALSE);
2565 /* if callee-save to be used for this function
2566 then save the registers being used in this function */
2567 if (IFFUNC_CALLEESAVES(sym->type)) {
2570 /* if any registers used */
2571 if (sym->regsUsed) {
2572 /* save the registers used */
2573 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2574 if (bitVectBitValue(sym->regsUsed,i) ||
2575 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2576 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2584 /* set the register bank to the desired value */
2585 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2586 pic14_emitcode("push","psw");
2587 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2590 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2592 if (options.useXstack) {
2593 pic14_emitcode("mov","r0,%s",spname);
2594 pic14_emitcode("mov","a,_bp");
2595 pic14_emitcode("movx","@r0,a");
2596 pic14_emitcode("inc","%s",spname);
2600 /* set up the stack */
2601 pic14_emitcode ("push","_bp"); /* save the callers stack */
2603 pic14_emitcode ("mov","_bp,%s",spname);
2606 /* adjust the stack for the function */
2611 werror(W_STACK_OVERFLOW,sym->name);
2613 if (i > 3 && sym->recvSize < 4) {
2615 pic14_emitcode ("mov","a,sp");
2616 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2617 pic14_emitcode ("mov","sp,a");
2622 pic14_emitcode("inc","sp");
2627 pic14_emitcode ("mov","a,_spx");
2628 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2629 pic14_emitcode ("mov","_spx,a");
2634 /*-----------------------------------------------------------------*/
2635 /* genEndFunction - generates epilogue for functions */
2636 /*-----------------------------------------------------------------*/
2637 static void genEndFunction (iCode *ic)
2639 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2643 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2645 pic14_emitcode ("mov","%s,_bp",spname);
2648 /* if use external stack but some variables were
2649 added to the local stack then decrement the
2651 if (options.useXstack && sym->stack) {
2652 pic14_emitcode("mov","a,sp");
2653 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2654 pic14_emitcode("mov","sp,a");
2658 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2659 if (options.useXstack) {
2660 pic14_emitcode("mov","r0,%s",spname);
2661 pic14_emitcode("movx","a,@r0");
2662 pic14_emitcode("mov","_bp,a");
2663 pic14_emitcode("dec","%s",spname);
2667 pic14_emitcode ("pop","_bp");
2671 /* restore the register bank */
2672 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2673 pic14_emitcode ("pop","psw");
2675 if (IFFUNC_ISISR(sym->type)) {
2677 /* now we need to restore the registers */
2678 /* if this isr has no bank i.e. is going to
2679 run with bank 0 , then we need to save more
2681 if (!FUNC_REGBANK(sym->type)) {
2683 /* if this function does not call any other
2684 function then we can be economical and
2685 save only those registers that are used */
2686 if (! IFFUNC_HASFCALL(sym->type)) {
2689 /* if any registers used */
2690 if (sym->regsUsed) {
2691 /* save the registers used */
2692 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2693 if (bitVectBitValue(sym->regsUsed,i) ||
2694 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2695 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2700 /* this function has a function call cannot
2701 determines register usage so we will have the
2703 unsaverbank(0,ic,FALSE);
2707 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2709 if (options.stack10bit)
2711 pic14_emitcode ("pop", "dpx1");
2712 pic14_emitcode ("pop", "dph1");
2713 pic14_emitcode ("pop", "dpl1");
2715 pic14_emitcode ("pop", "dps");
2716 pic14_emitcode ("pop", "dpx");
2718 if (!inExcludeList("dph"))
2719 pic14_emitcode ("pop","dph");
2720 if (!inExcludeList("dpl"))
2721 pic14_emitcode ("pop","dpl");
2722 if (!inExcludeList("b"))
2723 pic14_emitcode ("pop","b");
2724 if (!inExcludeList("acc"))
2725 pic14_emitcode ("pop","acc");
2727 if (IFFUNC_ISCRITICAL(sym->type))
2728 pic14_emitcode("setb","ea");
2730 /* if debug then send end of function */
2731 /* if (options.debug && currFunc) { */
2734 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2735 FileBaseName(ic->filename),currFunc->lastLine,
2736 ic->level,ic->block);
2737 if (IS_STATIC(currFunc->etype))
2738 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2740 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2744 pic14_emitcode ("reti","");
2747 if (IFFUNC_ISCRITICAL(sym->type))
2748 pic14_emitcode("setb","ea");
2750 if (IFFUNC_CALLEESAVES(sym->type)) {
2753 /* if any registers used */
2754 if (sym->regsUsed) {
2755 /* save the registers used */
2756 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2757 if (bitVectBitValue(sym->regsUsed,i) ||
2758 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2759 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2765 /* if debug then send end of function */
2768 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2769 FileBaseName(ic->filename),currFunc->lastLine,
2770 ic->level,ic->block);
2771 if (IS_STATIC(currFunc->etype))
2772 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2774 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2778 pic14_emitcode ("return","");
2779 emitpcodeNULLop(POC_RETURN);
2781 /* Mark the end of a function */
2782 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2787 /*-----------------------------------------------------------------*/
2788 /* genRet - generate code for return statement */
2789 /*-----------------------------------------------------------------*/
2790 static void genRet (iCode *ic)
2792 int size,offset = 0 , pushed = 0;
2794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2795 /* if we have no return value then
2796 just generate the "ret" */
2800 /* we have something to return then
2801 move the return value into place */
2802 aopOp(IC_LEFT(ic),ic,FALSE);
2803 size = AOP_SIZE(IC_LEFT(ic));
2807 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2809 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2811 pic14_emitcode("push","%s",l);
2814 l = aopGet(AOP(IC_LEFT(ic)),offset,
2816 if (strcmp(fReturn[offset],l)) {
2817 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2818 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2819 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2821 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2824 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2825 pic14_emitcode("movwf","%s",fReturn[offset]);
2835 if (strcmp(fReturn[pushed],"a"))
2836 pic14_emitcode("pop",fReturn[pushed]);
2838 pic14_emitcode("pop","acc");
2841 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2844 /* generate a jump to the return label
2845 if the next is not the return statement */
2846 if (!(ic->next && ic->next->op == LABEL &&
2847 IC_LABEL(ic->next) == returnLabel)) {
2849 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2850 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2855 /*-----------------------------------------------------------------*/
2856 /* genLabel - generates a label */
2857 /*-----------------------------------------------------------------*/
2858 static void genLabel (iCode *ic)
2860 /* special case never generate */
2861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2862 if (IC_LABEL(ic) == entryLabel)
2865 emitpLabel(IC_LABEL(ic)->key);
2866 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2869 /*-----------------------------------------------------------------*/
2870 /* genGoto - generates a goto */
2871 /*-----------------------------------------------------------------*/
2873 static void genGoto (iCode *ic)
2875 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2876 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2880 /*-----------------------------------------------------------------*/
2881 /* genMultbits :- multiplication of bits */
2882 /*-----------------------------------------------------------------*/
2883 static void genMultbits (operand *left,
2887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2889 if(!pic14_sameRegs(AOP(result),AOP(right)))
2890 emitpcode(POC_BSF, popGet(AOP(result),0));
2892 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2893 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2894 emitpcode(POC_BCF, popGet(AOP(result),0));
2899 /*-----------------------------------------------------------------*/
2900 /* genMultOneByte : 8 bit multiplication & division */
2901 /*-----------------------------------------------------------------*/
2902 static void genMultOneByte (operand *left,
2906 sym_link *opetype = operandType(result);
2911 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2912 DEBUGpic14_AopType(__LINE__,left,right,result);
2914 /* (if two literals, the value is computed before) */
2915 /* if one literal, literal on the right */
2916 if (AOP_TYPE(left) == AOP_LIT){
2922 size = AOP_SIZE(result);
2923 /* signed or unsigned */
2924 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2925 l = aopGet(AOP(left),0,FALSE,FALSE);
2927 pic14_emitcode("mul","ab");
2928 /* if result size = 1, mul signed = mul unsigned */
2929 aopPut(AOP(result),"a",0);
2931 if (SPEC_USIGN(opetype)){
2932 aopPut(AOP(result),"b",1);
2934 /* for filling the MSBs */
2935 pic14_emitcode("clr","a");
2938 pic14_emitcode("mov","a,b");
2940 /* adjust the MSB if left or right neg */
2942 /* if one literal */
2943 if (AOP_TYPE(right) == AOP_LIT){
2944 /* AND literal negative */
2945 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2946 /* adjust MSB (c==0 after mul) */
2947 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2951 lbl = newiTempLabel(NULL);
2952 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2953 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2954 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2955 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2956 lbl = newiTempLabel(NULL);
2957 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2958 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2959 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2962 lbl = newiTempLabel(NULL);
2963 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2964 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2965 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2966 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2967 lbl = newiTempLabel(NULL);
2968 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2969 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2970 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2972 aopPut(AOP(result),"a",1);
2975 pic14_emitcode("rlc","a");
2976 pic14_emitcode("subb","a,acc");
2983 aopPut(AOP(result),"a",offset++);
2987 /*-----------------------------------------------------------------*/
2988 /* genMult - generates code for multiplication */
2989 /*-----------------------------------------------------------------*/
2990 static void genMult (iCode *ic)
2992 operand *left = IC_LEFT(ic);
2993 operand *right = IC_RIGHT(ic);
2994 operand *result= IC_RESULT(ic);
2996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2997 /* assign the amsops */
2998 aopOp (left,ic,FALSE);
2999 aopOp (right,ic,FALSE);
3000 aopOp (result,ic,TRUE);
3002 DEBUGpic14_AopType(__LINE__,left,right,result);
3004 /* special cases first */
3006 if (AOP_TYPE(left) == AOP_CRY &&
3007 AOP_TYPE(right)== AOP_CRY) {
3008 genMultbits(left,right,result);
3012 /* if both are of size == 1 */
3013 if (AOP_SIZE(left) == 1 &&
3014 AOP_SIZE(right) == 1 ) {
3015 genMultOneByte(left,right,result);
3019 /* should have been converted to function call */
3023 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3024 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3025 freeAsmop(result,NULL,ic,TRUE);
3028 /*-----------------------------------------------------------------*/
3029 /* genDivbits :- division of bits */
3030 /*-----------------------------------------------------------------*/
3031 static void genDivbits (operand *left,
3038 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3039 /* the result must be bit */
3040 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3041 l = aopGet(AOP(left),0,FALSE,FALSE);
3045 pic14_emitcode("div","ab");
3046 pic14_emitcode("rrc","a");
3047 aopPut(AOP(result),"c",0);
3050 /*-----------------------------------------------------------------*/
3051 /* genDivOneByte : 8 bit division */
3052 /*-----------------------------------------------------------------*/
3053 static void genDivOneByte (operand *left,
3057 sym_link *opetype = operandType(result);
3062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3063 size = AOP_SIZE(result) - 1;
3065 /* signed or unsigned */
3066 if (SPEC_USIGN(opetype)) {
3067 /* unsigned is easy */
3068 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3069 l = aopGet(AOP(left),0,FALSE,FALSE);
3071 pic14_emitcode("div","ab");
3072 aopPut(AOP(result),"a",0);
3074 aopPut(AOP(result),zero,offset++);
3078 /* signed is a little bit more difficult */
3080 /* save the signs of the operands */
3081 l = aopGet(AOP(left),0,FALSE,FALSE);
3083 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3084 pic14_emitcode("push","acc"); /* save it on the stack */
3086 /* now sign adjust for both left & right */
3087 l = aopGet(AOP(right),0,FALSE,FALSE);
3089 lbl = newiTempLabel(NULL);
3090 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3091 pic14_emitcode("cpl","a");
3092 pic14_emitcode("inc","a");
3093 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3094 pic14_emitcode("mov","b,a");
3096 /* sign adjust left side */
3097 l = aopGet(AOP(left),0,FALSE,FALSE);
3100 lbl = newiTempLabel(NULL);
3101 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3102 pic14_emitcode("cpl","a");
3103 pic14_emitcode("inc","a");
3104 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3106 /* now the division */
3107 pic14_emitcode("div","ab");
3108 /* we are interested in the lower order
3110 pic14_emitcode("mov","b,a");
3111 lbl = newiTempLabel(NULL);
3112 pic14_emitcode("pop","acc");
3113 /* if there was an over flow we don't
3114 adjust the sign of the result */
3115 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3116 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3118 pic14_emitcode("clr","a");
3119 pic14_emitcode("subb","a,b");
3120 pic14_emitcode("mov","b,a");
3121 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3123 /* now we are done */
3124 aopPut(AOP(result),"b",0);
3126 pic14_emitcode("mov","c,b.7");
3127 pic14_emitcode("subb","a,acc");
3130 aopPut(AOP(result),"a",offset++);
3134 /*-----------------------------------------------------------------*/
3135 /* genDiv - generates code for division */
3136 /*-----------------------------------------------------------------*/
3137 static void genDiv (iCode *ic)
3139 operand *left = IC_LEFT(ic);
3140 operand *right = IC_RIGHT(ic);
3141 operand *result= IC_RESULT(ic);
3143 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3144 /* assign the amsops */
3145 aopOp (left,ic,FALSE);
3146 aopOp (right,ic,FALSE);
3147 aopOp (result,ic,TRUE);
3149 /* special cases first */
3151 if (AOP_TYPE(left) == AOP_CRY &&
3152 AOP_TYPE(right)== AOP_CRY) {
3153 genDivbits(left,right,result);
3157 /* if both are of size == 1 */
3158 if (AOP_SIZE(left) == 1 &&
3159 AOP_SIZE(right) == 1 ) {
3160 genDivOneByte(left,right,result);
3164 /* should have been converted to function call */
3167 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3168 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3169 freeAsmop(result,NULL,ic,TRUE);
3172 /*-----------------------------------------------------------------*/
3173 /* genModbits :- modulus of bits */
3174 /*-----------------------------------------------------------------*/
3175 static void genModbits (operand *left,
3182 /* the result must be bit */
3183 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3184 l = aopGet(AOP(left),0,FALSE,FALSE);
3188 pic14_emitcode("div","ab");
3189 pic14_emitcode("mov","a,b");
3190 pic14_emitcode("rrc","a");
3191 aopPut(AOP(result),"c",0);
3194 /*-----------------------------------------------------------------*/
3195 /* genModOneByte : 8 bit modulus */
3196 /*-----------------------------------------------------------------*/
3197 static void genModOneByte (operand *left,
3201 sym_link *opetype = operandType(result);
3205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3206 /* signed or unsigned */
3207 if (SPEC_USIGN(opetype)) {
3208 /* unsigned is easy */
3209 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3210 l = aopGet(AOP(left),0,FALSE,FALSE);
3212 pic14_emitcode("div","ab");
3213 aopPut(AOP(result),"b",0);
3217 /* signed is a little bit more difficult */
3219 /* save the signs of the operands */
3220 l = aopGet(AOP(left),0,FALSE,FALSE);
3223 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3224 pic14_emitcode("push","acc"); /* save it on the stack */
3226 /* now sign adjust for both left & right */
3227 l = aopGet(AOP(right),0,FALSE,FALSE);
3230 lbl = newiTempLabel(NULL);
3231 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3232 pic14_emitcode("cpl","a");
3233 pic14_emitcode("inc","a");
3234 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3235 pic14_emitcode("mov","b,a");
3237 /* sign adjust left side */
3238 l = aopGet(AOP(left),0,FALSE,FALSE);
3241 lbl = newiTempLabel(NULL);
3242 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3243 pic14_emitcode("cpl","a");
3244 pic14_emitcode("inc","a");
3245 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3247 /* now the multiplication */
3248 pic14_emitcode("div","ab");
3249 /* we are interested in the lower order
3251 lbl = newiTempLabel(NULL);
3252 pic14_emitcode("pop","acc");
3253 /* if there was an over flow we don't
3254 adjust the sign of the result */
3255 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3256 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3258 pic14_emitcode("clr","a");
3259 pic14_emitcode("subb","a,b");
3260 pic14_emitcode("mov","b,a");
3261 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263 /* now we are done */
3264 aopPut(AOP(result),"b",0);
3268 /*-----------------------------------------------------------------*/
3269 /* genMod - generates code for division */
3270 /*-----------------------------------------------------------------*/
3271 static void genMod (iCode *ic)
3273 operand *left = IC_LEFT(ic);
3274 operand *right = IC_RIGHT(ic);
3275 operand *result= IC_RESULT(ic);
3277 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3278 /* assign the amsops */
3279 aopOp (left,ic,FALSE);
3280 aopOp (right,ic,FALSE);
3281 aopOp (result,ic,TRUE);
3283 /* special cases first */
3285 if (AOP_TYPE(left) == AOP_CRY &&
3286 AOP_TYPE(right)== AOP_CRY) {
3287 genModbits(left,right,result);
3291 /* if both are of size == 1 */
3292 if (AOP_SIZE(left) == 1 &&
3293 AOP_SIZE(right) == 1 ) {
3294 genModOneByte(left,right,result);
3298 /* should have been converted to function call */
3302 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3303 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3304 freeAsmop(result,NULL,ic,TRUE);
3307 /*-----------------------------------------------------------------*/
3308 /* genIfxJump :- will create a jump depending on the ifx */
3309 /*-----------------------------------------------------------------*/
3311 note: May need to add parameter to indicate when a variable is in bit space.
3313 static void genIfxJump (iCode *ic, char *jval)
3316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3317 /* if true label then we jump if condition
3319 if ( IC_TRUE(ic) ) {
3321 if(strcmp(jval,"a") == 0)
3323 else if (strcmp(jval,"c") == 0)
3326 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3327 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3330 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3331 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3335 /* false label is present */
3336 if(strcmp(jval,"a") == 0)
3338 else if (strcmp(jval,"c") == 0)
3341 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3342 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3345 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3346 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3351 /* mark the icode as generated */
3355 /*-----------------------------------------------------------------*/
3357 /*-----------------------------------------------------------------*/
3358 static void genSkip(iCode *ifx,int status_bit)
3363 if ( IC_TRUE(ifx) ) {
3364 switch(status_bit) {
3379 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3380 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3384 switch(status_bit) {
3398 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3399 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3405 /*-----------------------------------------------------------------*/
3407 /*-----------------------------------------------------------------*/
3408 static void genSkipc(resolvedIfx *rifx)
3418 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3419 rifx->generated = 1;
3422 /*-----------------------------------------------------------------*/
3424 /*-----------------------------------------------------------------*/
3425 static void genSkipz2(resolvedIfx *rifx)
3435 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3436 rifx->generated = 1;
3439 /*-----------------------------------------------------------------*/
3441 /*-----------------------------------------------------------------*/
3442 static void genSkipz(iCode *ifx, int condition)
3453 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3455 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3458 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3460 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3463 /*-----------------------------------------------------------------*/
3465 /*-----------------------------------------------------------------*/
3466 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3472 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3474 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3477 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3478 rifx->generated = 1;
3480 /*-----------------------------------------------------------------*/
3481 /* genCmp :- greater or less than comparison */
3482 /*-----------------------------------------------------------------*/
3483 static void genCmp (operand *left,operand *right,
3484 operand *result, iCode *ifx, int sign)
3486 int size, offset = 0 ;
3487 unsigned long lit = 0L,i = 0;
3490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3492 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3493 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3496 resolveIfx(&rIfx,ifx);
3498 /* if left & right are bit variables */
3499 if (AOP_TYPE(left) == AOP_CRY &&
3500 AOP_TYPE(right) == AOP_CRY ) {
3501 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3502 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3504 /* subtract right from left if at the
3505 end the carry flag is set then we know that
3506 left is greater than right */
3507 size = max(AOP_SIZE(left),AOP_SIZE(right));
3509 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3510 if((size == 1) && !sign &&
3511 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3512 symbol *lbl = newiTempLabel(NULL);
3513 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3514 aopGet(AOP(left),offset,FALSE,FALSE),
3515 aopGet(AOP(right),offset,FALSE,FALSE),
3517 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3520 symbol *lbl = newiTempLabel(NULL);
3522 symbol *truelbl = newiTempLabel(NULL);
3525 if(AOP_TYPE(right) == AOP_LIT) {
3527 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3529 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3533 if(lit == 0 && sign == 0) {
3534 /* no need to compare to 0...*/
3535 if(ifx) ifx->generated = 1;
3542 i = (lit >> (size*8)) & 0xff;
3543 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3548 genSkipCond(&rIfx,left,0,7);
3551 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3555 emitpcode(POC_ADDLW, popGetLit(0x80));
3556 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3558 emitpcode(POC_ADDLW, popGetLit(i));
3563 if(ifx) ifx->generated = 1;
3570 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3575 i = (lit >> (size*8)) & 0xff;
3577 /* handle the first byte differently in signed compares */
3579 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3580 emitpcode(POC_ADDLW, popGetLit(0x80));
3581 emitpcode(POC_ADDLW, popGetLit(((-i)&0xff) ^ 0x80));
3584 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3589 emitpcode(POC_MOVLW, popGetLit(i));
3590 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3593 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3597 emitpLabel(lbl->key);
3600 emitpLabel(truelbl->key);
3602 if(ifx) ifx->generated = 1;
3608 if(AOP_TYPE(left) == AOP_LIT) {
3609 //symbol *lbl = newiTempLabel(NULL);
3611 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3613 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3616 if((lit == 0)&& (sign==0)) {
3619 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3621 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3623 if(ifx) ifx->generated = 1;
3630 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3631 emitpcode(POC_ADDLW, popGetLit(0x80));
3632 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3633 rIfx.condition ^= 1;
3636 genSkipCond(&rIfx,right,0,7);
3641 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3642 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3644 rIfx.condition ^= 1;
3647 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3655 i = (lit >> (size*8)) & 0xff;
3658 /* Handle first byte of compare differently */
3660 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3663 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3664 emitpcode(POC_ADDLW, popGetLit(0x80));
3665 emitpcode(POC_SUBLW, popGetLit( (i & 0xff) ^ 0x80));
3666 //rIfx.condition ^= 1;
3669 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3671 rIfx.condition ^= 1;
3672 genSkipCond(&rIfx,right,size,7);
3673 rIfx.condition ^= 1;
3680 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3681 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3682 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3684 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3686 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3687 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
3688 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3696 emitpLabel(lbl->key);
3698 rIfx.condition ^= 1;
3703 emitpLabel(truelbl->key);
3704 if(ifx) ifx->generated = 1;
3708 /* Compare two variables */
3710 DEBUGpic14_emitcode(";sign","%d",sign);
3714 /* Sigh. thus sucks... */
3716 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3717 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
3718 emitpcode(POC_MOVLW, popGetLit(0x80));
3719 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
3720 emitpcode(POC_XORFW, popGet(AOP(right),size));
3721 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
3723 /* Signed char comparison */
3724 /* Special thanks to Nikolai Golovchenko for this snippet */
3725 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3726 emitpcode(POC_SUBFW, popGet(AOP(left),0));
3727 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
3728 emitpcode(POC_XORFW, popGet(AOP(left),0));
3729 emitpcode(POC_XORFW, popGet(AOP(right),0));
3730 emitpcode(POC_ADDLW, popGetLit(0x80));
3732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3735 if(ifx) ifx->generated = 1;
3741 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3742 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3746 /* The rest of the bytes of a multi-byte compare */
3750 emitpcode(POC_GOTO, popGetLabel(lbl->key));
3753 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3754 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3759 emitpLabel(lbl->key);
3761 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3763 if(ifx) ifx->generated = 1;
3770 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3771 pic14_outBitC(result);
3773 /* if the result is used in the next
3774 ifx conditional branch then generate
3775 code a little differently */
3777 genIfxJump (ifx,"c");
3779 pic14_outBitC(result);
3780 /* leave the result in acc */
3785 /*-----------------------------------------------------------------*/
3786 /* genCmpGt :- greater than comparison */
3787 /*-----------------------------------------------------------------*/
3788 static void genCmpGt (iCode *ic, iCode *ifx)
3790 operand *left, *right, *result;
3791 sym_link *letype , *retype;
3794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3796 right= IC_RIGHT(ic);
3797 result = IC_RESULT(ic);
3799 letype = getSpec(operandType(left));
3800 retype =getSpec(operandType(right));
3801 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3802 /* assign the amsops */
3803 aopOp (left,ic,FALSE);
3804 aopOp (right,ic,FALSE);
3805 aopOp (result,ic,TRUE);
3807 genCmp(right, left, result, ifx, sign);
3809 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3810 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3811 freeAsmop(result,NULL,ic,TRUE);
3814 /*-----------------------------------------------------------------*/
3815 /* genCmpLt - less than comparisons */
3816 /*-----------------------------------------------------------------*/
3817 static void genCmpLt (iCode *ic, iCode *ifx)
3819 operand *left, *right, *result;
3820 sym_link *letype , *retype;
3823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3825 right= IC_RIGHT(ic);
3826 result = IC_RESULT(ic);
3828 letype = getSpec(operandType(left));
3829 retype =getSpec(operandType(right));
3830 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3832 /* assign the amsops */
3833 aopOp (left,ic,FALSE);
3834 aopOp (right,ic,FALSE);
3835 aopOp (result,ic,TRUE);
3837 genCmp(left, right, result, ifx, sign);
3839 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3840 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3841 freeAsmop(result,NULL,ic,TRUE);
3844 /*-----------------------------------------------------------------*/
3845 /* genc16bit2lit - compare a 16 bit value to a literal */
3846 /*-----------------------------------------------------------------*/
3847 static void genc16bit2lit(operand *op, int lit, int offset)
3851 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3852 if( (lit&0xff) == 0)
3857 switch( BYTEofLONG(lit,i)) {
3859 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3862 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3865 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3868 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
3869 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3874 switch( BYTEofLONG(lit,i)) {
3876 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
3880 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
3884 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
3887 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3889 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
3895 /*-----------------------------------------------------------------*/
3896 /* gencjneshort - compare and jump if not equal */
3897 /*-----------------------------------------------------------------*/
3898 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
3900 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3905 unsigned long lit = 0L;
3906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3907 DEBUGpic14_AopType(__LINE__,left,right,NULL);
3909 resolveIfx(&rIfx,ifx);
3910 lbl = newiTempLabel(NULL);
3913 /* if the left side is a literal or
3914 if the right is in a pointer register and left
3916 if ((AOP_TYPE(left) == AOP_LIT) ||
3917 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3922 if(AOP_TYPE(right) == AOP_LIT)
3923 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3925 /* if the right side is a literal then anything goes */
3926 if (AOP_TYPE(right) == AOP_LIT &&
3927 AOP_TYPE(left) != AOP_DIR ) {
3930 genc16bit2lit(left, lit, 0);
3932 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3937 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3938 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3940 emitpcode(POC_MOVF,popGet(AOP(left),offset));
3944 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3952 /* if the right side is in a register or in direct space or
3953 if the left is a pointer register & right is not */
3954 else if (AOP_TYPE(right) == AOP_REG ||
3955 AOP_TYPE(right) == AOP_DIR ||
3956 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3957 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3960 genc16bit2lit(left, lit, 0);
3962 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3967 if((AOP_TYPE(left) == AOP_DIR) &&
3968 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3970 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3971 emitpcode(POC_XORFW,popGet(AOP(right),offset));
3973 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3975 switch (lit & 0xff) {
3977 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3980 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
3981 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3985 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
3986 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3990 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
3991 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3996 emitpcode(POC_MOVF,popGet(AOP(left),offset));
3999 if(AOP_TYPE(result) == AOP_CRY) {
4000 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4005 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4007 /* fix me. probably need to check result size too */
4008 emitpcode(POC_CLRF,popGet(AOP(result),0));
4013 emitpcode(POC_INCF,popGet(AOP(result),0));
4023 } else if(AOP_TYPE(right) == AOP_REG &&
4024 AOP_TYPE(left) != AOP_DIR){
4027 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4028 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4029 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4034 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4039 /* right is a pointer reg need both a & b */
4041 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4043 pic14_emitcode("mov","b,%s",l);
4044 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4045 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4049 emitpLabel(lbl->key);
4056 /*-----------------------------------------------------------------*/
4057 /* gencjne - compare and jump if not equal */
4058 /*-----------------------------------------------------------------*/
4059 static void gencjne(operand *left, operand *right, iCode *ifx)
4061 symbol *tlbl = newiTempLabel(NULL);
4063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4064 gencjneshort(left, right, lbl);
4066 pic14_emitcode("mov","a,%s",one);
4067 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4068 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4069 pic14_emitcode("clr","a");
4070 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4072 emitpLabel(lbl->key);
4073 emitpLabel(tlbl->key);
4078 /*-----------------------------------------------------------------*/
4079 /* genCmpEq - generates code for equal to */
4080 /*-----------------------------------------------------------------*/
4081 static void genCmpEq (iCode *ic, iCode *ifx)
4083 operand *left, *right, *result;
4084 unsigned long lit = 0L;
4087 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4090 DEBUGpic14_emitcode ("; ifx is non-null","");
4092 DEBUGpic14_emitcode ("; ifx is null","");
4094 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4095 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4096 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4098 size = max(AOP_SIZE(left),AOP_SIZE(right));
4100 DEBUGpic14_AopType(__LINE__,left,right,result);
4102 /* if literal, literal on the right or
4103 if the right is in a pointer register and left
4105 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4106 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4107 operand *t = IC_RIGHT(ic);
4108 IC_RIGHT(ic) = IC_LEFT(ic);
4112 if(ifx && !AOP_SIZE(result)){
4114 /* if they are both bit variables */
4115 if (AOP_TYPE(left) == AOP_CRY &&
4116 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4117 if(AOP_TYPE(right) == AOP_LIT){
4118 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4120 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4121 pic14_emitcode("cpl","c");
4122 } else if(lit == 1L) {
4123 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4125 pic14_emitcode("clr","c");
4127 /* AOP_TYPE(right) == AOP_CRY */
4129 symbol *lbl = newiTempLabel(NULL);
4130 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4131 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4132 pic14_emitcode("cpl","c");
4133 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4135 /* if true label then we jump if condition
4137 tlbl = newiTempLabel(NULL);
4138 if ( IC_TRUE(ifx) ) {
4139 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4140 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4142 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4143 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4145 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4148 /* They're not both bit variables. Is the right a literal? */
4149 if(AOP_TYPE(right) == AOP_LIT) {
4150 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4156 switch(lit & 0xff) {
4158 if ( IC_TRUE(ifx) ) {
4159 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4161 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4163 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4164 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4168 if ( IC_TRUE(ifx) ) {
4169 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4171 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4173 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4174 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4178 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4180 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4185 /* end of size == 1 */
4189 genc16bit2lit(left,lit,offset);
4192 /* end of size == 2 */
4197 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4198 emitpcode(POC_IORFW,popGet(AOP(left),1));
4199 emitpcode(POC_IORFW,popGet(AOP(left),2));
4200 emitpcode(POC_IORFW,popGet(AOP(left),3));
4204 /* search for patterns that can be optimized */
4206 genc16bit2lit(left,lit,0);
4209 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4211 genc16bit2lit(left,lit,2);
4213 emitpcode(POC_IORFW,popGet(AOP(left),2));
4214 emitpcode(POC_IORFW,popGet(AOP(left),3));
4227 } else if(AOP_TYPE(right) == AOP_CRY ) {
4228 /* we know the left is not a bit, but that the right is */
4229 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4230 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4231 popGet(AOP(right),offset));
4232 emitpcode(POC_XORLW,popGetLit(1));
4234 /* if the two are equal, then W will be 0 and the Z bit is set
4235 * we could test Z now, or go ahead and check the high order bytes if
4236 * the variable we're comparing is larger than a byte. */
4239 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4241 if ( IC_TRUE(ifx) ) {
4243 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4244 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4247 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4248 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4252 /* They're both variables that are larger than bits */
4255 tlbl = newiTempLabel(NULL);
4258 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4259 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4261 if ( IC_TRUE(ifx) ) {
4264 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4265 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4268 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4269 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4273 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4274 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4278 if(s>1 && IC_TRUE(ifx)) {
4279 emitpLabel(tlbl->key);
4280 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4284 /* mark the icode as generated */
4289 /* if they are both bit variables */
4290 if (AOP_TYPE(left) == AOP_CRY &&
4291 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4292 if(AOP_TYPE(right) == AOP_LIT){
4293 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4295 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4296 pic14_emitcode("cpl","c");
4297 } else if(lit == 1L) {
4298 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4300 pic14_emitcode("clr","c");
4302 /* AOP_TYPE(right) == AOP_CRY */
4304 symbol *lbl = newiTempLabel(NULL);
4305 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4306 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4307 pic14_emitcode("cpl","c");
4308 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4311 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4312 pic14_outBitC(result);
4316 genIfxJump (ifx,"c");
4319 /* if the result is used in an arithmetic operation
4320 then put the result in place */
4321 pic14_outBitC(result);
4324 gencjne(left,right,result,ifx);
4327 gencjne(left,right,newiTempLabel(NULL));
4329 if(IC_TRUE(ifx)->key)
4330 gencjne(left,right,IC_TRUE(ifx)->key);
4332 gencjne(left,right,IC_FALSE(ifx)->key);
4336 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4337 aopPut(AOP(result),"a",0);
4342 genIfxJump (ifx,"a");
4346 /* if the result is used in an arithmetic operation
4347 then put the result in place */
4349 if (AOP_TYPE(result) != AOP_CRY)
4350 pic14_outAcc(result);
4352 /* leave the result in acc */
4356 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4357 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4358 freeAsmop(result,NULL,ic,TRUE);
4361 /*-----------------------------------------------------------------*/
4362 /* ifxForOp - returns the icode containing the ifx for operand */
4363 /*-----------------------------------------------------------------*/
4364 static iCode *ifxForOp ( operand *op, iCode *ic )
4366 /* if true symbol then needs to be assigned */
4367 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4368 if (IS_TRUE_SYMOP(op))
4371 /* if this has register type condition and
4372 the next instruction is ifx with the same operand
4373 and live to of the operand is upto the ifx only then */
4375 ic->next->op == IFX &&
4376 IC_COND(ic->next)->key == op->key &&
4377 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4381 ic->next->op == IFX &&
4382 IC_COND(ic->next)->key == op->key) {
4383 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4387 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4389 ic->next->op == IFX)
4390 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4393 ic->next->op == IFX &&
4394 IC_COND(ic->next)->key == op->key) {
4395 DEBUGpic14_emitcode ("; "," key is okay");
4396 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4397 OP_SYMBOL(op)->liveTo,
4404 /*-----------------------------------------------------------------*/
4405 /* genAndOp - for && operation */
4406 /*-----------------------------------------------------------------*/
4407 static void genAndOp (iCode *ic)
4409 operand *left,*right, *result;
4412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4413 /* note here that && operations that are in an
4414 if statement are taken away by backPatchLabels
4415 only those used in arthmetic operations remain */
4416 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4417 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4418 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4420 /* if both are bit variables */
4421 if (AOP_TYPE(left) == AOP_CRY &&
4422 AOP_TYPE(right) == AOP_CRY ) {
4423 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4424 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4425 pic14_outBitC(result);
4427 tlbl = newiTempLabel(NULL);
4428 pic14_toBoolean(left);
4429 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4430 pic14_toBoolean(right);
4431 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4432 pic14_outBitAcc(result);
4435 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4436 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4437 freeAsmop(result,NULL,ic,TRUE);
4441 /*-----------------------------------------------------------------*/
4442 /* genOrOp - for || operation */
4443 /*-----------------------------------------------------------------*/
4446 modified this code, but it doesn't appear to ever get called
4449 static void genOrOp (iCode *ic)
4451 operand *left,*right, *result;
4454 /* note here that || operations that are in an
4455 if statement are taken away by backPatchLabels
4456 only those used in arthmetic operations remain */
4457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4458 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4459 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4460 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4462 DEBUGpic14_AopType(__LINE__,left,right,result);
4464 /* if both are bit variables */
4465 if (AOP_TYPE(left) == AOP_CRY &&
4466 AOP_TYPE(right) == AOP_CRY ) {
4467 pic14_emitcode("clrc","");
4468 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4469 AOP(left)->aopu.aop_dir,
4470 AOP(left)->aopu.aop_dir);
4471 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4472 AOP(right)->aopu.aop_dir,
4473 AOP(right)->aopu.aop_dir);
4474 pic14_emitcode("setc","");
4477 tlbl = newiTempLabel(NULL);
4478 pic14_toBoolean(left);
4480 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4481 pic14_toBoolean(right);
4482 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4484 pic14_outBitAcc(result);
4487 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4488 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4489 freeAsmop(result,NULL,ic,TRUE);
4492 /*-----------------------------------------------------------------*/
4493 /* isLiteralBit - test if lit == 2^n */
4494 /*-----------------------------------------------------------------*/
4495 static int isLiteralBit(unsigned long lit)
4497 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4498 0x100L,0x200L,0x400L,0x800L,
4499 0x1000L,0x2000L,0x4000L,0x8000L,
4500 0x10000L,0x20000L,0x40000L,0x80000L,
4501 0x100000L,0x200000L,0x400000L,0x800000L,
4502 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4503 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4506 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4507 for(idx = 0; idx < 32; idx++)
4513 /*-----------------------------------------------------------------*/
4514 /* continueIfTrue - */
4515 /*-----------------------------------------------------------------*/
4516 static void continueIfTrue (iCode *ic)
4518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4520 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4524 /*-----------------------------------------------------------------*/
4526 /*-----------------------------------------------------------------*/
4527 static void jumpIfTrue (iCode *ic)
4529 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4531 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4535 /*-----------------------------------------------------------------*/
4536 /* jmpTrueOrFalse - */
4537 /*-----------------------------------------------------------------*/
4538 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4540 // ugly but optimized by peephole
4541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4543 symbol *nlbl = newiTempLabel(NULL);
4544 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4545 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4546 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4547 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4550 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4551 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4556 /*-----------------------------------------------------------------*/
4557 /* genAnd - code for and */
4558 /*-----------------------------------------------------------------*/
4559 static void genAnd (iCode *ic, iCode *ifx)
4561 operand *left, *right, *result;
4563 unsigned long lit = 0L;
4568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4569 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4570 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4571 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4573 resolveIfx(&rIfx,ifx);
4575 /* if left is a literal & right is not then exchange them */
4576 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4577 AOP_NEEDSACC(left)) {
4578 operand *tmp = right ;
4583 /* if result = right then exchange them */
4584 if(pic14_sameRegs(AOP(result),AOP(right))){
4585 operand *tmp = right ;
4590 /* if right is bit then exchange them */
4591 if (AOP_TYPE(right) == AOP_CRY &&
4592 AOP_TYPE(left) != AOP_CRY){
4593 operand *tmp = right ;
4597 if(AOP_TYPE(right) == AOP_LIT)
4598 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4600 size = AOP_SIZE(result);
4602 DEBUGpic14_AopType(__LINE__,left,right,result);
4605 // result = bit & yy;
4606 if (AOP_TYPE(left) == AOP_CRY){
4607 // c = bit & literal;
4608 if(AOP_TYPE(right) == AOP_LIT){
4610 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4613 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4616 if(size && (AOP_TYPE(result) == AOP_CRY)){
4617 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4620 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4624 pic14_emitcode("clr","c");
4627 if (AOP_TYPE(right) == AOP_CRY){
4629 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4630 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4633 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4635 pic14_emitcode("rrc","a");
4636 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4642 pic14_outBitC(result);
4644 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4645 genIfxJump(ifx, "c");
4649 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4650 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4651 if((AOP_TYPE(right) == AOP_LIT) &&
4652 (AOP_TYPE(result) == AOP_CRY) &&
4653 (AOP_TYPE(left) != AOP_CRY)){
4654 int posbit = isLiteralBit(lit);
4658 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4661 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4667 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4668 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4670 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4671 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4674 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4675 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4676 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4683 symbol *tlbl = newiTempLabel(NULL);
4684 int sizel = AOP_SIZE(left);
4686 pic14_emitcode("setb","c");
4688 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4689 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4691 if((posbit = isLiteralBit(bytelit)) != 0)
4692 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4694 if(bytelit != 0x0FFL)
4695 pic14_emitcode("anl","a,%s",
4696 aopGet(AOP(right),offset,FALSE,TRUE));
4697 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4702 // bit = left & literal
4704 pic14_emitcode("clr","c");
4705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4707 // if(left & literal)
4710 jmpTrueOrFalse(ifx, tlbl);
4714 pic14_outBitC(result);
4718 /* if left is same as result */
4719 if(pic14_sameRegs(AOP(result),AOP(left))){
4721 for(;size--; offset++,lit>>=8) {
4722 if(AOP_TYPE(right) == AOP_LIT){
4723 switch(lit & 0xff) {
4725 /* and'ing with 0 has clears the result */
4726 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4727 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4730 /* and'ing with 0xff is a nop when the result and left are the same */
4735 int p = my_powof2( (~lit) & 0xff );
4737 /* only one bit is set in the literal, so use a bcf instruction */
4738 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4739 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4742 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4743 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4744 if(know_W != (lit&0xff))
4745 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4747 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4752 if (AOP_TYPE(left) == AOP_ACC) {
4753 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4755 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4756 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
4763 // left & result in different registers
4764 if(AOP_TYPE(result) == AOP_CRY){
4766 // if(size), result in bit
4767 // if(!size && ifx), conditional oper: if(left & right)
4768 symbol *tlbl = newiTempLabel(NULL);
4769 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4771 pic14_emitcode("setb","c");
4773 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4774 pic14_emitcode("anl","a,%s",
4775 aopGet(AOP(left),offset,FALSE,FALSE));
4776 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4781 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4782 pic14_outBitC(result);
4784 jmpTrueOrFalse(ifx, tlbl);
4786 for(;(size--);offset++) {
4788 // result = left & right
4789 if(AOP_TYPE(right) == AOP_LIT){
4790 int t = (lit >> (offset*8)) & 0x0FFL;
4793 pic14_emitcode("clrf","%s",
4794 aopGet(AOP(result),offset,FALSE,FALSE));
4795 emitpcode(POC_CLRF,popGet(AOP(result),offset));
4798 pic14_emitcode("movf","%s,w",
4799 aopGet(AOP(left),offset,FALSE,FALSE));
4800 pic14_emitcode("movwf","%s",
4801 aopGet(AOP(result),offset,FALSE,FALSE));
4802 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4803 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4806 pic14_emitcode("movlw","0x%x",t);
4807 pic14_emitcode("andwf","%s,w",
4808 aopGet(AOP(left),offset,FALSE,FALSE));
4809 pic14_emitcode("movwf","%s",
4810 aopGet(AOP(result),offset,FALSE,FALSE));
4812 emitpcode(POC_MOVLW, popGetLit(t));
4813 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4814 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4819 if (AOP_TYPE(left) == AOP_ACC) {
4820 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4821 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
4823 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4824 pic14_emitcode("andwf","%s,w",
4825 aopGet(AOP(left),offset,FALSE,FALSE));
4826 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
4827 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
4829 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4830 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
4836 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4837 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4838 freeAsmop(result,NULL,ic,TRUE);
4841 /*-----------------------------------------------------------------*/
4842 /* genOr - code for or */
4843 /*-----------------------------------------------------------------*/
4844 static void genOr (iCode *ic, iCode *ifx)
4846 operand *left, *right, *result;
4848 unsigned long lit = 0L;
4850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4852 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4853 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4854 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4856 DEBUGpic14_AopType(__LINE__,left,right,result);
4858 /* if left is a literal & right is not then exchange them */
4859 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4860 AOP_NEEDSACC(left)) {
4861 operand *tmp = right ;
4866 /* if result = right then exchange them */
4867 if(pic14_sameRegs(AOP(result),AOP(right))){
4868 operand *tmp = right ;
4873 /* if right is bit then exchange them */
4874 if (AOP_TYPE(right) == AOP_CRY &&
4875 AOP_TYPE(left) != AOP_CRY){
4876 operand *tmp = right ;
4881 DEBUGpic14_AopType(__LINE__,left,right,result);
4883 if(AOP_TYPE(right) == AOP_LIT)
4884 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4886 size = AOP_SIZE(result);
4890 if (AOP_TYPE(left) == AOP_CRY){
4891 if(AOP_TYPE(right) == AOP_LIT){
4892 // c = bit & literal;
4894 // lit != 0 => result = 1
4895 if(AOP_TYPE(result) == AOP_CRY){
4897 emitpcode(POC_BSF, popGet(AOP(result),0));
4898 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4899 // AOP(result)->aopu.aop_dir,
4900 // AOP(result)->aopu.aop_dir);
4902 continueIfTrue(ifx);
4906 // lit == 0 => result = left
4907 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4909 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4912 if (AOP_TYPE(right) == AOP_CRY){
4913 if(pic14_sameRegs(AOP(result),AOP(left))){
4915 emitpcode(POC_BCF, popGet(AOP(result),0));
4916 emitpcode(POC_BTFSC, popGet(AOP(right),0));
4917 emitpcode(POC_BSF, popGet(AOP(result),0));
4919 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4920 AOP(result)->aopu.aop_dir,
4921 AOP(result)->aopu.aop_dir);
4922 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4923 AOP(right)->aopu.aop_dir,
4924 AOP(right)->aopu.aop_dir);
4925 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4926 AOP(result)->aopu.aop_dir,
4927 AOP(result)->aopu.aop_dir);
4929 if( AOP_TYPE(result) == AOP_ACC) {
4930 emitpcode(POC_MOVLW, popGetLit(0));
4931 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4932 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4933 emitpcode(POC_MOVLW, popGetLit(1));
4937 emitpcode(POC_BCF, popGet(AOP(result),0));
4938 emitpcode(POC_BTFSS, popGet(AOP(right),0));
4939 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4940 emitpcode(POC_BSF, popGet(AOP(result),0));
4942 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4943 AOP(result)->aopu.aop_dir,
4944 AOP(result)->aopu.aop_dir);
4945 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4946 AOP(right)->aopu.aop_dir,
4947 AOP(right)->aopu.aop_dir);
4948 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4949 AOP(left)->aopu.aop_dir,
4950 AOP(left)->aopu.aop_dir);
4951 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4952 AOP(result)->aopu.aop_dir,
4953 AOP(result)->aopu.aop_dir);
4958 symbol *tlbl = newiTempLabel(NULL);
4959 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4962 emitpcode(POC_BCF, popGet(AOP(result),0));
4963 if( AOP_TYPE(right) == AOP_ACC) {
4964 emitpcode(POC_IORLW, popGetLit(0));
4966 emitpcode(POC_BTFSC, popGet(AOP(left),0));
4967 emitpcode(POC_BSF, popGet(AOP(result),0));
4972 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4973 pic14_emitcode(";XXX setb","c");
4974 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4975 AOP(left)->aopu.aop_dir,tlbl->key+100);
4976 pic14_toBoolean(right);
4977 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4978 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4979 jmpTrueOrFalse(ifx, tlbl);
4983 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4990 pic14_outBitC(result);
4992 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4993 genIfxJump(ifx, "c");
4997 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4998 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4999 if((AOP_TYPE(right) == AOP_LIT) &&
5000 (AOP_TYPE(result) == AOP_CRY) &&
5001 (AOP_TYPE(left) != AOP_CRY)){
5003 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5006 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5008 continueIfTrue(ifx);
5011 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5012 // lit = 0, result = boolean(left)
5014 pic14_emitcode(";XXX setb","c");
5015 pic14_toBoolean(right);
5017 symbol *tlbl = newiTempLabel(NULL);
5018 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5020 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5022 genIfxJump (ifx,"a");
5026 pic14_outBitC(result);
5030 /* if left is same as result */
5031 if(pic14_sameRegs(AOP(result),AOP(left))){
5033 for(;size--; offset++,lit>>=8) {
5034 if(AOP_TYPE(right) == AOP_LIT){
5035 if((lit & 0xff) == 0)
5036 /* or'ing with 0 has no effect */
5039 int p = my_powof2(lit & 0xff);
5041 /* only one bit is set in the literal, so use a bsf instruction */
5043 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5045 if(know_W != (lit & 0xff))
5046 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5047 know_W = lit & 0xff;
5048 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5053 if (AOP_TYPE(left) == AOP_ACC) {
5054 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5055 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5057 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5058 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5060 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5061 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5067 // left & result in different registers
5068 if(AOP_TYPE(result) == AOP_CRY){
5070 // if(size), result in bit
5071 // if(!size && ifx), conditional oper: if(left | right)
5072 symbol *tlbl = newiTempLabel(NULL);
5073 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5074 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5078 pic14_emitcode(";XXX setb","c");
5080 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5081 pic14_emitcode(";XXX orl","a,%s",
5082 aopGet(AOP(left),offset,FALSE,FALSE));
5083 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5088 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5089 pic14_outBitC(result);
5091 jmpTrueOrFalse(ifx, tlbl);
5092 } else for(;(size--);offset++){
5094 // result = left & right
5095 if(AOP_TYPE(right) == AOP_LIT){
5096 int t = (lit >> (offset*8)) & 0x0FFL;
5099 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5100 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5102 pic14_emitcode("movf","%s,w",
5103 aopGet(AOP(left),offset,FALSE,FALSE));
5104 pic14_emitcode("movwf","%s",
5105 aopGet(AOP(result),offset,FALSE,FALSE));
5108 emitpcode(POC_MOVLW, popGetLit(t));
5109 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5110 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5112 pic14_emitcode("movlw","0x%x",t);
5113 pic14_emitcode("iorwf","%s,w",
5114 aopGet(AOP(left),offset,FALSE,FALSE));
5115 pic14_emitcode("movwf","%s",
5116 aopGet(AOP(result),offset,FALSE,FALSE));
5122 // faster than result <- left, anl result,right
5123 // and better if result is SFR
5124 if (AOP_TYPE(left) == AOP_ACC) {
5125 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5126 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5128 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5129 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5131 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5132 pic14_emitcode("iorwf","%s,w",
5133 aopGet(AOP(left),offset,FALSE,FALSE));
5135 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5136 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5141 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5142 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5143 freeAsmop(result,NULL,ic,TRUE);
5146 /*-----------------------------------------------------------------*/
5147 /* genXor - code for xclusive or */
5148 /*-----------------------------------------------------------------*/
5149 static void genXor (iCode *ic, iCode *ifx)
5151 operand *left, *right, *result;
5153 unsigned long lit = 0L;
5155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5157 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5158 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5159 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5161 /* if left is a literal & right is not ||
5162 if left needs acc & right does not */
5163 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5164 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5165 operand *tmp = right ;
5170 /* if result = right then exchange them */
5171 if(pic14_sameRegs(AOP(result),AOP(right))){
5172 operand *tmp = right ;
5177 /* if right is bit then exchange them */
5178 if (AOP_TYPE(right) == AOP_CRY &&
5179 AOP_TYPE(left) != AOP_CRY){
5180 operand *tmp = right ;
5184 if(AOP_TYPE(right) == AOP_LIT)
5185 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5187 size = AOP_SIZE(result);
5191 if (AOP_TYPE(left) == AOP_CRY){
5192 if(AOP_TYPE(right) == AOP_LIT){
5193 // c = bit & literal;
5195 // lit>>1 != 0 => result = 1
5196 if(AOP_TYPE(result) == AOP_CRY){
5198 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5200 continueIfTrue(ifx);
5203 pic14_emitcode("setb","c");
5207 // lit == 0, result = left
5208 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5210 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5212 // lit == 1, result = not(left)
5213 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5214 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5217 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5218 pic14_emitcode("cpl","c");
5225 symbol *tlbl = newiTempLabel(NULL);
5226 if (AOP_TYPE(right) == AOP_CRY){
5228 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5231 int sizer = AOP_SIZE(right);
5233 // if val>>1 != 0, result = 1
5234 pic14_emitcode("setb","c");
5236 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5238 // test the msb of the lsb
5239 pic14_emitcode("anl","a,#0xfe");
5240 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5244 pic14_emitcode("rrc","a");
5246 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5247 pic14_emitcode("cpl","c");
5248 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5253 pic14_outBitC(result);
5255 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5256 genIfxJump(ifx, "c");
5260 if(pic14_sameRegs(AOP(result),AOP(left))){
5261 /* if left is same as result */
5262 for(;size--; offset++) {
5263 if(AOP_TYPE(right) == AOP_LIT){
5264 int t = (lit >> (offset*8)) & 0x0FFL;
5268 if (IS_AOP_PREG(left)) {
5269 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5270 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5271 aopPut(AOP(result),"a",offset);
5273 emitpcode(POC_MOVLW, popGetLit(t));
5274 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5275 pic14_emitcode("xrl","%s,%s",
5276 aopGet(AOP(left),offset,FALSE,TRUE),
5277 aopGet(AOP(right),offset,FALSE,FALSE));
5280 if (AOP_TYPE(left) == AOP_ACC)
5281 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5283 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5284 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5286 if (IS_AOP_PREG(left)) {
5287 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5288 aopPut(AOP(result),"a",offset);
5290 pic14_emitcode("xrl","%s,a",
5291 aopGet(AOP(left),offset,FALSE,TRUE));
5297 // left & result in different registers
5298 if(AOP_TYPE(result) == AOP_CRY){
5300 // if(size), result in bit
5301 // if(!size && ifx), conditional oper: if(left ^ right)
5302 symbol *tlbl = newiTempLabel(NULL);
5303 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5305 pic14_emitcode("setb","c");
5307 if((AOP_TYPE(right) == AOP_LIT) &&
5308 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5309 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5311 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5312 pic14_emitcode("xrl","a,%s",
5313 aopGet(AOP(left),offset,FALSE,FALSE));
5315 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5320 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5321 pic14_outBitC(result);
5323 jmpTrueOrFalse(ifx, tlbl);
5324 } else for(;(size--);offset++){
5326 // result = left & right
5327 if(AOP_TYPE(right) == AOP_LIT){
5328 int t = (lit >> (offset*8)) & 0x0FFL;
5331 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5332 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5333 pic14_emitcode("movf","%s,w",
5334 aopGet(AOP(left),offset,FALSE,FALSE));
5335 pic14_emitcode("movwf","%s",
5336 aopGet(AOP(result),offset,FALSE,FALSE));
5339 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5340 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5341 pic14_emitcode("comf","%s,w",
5342 aopGet(AOP(left),offset,FALSE,FALSE));
5343 pic14_emitcode("movwf","%s",
5344 aopGet(AOP(result),offset,FALSE,FALSE));
5347 emitpcode(POC_MOVLW, popGetLit(t));
5348 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5349 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5350 pic14_emitcode("movlw","0x%x",t);
5351 pic14_emitcode("xorwf","%s,w",
5352 aopGet(AOP(left),offset,FALSE,FALSE));
5353 pic14_emitcode("movwf","%s",
5354 aopGet(AOP(result),offset,FALSE,FALSE));
5360 // faster than result <- left, anl result,right
5361 // and better if result is SFR
5362 if (AOP_TYPE(left) == AOP_ACC) {
5363 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5364 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5366 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5367 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5368 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5369 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5371 if ( AOP_TYPE(result) != AOP_ACC){
5372 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5373 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5379 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5380 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5381 freeAsmop(result,NULL,ic,TRUE);
5384 /*-----------------------------------------------------------------*/
5385 /* genInline - write the inline code out */
5386 /*-----------------------------------------------------------------*/
5387 static void genInline (iCode *ic)
5389 char *buffer, *bp, *bp1;
5391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5393 _G.inLine += (!options.asmpeep);
5395 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5396 strcpy(buffer,IC_INLINE(ic));
5398 /* emit each line as a code */
5402 pic14_emitcode(bp1,"");
5409 pic14_emitcode(bp1,"");
5416 pic14_emitcode(bp1,"");
5417 /* pic14_emitcode("",buffer); */
5418 _G.inLine -= (!options.asmpeep);
5421 /*-----------------------------------------------------------------*/
5422 /* genRRC - rotate right with carry */
5423 /*-----------------------------------------------------------------*/
5424 static void genRRC (iCode *ic)
5426 operand *left , *result ;
5427 int size, offset = 0, same;
5429 /* rotate right with carry */
5431 result=IC_RESULT(ic);
5432 aopOp (left,ic,FALSE);
5433 aopOp (result,ic,FALSE);
5435 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5437 same = pic14_sameRegs(AOP(result),AOP(left));
5439 size = AOP_SIZE(result);
5441 /* get the lsb and put it into the carry */
5442 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5449 emitpcode(POC_RRF, popGet(AOP(left),offset));
5451 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5452 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5458 freeAsmop(left,NULL,ic,TRUE);
5459 freeAsmop(result,NULL,ic,TRUE);
5462 /*-----------------------------------------------------------------*/
5463 /* genRLC - generate code for rotate left with carry */
5464 /*-----------------------------------------------------------------*/
5465 static void genRLC (iCode *ic)
5467 operand *left , *result ;
5468 int size, offset = 0;
5471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5472 /* rotate right with carry */
5474 result=IC_RESULT(ic);
5475 aopOp (left,ic,FALSE);
5476 aopOp (result,ic,FALSE);
5478 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5480 same = pic14_sameRegs(AOP(result),AOP(left));
5482 /* move it to the result */
5483 size = AOP_SIZE(result);
5485 /* get the msb and put it into the carry */
5486 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5493 emitpcode(POC_RLF, popGet(AOP(left),offset));
5495 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5496 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5503 freeAsmop(left,NULL,ic,TRUE);
5504 freeAsmop(result,NULL,ic,TRUE);
5507 /*-----------------------------------------------------------------*/
5508 /* genGetHbit - generates code get highest order bit */
5509 /*-----------------------------------------------------------------*/
5510 static void genGetHbit (iCode *ic)
5512 operand *left, *result;
5514 result=IC_RESULT(ic);
5515 aopOp (left,ic,FALSE);
5516 aopOp (result,ic,FALSE);
5518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5519 /* get the highest order byte into a */
5520 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5521 if(AOP_TYPE(result) == AOP_CRY){
5522 pic14_emitcode("rlc","a");
5523 pic14_outBitC(result);
5526 pic14_emitcode("rl","a");
5527 pic14_emitcode("anl","a,#0x01");
5528 pic14_outAcc(result);
5532 freeAsmop(left,NULL,ic,TRUE);
5533 freeAsmop(result,NULL,ic,TRUE);
5536 /*-----------------------------------------------------------------*/
5537 /* AccRol - rotate left accumulator by known count */
5538 /*-----------------------------------------------------------------*/
5539 static void AccRol (int shCount)
5541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5542 shCount &= 0x0007; // shCount : 0..7
5547 pic14_emitcode("rl","a");
5550 pic14_emitcode("rl","a");
5551 pic14_emitcode("rl","a");
5554 pic14_emitcode("swap","a");
5555 pic14_emitcode("rr","a");
5558 pic14_emitcode("swap","a");
5561 pic14_emitcode("swap","a");
5562 pic14_emitcode("rl","a");
5565 pic14_emitcode("rr","a");
5566 pic14_emitcode("rr","a");
5569 pic14_emitcode("rr","a");
5574 /*-----------------------------------------------------------------*/
5575 /* AccLsh - left shift accumulator by known count */
5576 /*-----------------------------------------------------------------*/
5577 static void AccLsh (int shCount)
5579 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5582 pic14_emitcode("add","a,acc");
5585 pic14_emitcode("add","a,acc");
5586 pic14_emitcode("add","a,acc");
5588 /* rotate left accumulator */
5590 /* and kill the lower order bits */
5591 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5596 /*-----------------------------------------------------------------*/
5597 /* AccRsh - right shift accumulator by known count */
5598 /*-----------------------------------------------------------------*/
5599 static void AccRsh (int shCount)
5601 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5605 pic14_emitcode("rrc","a");
5607 /* rotate right accumulator */
5608 AccRol(8 - shCount);
5609 /* and kill the higher order bits */
5610 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5616 /*-----------------------------------------------------------------*/
5617 /* AccSRsh - signed right shift accumulator by known count */
5618 /*-----------------------------------------------------------------*/
5619 static void AccSRsh (int shCount)
5622 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5625 pic14_emitcode("mov","c,acc.7");
5626 pic14_emitcode("rrc","a");
5627 } else if(shCount == 2){
5628 pic14_emitcode("mov","c,acc.7");
5629 pic14_emitcode("rrc","a");
5630 pic14_emitcode("mov","c,acc.7");
5631 pic14_emitcode("rrc","a");
5633 tlbl = newiTempLabel(NULL);
5634 /* rotate right accumulator */
5635 AccRol(8 - shCount);
5636 /* and kill the higher order bits */
5637 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5638 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5639 pic14_emitcode("orl","a,#0x%02x",
5640 (unsigned char)~SRMask[shCount]);
5641 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5646 /*-----------------------------------------------------------------*/
5647 /* shiftR1Left2Result - shift right one byte from left to result */
5648 /*-----------------------------------------------------------------*/
5649 static void shiftR1Left2ResultSigned (operand *left, int offl,
5650 operand *result, int offr,
5655 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5657 same = (left == result) || (AOP(left) == AOP(result));
5661 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5663 emitpcode(POC_RRF, popGet(AOP(result),offr));
5665 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5666 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5676 /*-----------------------------------------------------------------*/
5677 /* shiftR1Left2Result - shift right one byte from left to result */
5678 /*-----------------------------------------------------------------*/
5679 static void shiftR1Left2Result (operand *left, int offl,
5680 operand *result, int offr,
5681 int shCount, int sign)
5685 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5687 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5689 /* Copy the msb into the carry if signed. */
5691 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5701 emitpcode(POC_RRF, popGet(AOP(result),offr));
5703 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5704 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5710 emitpcode(POC_RRF, popGet(AOP(result),offr));
5712 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5713 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5716 emitpcode(POC_RRF, popGet(AOP(result),offr));
5721 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5723 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5724 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5727 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5728 emitpcode(POC_RLFW, popGet(AOP(result),offr));
5729 emitpcode(POC_ANDLW, popGetLit(0x1f));
5730 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5734 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5735 emitpcode(POC_ANDLW, popGetLit(0x0f));
5736 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5740 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
5741 emitpcode(POC_ANDLW, popGetLit(0x0f));
5742 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5744 emitpcode(POC_RRF, popGet(AOP(result),offr));
5749 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5750 emitpcode(POC_ANDLW, popGetLit(0x80));
5751 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5752 emitpcode(POC_RLF, popGet(AOP(result),offr));
5753 emitpcode(POC_RLF, popGet(AOP(result),offr));
5758 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5759 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5760 emitpcode(POC_RLF, popGet(AOP(result),offr));
5771 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5773 /* shift right accumulator */
5778 aopPut(AOP(result),"a",offr);
5782 /*-----------------------------------------------------------------*/
5783 /* shiftL1Left2Result - shift left one byte from left to result */
5784 /*-----------------------------------------------------------------*/
5785 static void shiftL1Left2Result (operand *left, int offl,
5786 operand *result, int offr, int shCount)
5791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5793 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5794 DEBUGpic14_emitcode ("; ***","same = %d",same);
5795 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5797 /* shift left accumulator */
5798 //AccLsh(shCount); // don't comment out just yet...
5799 // aopPut(AOP(result),"a",offr);
5803 /* Shift left 1 bit position */
5804 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5806 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
5808 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
5809 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5813 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5814 emitpcode(POC_ANDLW,popGetLit(0x7e));
5815 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5816 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5819 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5820 emitpcode(POC_ANDLW,popGetLit(0x3e));
5821 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5822 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5823 emitpcode(POC_RLF, popGet(AOP(result),offr));
5826 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5827 emitpcode(POC_ANDLW, popGetLit(0xf0));
5828 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5831 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5832 emitpcode(POC_ANDLW, popGetLit(0xf0));
5833 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5834 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5837 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5838 emitpcode(POC_ANDLW, popGetLit(0x30));
5839 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
5840 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5841 emitpcode(POC_RLF, popGet(AOP(result),offr));
5844 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5845 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5846 emitpcode(POC_RRF, popGet(AOP(result),offr));
5850 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5855 /*-----------------------------------------------------------------*/
5856 /* movLeft2Result - move byte from left to result */
5857 /*-----------------------------------------------------------------*/
5858 static void movLeft2Result (operand *left, int offl,
5859 operand *result, int offr, int sign)
5862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5863 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5864 l = aopGet(AOP(left),offl,FALSE,FALSE);
5866 if (*l == '@' && (IS_AOP_PREG(result))) {
5867 pic14_emitcode("mov","a,%s",l);
5868 aopPut(AOP(result),"a",offr);
5871 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5872 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5874 //aopPut(AOP(result),l,offr);
5876 /* MSB sign in acc.7 ! */
5877 if(pic14_getDataSize(left) == offl+1){
5878 pic14_emitcode("mov","a,%s",l);
5879 aopPut(AOP(result),"a",offr);
5886 /*-----------------------------------------------------------------*/
5887 /* shiftL2Left2Result - shift left two bytes from left to result */
5888 /*-----------------------------------------------------------------*/
5889 static void shiftL2Left2Result (operand *left, int offl,
5890 operand *result, int offr, int shCount)
5894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5896 if(pic14_sameRegs(AOP(result), AOP(left))) {
5904 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
5905 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
5906 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5910 emitpcode(POC_RLF, popGet(AOP(result),offr));
5911 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5917 emitpcode(POC_MOVLW, popGetLit(0x0f));
5918 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
5919 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
5920 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
5921 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
5922 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5923 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5925 emitpcode(POC_RLF, popGet(AOP(result),offr));
5926 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5930 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5931 emitpcode(POC_RRF, popGet(AOP(result),offr));
5932 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5933 emitpcode(POC_RRF, popGet(AOP(result),offr));
5934 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5935 emitpcode(POC_ANDLW,popGetLit(0xc0));
5936 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5937 emitpcode(POC_XORWF,popGet(AOP(result),offr));
5938 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5939 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5942 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5943 emitpcode(POC_RRFW, popGet(AOP(result),offr));
5944 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5945 emitpcode(POC_CLRF, popGet(AOP(result),offr));
5946 emitpcode(POC_RRF, popGet(AOP(result),offr));
5956 /* note, use a mov/add for the shift since the mov has a
5957 chance of getting optimized out */
5958 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
5959 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5960 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
5961 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
5962 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5966 emitpcode(POC_RLF, popGet(AOP(result),offr));
5967 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5973 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
5974 emitpcode(POC_ANDLW, popGetLit(0xF0));
5975 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
5976 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
5977 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5978 emitpcode(POC_ANDLW, popGetLit(0xF0));
5979 emitpcode(POC_XORWF, popGet(AOP(result),offr));
5980 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
5984 emitpcode(POC_RLF, popGet(AOP(result),offr));
5985 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
5989 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
5990 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
5991 emitpcode(POC_RRFW, popGet(AOP(result),offl));
5992 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5994 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
5995 emitpcode(POC_RRF, popGet(AOP(result),offr));
5996 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
5997 emitpcode(POC_ANDLW,popGetLit(0xc0));
5998 emitpcode(POC_XORFW,popGet(AOP(result),offr));
5999 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6000 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6001 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6004 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6005 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6006 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6007 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6008 emitpcode(POC_RRF, popGet(AOP(result),offr));
6013 /*-----------------------------------------------------------------*/
6014 /* shiftR2Left2Result - shift right two bytes from left to result */
6015 /*-----------------------------------------------------------------*/
6016 static void shiftR2Left2Result (operand *left, int offl,
6017 operand *result, int offr,
6018 int shCount, int sign)
6022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6023 same = pic14_sameRegs(AOP(result), AOP(left));
6025 if(same && ((offl + MSB16) == offr)){
6027 /* don't crash result[offr] */
6028 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6029 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6031 movLeft2Result(left,offl, result, offr, 0);
6032 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6034 /* a:x >> shCount (x = lsb(result))*/
6037 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6039 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6049 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6050 emitpcode(POC_RRF,popGet(AOP(result),offr));
6053 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6054 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6055 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6056 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6061 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6062 emitpcode(POC_RRF,popGet(AOP(result),offr));
6069 emitpcode(POC_MOVLW, popGetLit(0xf0));
6070 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6071 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6073 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6074 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6075 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6076 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6078 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6079 emitpcode(POC_ANDLW, popGetLit(0x0f));
6080 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6082 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6083 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6084 emitpcode(POC_ANDLW, popGetLit(0xf0));
6085 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6086 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6090 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6091 emitpcode(POC_RRF, popGet(AOP(result),offr));
6099 emitpcode(POC_RLF, popGet(AOP(result),offr));
6100 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6102 emitpcode(POC_RLF, popGet(AOP(result),offr));
6103 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6104 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6105 emitpcode(POC_ANDLW,popGetLit(0x03));
6106 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6107 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6108 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6109 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6111 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6112 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6113 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6114 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6115 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6116 emitpcode(POC_RLF, popGet(AOP(result),offr));
6117 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6118 emitpcode(POC_ANDLW,popGetLit(0x03));
6119 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6124 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6125 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6126 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6127 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6128 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6133 /*-----------------------------------------------------------------*/
6134 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6135 /*-----------------------------------------------------------------*/
6136 static void shiftLLeftOrResult (operand *left, int offl,
6137 operand *result, int offr, int shCount)
6139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6140 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6141 /* shift left accumulator */
6143 /* or with result */
6144 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6145 /* back to result */
6146 aopPut(AOP(result),"a",offr);
6149 /*-----------------------------------------------------------------*/
6150 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6151 /*-----------------------------------------------------------------*/
6152 static void shiftRLeftOrResult (operand *left, int offl,
6153 operand *result, int offr, int shCount)
6155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6156 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6157 /* shift right accumulator */
6159 /* or with result */
6160 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6161 /* back to result */
6162 aopPut(AOP(result),"a",offr);
6165 /*-----------------------------------------------------------------*/
6166 /* genlshOne - left shift a one byte quantity by known count */
6167 /*-----------------------------------------------------------------*/
6168 static void genlshOne (operand *result, operand *left, int shCount)
6170 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6171 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6174 /*-----------------------------------------------------------------*/
6175 /* genlshTwo - left shift two bytes by known amount != 0 */
6176 /*-----------------------------------------------------------------*/
6177 static void genlshTwo (operand *result,operand *left, int shCount)
6181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6182 size = pic14_getDataSize(result);
6184 /* if shCount >= 8 */
6190 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6192 movLeft2Result(left, LSB, result, MSB16, 0);
6194 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6197 /* 1 <= shCount <= 7 */
6200 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6202 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6206 /*-----------------------------------------------------------------*/
6207 /* shiftLLong - shift left one long from left to result */
6208 /* offl = LSB or MSB16 */
6209 /*-----------------------------------------------------------------*/
6210 static void shiftLLong (operand *left, operand *result, int offr )
6213 int size = AOP_SIZE(result);
6215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6216 if(size >= LSB+offr){
6217 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6219 pic14_emitcode("add","a,acc");
6220 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6221 size >= MSB16+offr && offr != LSB )
6222 pic14_emitcode("xch","a,%s",
6223 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6225 aopPut(AOP(result),"a",LSB+offr);
6228 if(size >= MSB16+offr){
6229 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6230 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6233 pic14_emitcode("rlc","a");
6234 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6235 size >= MSB24+offr && offr != LSB)
6236 pic14_emitcode("xch","a,%s",
6237 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6239 aopPut(AOP(result),"a",MSB16+offr);
6242 if(size >= MSB24+offr){
6243 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6244 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6247 pic14_emitcode("rlc","a");
6248 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6249 size >= MSB32+offr && offr != LSB )
6250 pic14_emitcode("xch","a,%s",
6251 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6253 aopPut(AOP(result),"a",MSB24+offr);
6256 if(size > MSB32+offr){
6257 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6258 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6261 pic14_emitcode("rlc","a");
6262 aopPut(AOP(result),"a",MSB32+offr);
6265 aopPut(AOP(result),zero,LSB);
6268 /*-----------------------------------------------------------------*/
6269 /* genlshFour - shift four byte by a known amount != 0 */
6270 /*-----------------------------------------------------------------*/
6271 static void genlshFour (operand *result, operand *left, int shCount)
6275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6276 size = AOP_SIZE(result);
6278 /* if shifting more that 3 bytes */
6279 if (shCount >= 24 ) {
6282 /* lowest order of left goes to the highest
6283 order of the destination */
6284 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6286 movLeft2Result(left, LSB, result, MSB32, 0);
6287 aopPut(AOP(result),zero,LSB);
6288 aopPut(AOP(result),zero,MSB16);
6289 aopPut(AOP(result),zero,MSB32);
6293 /* more than two bytes */
6294 else if ( shCount >= 16 ) {
6295 /* lower order two bytes goes to higher order two bytes */
6297 /* if some more remaining */
6299 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6301 movLeft2Result(left, MSB16, result, MSB32, 0);
6302 movLeft2Result(left, LSB, result, MSB24, 0);
6304 aopPut(AOP(result),zero,MSB16);
6305 aopPut(AOP(result),zero,LSB);
6309 /* if more than 1 byte */
6310 else if ( shCount >= 8 ) {
6311 /* lower order three bytes goes to higher order three bytes */
6315 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6317 movLeft2Result(left, LSB, result, MSB16, 0);
6319 else{ /* size = 4 */
6321 movLeft2Result(left, MSB24, result, MSB32, 0);
6322 movLeft2Result(left, MSB16, result, MSB24, 0);
6323 movLeft2Result(left, LSB, result, MSB16, 0);
6324 aopPut(AOP(result),zero,LSB);
6326 else if(shCount == 1)
6327 shiftLLong(left, result, MSB16);
6329 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6330 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6331 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6332 aopPut(AOP(result),zero,LSB);
6337 /* 1 <= shCount <= 7 */
6338 else if(shCount <= 2){
6339 shiftLLong(left, result, LSB);
6341 shiftLLong(result, result, LSB);
6343 /* 3 <= shCount <= 7, optimize */
6345 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6346 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6347 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6351 /*-----------------------------------------------------------------*/
6352 /* genLeftShiftLiteral - left shifting by known count */
6353 /*-----------------------------------------------------------------*/
6354 static void genLeftShiftLiteral (operand *left,
6359 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6363 freeAsmop(right,NULL,ic,TRUE);
6365 aopOp(left,ic,FALSE);
6366 aopOp(result,ic,FALSE);
6368 size = getSize(operandType(result));
6371 pic14_emitcode("; shift left ","result %d, left %d",size,
6375 /* I suppose that the left size >= result size */
6378 movLeft2Result(left, size, result, size, 0);
6382 else if(shCount >= (size * 8))
6384 aopPut(AOP(result),zero,size);
6388 genlshOne (result,left,shCount);
6393 genlshTwo (result,left,shCount);
6397 genlshFour (result,left,shCount);
6401 freeAsmop(left,NULL,ic,TRUE);
6402 freeAsmop(result,NULL,ic,TRUE);
6405 /*-----------------------------------------------------------------*/
6406 /* genLeftShift - generates code for left shifting */
6407 /*-----------------------------------------------------------------*/
6408 static void genLeftShift (iCode *ic)
6410 operand *left,*right, *result;
6413 symbol *tlbl , *tlbl1;
6415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6417 right = IC_RIGHT(ic);
6419 result = IC_RESULT(ic);
6421 aopOp(right,ic,FALSE);
6423 /* if the shift count is known then do it
6424 as efficiently as possible */
6425 if (AOP_TYPE(right) == AOP_LIT) {
6426 genLeftShiftLiteral (left,right,result,ic);
6430 /* shift count is unknown then we have to form
6431 a loop get the loop count in B : Note: we take
6432 only the lower order byte since shifting
6433 more that 32 bits make no sense anyway, ( the
6434 largest size of an object can be only 32 bits ) */
6437 aopOp(left,ic,FALSE);
6438 aopOp(result,ic,FALSE);
6440 /* now move the left to the result if they are not the
6442 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6443 AOP_SIZE(result) > 1) {
6445 size = AOP_SIZE(result);
6448 l = aopGet(AOP(left),offset,FALSE,TRUE);
6449 if (*l == '@' && (IS_AOP_PREG(result))) {
6451 pic14_emitcode("mov","a,%s",l);
6452 aopPut(AOP(result),"a",offset);
6454 aopPut(AOP(result),l,offset);
6459 size = AOP_SIZE(result);
6461 /* if it is only one byte then */
6463 if(optimized_for_speed) {
6464 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6465 emitpcode(POC_ANDLW, popGetLit(0xf0));
6466 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6467 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6468 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6469 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6470 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6471 emitpcode(POC_RLFW, popGet(AOP(result),0));
6472 emitpcode(POC_ANDLW, popGetLit(0xfe));
6473 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6474 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6475 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6478 tlbl = newiTempLabel(NULL);
6479 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6480 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6481 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6484 emitpcode(POC_COMFW, popGet(AOP(right),0));
6485 emitpcode(POC_RRF, popGet(AOP(result),0));
6486 emitpLabel(tlbl->key);
6487 emitpcode(POC_RLF, popGet(AOP(result),0));
6488 emitpcode(POC_ADDLW, popGetLit(1));
6490 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6496 tlbl = newiTempLabel(NULL);
6498 tlbl1 = newiTempLabel(NULL);
6500 reAdjustPreg(AOP(result));
6502 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6503 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6504 l = aopGet(AOP(result),offset,FALSE,FALSE);
6506 pic14_emitcode("add","a,acc");
6507 aopPut(AOP(result),"a",offset++);
6509 l = aopGet(AOP(result),offset,FALSE,FALSE);
6511 pic14_emitcode("rlc","a");
6512 aopPut(AOP(result),"a",offset++);
6514 reAdjustPreg(AOP(result));
6516 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6517 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6519 freeAsmop (right,NULL,ic,TRUE);
6520 freeAsmop(left,NULL,ic,TRUE);
6521 freeAsmop(result,NULL,ic,TRUE);
6524 /*-----------------------------------------------------------------*/
6525 /* genrshOne - right shift a one byte quantity by known count */
6526 /*-----------------------------------------------------------------*/
6527 static void genrshOne (operand *result, operand *left,
6528 int shCount, int sign)
6530 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6531 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6534 /*-----------------------------------------------------------------*/
6535 /* genrshTwo - right shift two bytes by known amount != 0 */
6536 /*-----------------------------------------------------------------*/
6537 static void genrshTwo (operand *result,operand *left,
6538 int shCount, int sign)
6540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6541 /* if shCount >= 8 */
6545 shiftR1Left2Result(left, MSB16, result, LSB,
6548 movLeft2Result(left, MSB16, result, LSB, sign);
6550 addSign(result, MSB16, sign);
6552 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6556 /* 1 <= shCount <= 7 */
6558 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6561 /*-----------------------------------------------------------------*/
6562 /* shiftRLong - shift right one long from left to result */
6563 /* offl = LSB or MSB16 */
6564 /*-----------------------------------------------------------------*/
6565 static void shiftRLong (operand *left, int offl,
6566 operand *result, int sign)
6568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6570 pic14_emitcode("clr","c");
6571 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6573 pic14_emitcode("mov","c,acc.7");
6574 pic14_emitcode("rrc","a");
6575 aopPut(AOP(result),"a",MSB32-offl);
6577 /* add sign of "a" */
6578 addSign(result, MSB32, sign);
6580 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6581 pic14_emitcode("rrc","a");
6582 aopPut(AOP(result),"a",MSB24-offl);
6584 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6585 pic14_emitcode("rrc","a");
6586 aopPut(AOP(result),"a",MSB16-offl);
6589 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6590 pic14_emitcode("rrc","a");
6591 aopPut(AOP(result),"a",LSB);
6595 /*-----------------------------------------------------------------*/
6596 /* genrshFour - shift four byte by a known amount != 0 */
6597 /*-----------------------------------------------------------------*/
6598 static void genrshFour (operand *result, operand *left,
6599 int shCount, int sign)
6601 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6602 /* if shifting more that 3 bytes */
6603 if(shCount >= 24 ) {
6606 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6608 movLeft2Result(left, MSB32, result, LSB, sign);
6609 addSign(result, MSB16, sign);
6611 else if(shCount >= 16){
6614 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6616 movLeft2Result(left, MSB24, result, LSB, 0);
6617 movLeft2Result(left, MSB32, result, MSB16, sign);
6619 addSign(result, MSB24, sign);
6621 else if(shCount >= 8){
6624 shiftRLong(left, MSB16, result, sign);
6625 else if(shCount == 0){
6626 movLeft2Result(left, MSB16, result, LSB, 0);
6627 movLeft2Result(left, MSB24, result, MSB16, 0);
6628 movLeft2Result(left, MSB32, result, MSB24, sign);
6629 addSign(result, MSB32, sign);
6632 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6633 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6634 /* the last shift is signed */
6635 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6636 addSign(result, MSB32, sign);
6639 else{ /* 1 <= shCount <= 7 */
6641 shiftRLong(left, LSB, result, sign);
6643 shiftRLong(result, LSB, result, sign);
6646 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6647 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6648 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6653 /*-----------------------------------------------------------------*/
6654 /* genRightShiftLiteral - right shifting by known count */
6655 /*-----------------------------------------------------------------*/
6656 static void genRightShiftLiteral (operand *left,
6662 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6665 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6666 freeAsmop(right,NULL,ic,TRUE);
6668 aopOp(left,ic,FALSE);
6669 aopOp(result,ic,FALSE);
6672 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6676 size = pic14_getDataSize(left);
6677 /* test the LEFT size !!! */
6679 /* I suppose that the left size >= result size */
6681 size = pic14_getDataSize(result);
6683 movLeft2Result(left, size, result, size, 0);
6686 else if(shCount >= (size * 8)){
6688 /* get sign in acc.7 */
6689 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6690 addSign(result, LSB, sign);
6694 genrshOne (result,left,shCount,sign);
6698 genrshTwo (result,left,shCount,sign);
6702 genrshFour (result,left,shCount,sign);
6708 freeAsmop(left,NULL,ic,TRUE);
6709 freeAsmop(result,NULL,ic,TRUE);
6713 /*-----------------------------------------------------------------*/
6714 /* genSignedRightShift - right shift of signed number */
6715 /*-----------------------------------------------------------------*/
6716 static void genSignedRightShift (iCode *ic)
6718 operand *right, *left, *result;
6721 symbol *tlbl, *tlbl1 ;
6723 /* we do it the hard way put the shift count in b
6724 and loop thru preserving the sign */
6725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6727 right = IC_RIGHT(ic);
6729 result = IC_RESULT(ic);
6731 aopOp(right,ic,FALSE);
6734 if ( AOP_TYPE(right) == AOP_LIT) {
6735 genRightShiftLiteral (left,right,result,ic,1);
6738 /* shift count is unknown then we have to form
6739 a loop get the loop count in B : Note: we take
6740 only the lower order byte since shifting
6741 more that 32 bits make no sense anyway, ( the
6742 largest size of an object can be only 32 bits ) */
6744 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6745 pic14_emitcode("inc","b");
6746 freeAsmop (right,NULL,ic,TRUE);
6747 aopOp(left,ic,FALSE);
6748 aopOp(result,ic,FALSE);
6750 /* now move the left to the result if they are not the
6752 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6753 AOP_SIZE(result) > 1) {
6755 size = AOP_SIZE(result);
6758 l = aopGet(AOP(left),offset,FALSE,TRUE);
6759 if (*l == '@' && IS_AOP_PREG(result)) {
6761 pic14_emitcode("mov","a,%s",l);
6762 aopPut(AOP(result),"a",offset);
6764 aopPut(AOP(result),l,offset);
6769 /* mov the highest order bit to OVR */
6770 tlbl = newiTempLabel(NULL);
6771 tlbl1= newiTempLabel(NULL);
6773 size = AOP_SIZE(result);
6775 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6776 pic14_emitcode("rlc","a");
6777 pic14_emitcode("mov","ov,c");
6778 /* if it is only one byte then */
6780 l = aopGet(AOP(left),0,FALSE,FALSE);
6782 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6783 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6784 pic14_emitcode("mov","c,ov");
6785 pic14_emitcode("rrc","a");
6786 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6787 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6788 aopPut(AOP(result),"a",0);
6792 reAdjustPreg(AOP(result));
6793 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6794 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6795 pic14_emitcode("mov","c,ov");
6797 l = aopGet(AOP(result),offset,FALSE,FALSE);
6799 pic14_emitcode("rrc","a");
6800 aopPut(AOP(result),"a",offset--);
6802 reAdjustPreg(AOP(result));
6803 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6804 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6807 freeAsmop(left,NULL,ic,TRUE);
6808 freeAsmop(result,NULL,ic,TRUE);
6811 /*-----------------------------------------------------------------*/
6812 /* genRightShift - generate code for right shifting */
6813 /*-----------------------------------------------------------------*/
6814 static void genRightShift (iCode *ic)
6816 operand *right, *left, *result;
6820 symbol *tlbl, *tlbl1 ;
6822 /* if signed then we do it the hard way preserve the
6823 sign bit moving it inwards */
6824 retype = getSpec(operandType(IC_RESULT(ic)));
6825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6827 if (!SPEC_USIGN(retype)) {
6828 genSignedRightShift (ic);
6832 /* signed & unsigned types are treated the same : i.e. the
6833 signed is NOT propagated inwards : quoting from the
6834 ANSI - standard : "for E1 >> E2, is equivalent to division
6835 by 2**E2 if unsigned or if it has a non-negative value,
6836 otherwise the result is implementation defined ", MY definition
6837 is that the sign does not get propagated */
6839 right = IC_RIGHT(ic);
6841 result = IC_RESULT(ic);
6843 aopOp(right,ic,FALSE);
6845 /* if the shift count is known then do it
6846 as efficiently as possible */
6847 if (AOP_TYPE(right) == AOP_LIT) {
6848 genRightShiftLiteral (left,right,result,ic, 0);
6852 /* shift count is unknown then we have to form
6853 a loop get the loop count in B : Note: we take
6854 only the lower order byte since shifting
6855 more that 32 bits make no sense anyway, ( the
6856 largest size of an object can be only 32 bits ) */
6858 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6859 pic14_emitcode("inc","b");
6860 aopOp(left,ic,FALSE);
6861 aopOp(result,ic,FALSE);
6863 /* now move the left to the result if they are not the
6865 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6866 AOP_SIZE(result) > 1) {
6868 size = AOP_SIZE(result);
6871 l = aopGet(AOP(left),offset,FALSE,TRUE);
6872 if (*l == '@' && IS_AOP_PREG(result)) {
6874 pic14_emitcode("mov","a,%s",l);
6875 aopPut(AOP(result),"a",offset);
6877 aopPut(AOP(result),l,offset);
6882 tlbl = newiTempLabel(NULL);
6883 tlbl1= newiTempLabel(NULL);
6884 size = AOP_SIZE(result);
6887 /* if it is only one byte then */
6890 l = aopGet(AOP(left),0,FALSE,FALSE);
6892 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6893 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6895 pic14_emitcode("rrc","a");
6896 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6897 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6898 aopPut(AOP(result),"a",0);
6900 tlbl = newiTempLabel(NULL);
6901 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6902 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6903 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6906 emitpcode(POC_COMFW, popGet(AOP(right),0));
6907 emitpcode(POC_RLF, popGet(AOP(result),0));
6908 emitpLabel(tlbl->key);
6909 emitpcode(POC_RRF, popGet(AOP(result),0));
6910 emitpcode(POC_ADDLW, popGetLit(1));
6912 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6917 reAdjustPreg(AOP(result));
6918 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6919 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6922 l = aopGet(AOP(result),offset,FALSE,FALSE);
6924 pic14_emitcode("rrc","a");
6925 aopPut(AOP(result),"a",offset--);
6927 reAdjustPreg(AOP(result));
6929 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6930 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6933 freeAsmop(left,NULL,ic,TRUE);
6934 freeAsmop (right,NULL,ic,TRUE);
6935 freeAsmop(result,NULL,ic,TRUE);
6938 /*-----------------------------------------------------------------*/
6939 /* genUnpackBits - generates code for unpacking bits */
6940 /*-----------------------------------------------------------------*/
6941 static void genUnpackBits (operand *result, char *rname, int ptype)
6948 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6949 etype = getSpec(operandType(result));
6951 /* read the first byte */
6956 pic14_emitcode("mov","a,@%s",rname);
6960 pic14_emitcode("movx","a,@%s",rname);
6964 pic14_emitcode("movx","a,@dptr");
6968 pic14_emitcode("clr","a");
6969 pic14_emitcode("movc","a","@a+dptr");
6973 pic14_emitcode("lcall","__gptrget");
6977 /* if we have bitdisplacement then it fits */
6978 /* into this byte completely or if length is */
6979 /* less than a byte */
6980 if ((shCnt = SPEC_BSTR(etype)) ||
6981 (SPEC_BLEN(etype) <= 8)) {
6983 /* shift right acc */
6986 pic14_emitcode("anl","a,#0x%02x",
6987 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
6988 aopPut(AOP(result),"a",offset);
6992 /* bit field did not fit in a byte */
6993 rlen = SPEC_BLEN(etype) - 8;
6994 aopPut(AOP(result),"a",offset++);
7001 pic14_emitcode("inc","%s",rname);
7002 pic14_emitcode("mov","a,@%s",rname);
7006 pic14_emitcode("inc","%s",rname);
7007 pic14_emitcode("movx","a,@%s",rname);
7011 pic14_emitcode("inc","dptr");
7012 pic14_emitcode("movx","a,@dptr");
7016 pic14_emitcode("clr","a");
7017 pic14_emitcode("inc","dptr");
7018 pic14_emitcode("movc","a","@a+dptr");
7022 pic14_emitcode("inc","dptr");
7023 pic14_emitcode("lcall","__gptrget");
7028 /* if we are done */
7032 aopPut(AOP(result),"a",offset++);
7037 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7038 aopPut(AOP(result),"a",offset);
7045 /*-----------------------------------------------------------------*/
7046 /* genDataPointerGet - generates code when ptr offset is known */
7047 /*-----------------------------------------------------------------*/
7048 static void genDataPointerGet (operand *left,
7052 int size , offset = 0;
7055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7058 /* optimization - most of the time, left and result are the same
7059 * address, but different types. for the pic code, we could omit
7063 aopOp(result,ic,TRUE);
7065 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7067 size = AOP_SIZE(result);
7070 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7074 freeAsmop(left,NULL,ic,TRUE);
7075 freeAsmop(result,NULL,ic,TRUE);
7078 /*-----------------------------------------------------------------*/
7079 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7080 /*-----------------------------------------------------------------*/
7081 static void genNearPointerGet (operand *left,
7088 sym_link *rtype, *retype;
7089 sym_link *ltype = operandType(left);
7092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7094 rtype = operandType(result);
7095 retype= getSpec(rtype);
7097 aopOp(left,ic,FALSE);
7099 /* if left is rematerialisable and
7100 result is not bit variable type and
7101 the left is pointer to data space i.e
7102 lower 128 bytes of space */
7103 if (AOP_TYPE(left) == AOP_IMMD &&
7104 !IS_BITVAR(retype) &&
7105 DCL_TYPE(ltype) == POINTER) {
7106 genDataPointerGet (left,result,ic);
7110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7112 /* if the value is already in a pointer register
7113 then don't need anything more */
7114 if (!AOP_INPREG(AOP(left))) {
7115 /* otherwise get a free pointer register */
7116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7118 preg = getFreePtr(ic,&aop,FALSE);
7119 pic14_emitcode("mov","%s,%s",
7121 aopGet(AOP(left),0,FALSE,TRUE));
7122 rname = preg->name ;
7124 rname = aopGet(AOP(left),0,FALSE,FALSE);
7126 freeAsmop(left,NULL,ic,TRUE);
7127 aopOp (result,ic,FALSE);
7129 /* if bitfield then unpack the bits */
7130 if (IS_BITVAR(retype))
7131 genUnpackBits (result,rname,POINTER);
7133 /* we have can just get the values */
7134 int size = AOP_SIZE(result);
7137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7139 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7141 pic14_emitcode("mov","a,@%s",rname);
7142 aopPut(AOP(result),"a",offset);
7144 sprintf(buffer,"@%s",rname);
7145 aopPut(AOP(result),buffer,offset);
7149 pic14_emitcode("inc","%s",rname);
7153 /* now some housekeeping stuff */
7155 /* we had to allocate for this iCode */
7156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7157 freeAsmop(NULL,aop,ic,TRUE);
7159 /* we did not allocate which means left
7160 already in a pointer register, then
7161 if size > 0 && this could be used again
7162 we have to point it back to where it
7164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7165 if (AOP_SIZE(result) > 1 &&
7166 !OP_SYMBOL(left)->remat &&
7167 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7169 int size = AOP_SIZE(result) - 1;
7171 pic14_emitcode("dec","%s",rname);
7176 freeAsmop(result,NULL,ic,TRUE);
7180 /*-----------------------------------------------------------------*/
7181 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7182 /*-----------------------------------------------------------------*/
7183 static void genPagedPointerGet (operand *left,
7190 sym_link *rtype, *retype;
7192 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7194 rtype = operandType(result);
7195 retype= getSpec(rtype);
7197 aopOp(left,ic,FALSE);
7199 /* if the value is already in a pointer register
7200 then don't need anything more */
7201 if (!AOP_INPREG(AOP(left))) {
7202 /* otherwise get a free pointer register */
7204 preg = getFreePtr(ic,&aop,FALSE);
7205 pic14_emitcode("mov","%s,%s",
7207 aopGet(AOP(left),0,FALSE,TRUE));
7208 rname = preg->name ;
7210 rname = aopGet(AOP(left),0,FALSE,FALSE);
7212 freeAsmop(left,NULL,ic,TRUE);
7213 aopOp (result,ic,FALSE);
7215 /* if bitfield then unpack the bits */
7216 if (IS_BITVAR(retype))
7217 genUnpackBits (result,rname,PPOINTER);
7219 /* we have can just get the values */
7220 int size = AOP_SIZE(result);
7225 pic14_emitcode("movx","a,@%s",rname);
7226 aopPut(AOP(result),"a",offset);
7231 pic14_emitcode("inc","%s",rname);
7235 /* now some housekeeping stuff */
7237 /* we had to allocate for this iCode */
7238 freeAsmop(NULL,aop,ic,TRUE);
7240 /* we did not allocate which means left
7241 already in a pointer register, then
7242 if size > 0 && this could be used again
7243 we have to point it back to where it
7245 if (AOP_SIZE(result) > 1 &&
7246 !OP_SYMBOL(left)->remat &&
7247 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7249 int size = AOP_SIZE(result) - 1;
7251 pic14_emitcode("dec","%s",rname);
7256 freeAsmop(result,NULL,ic,TRUE);
7261 /*-----------------------------------------------------------------*/
7262 /* genFarPointerGet - gget value from far space */
7263 /*-----------------------------------------------------------------*/
7264 static void genFarPointerGet (operand *left,
7265 operand *result, iCode *ic)
7268 sym_link *retype = getSpec(operandType(result));
7270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7272 aopOp(left,ic,FALSE);
7274 /* if the operand is already in dptr
7275 then we do nothing else we move the value to dptr */
7276 if (AOP_TYPE(left) != AOP_STR) {
7277 /* if this is remateriazable */
7278 if (AOP_TYPE(left) == AOP_IMMD)
7279 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7280 else { /* we need to get it byte by byte */
7281 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7282 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7283 if (options.model == MODEL_FLAT24)
7285 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7289 /* so dptr know contains the address */
7290 freeAsmop(left,NULL,ic,TRUE);
7291 aopOp(result,ic,FALSE);
7293 /* if bit then unpack */
7294 if (IS_BITVAR(retype))
7295 genUnpackBits(result,"dptr",FPOINTER);
7297 size = AOP_SIZE(result);
7301 pic14_emitcode("movx","a,@dptr");
7302 aopPut(AOP(result),"a",offset++);
7304 pic14_emitcode("inc","dptr");
7308 freeAsmop(result,NULL,ic,TRUE);
7311 /*-----------------------------------------------------------------*/
7312 /* pic14_emitcodePointerGet - gget value from code space */
7313 /*-----------------------------------------------------------------*/
7314 static void pic14_emitcodePointerGet (operand *left,
7315 operand *result, iCode *ic)
7318 sym_link *retype = getSpec(operandType(result));
7320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7322 aopOp(left,ic,FALSE);
7324 /* if the operand is already in dptr
7325 then we do nothing else we move the value to dptr */
7326 if (AOP_TYPE(left) != AOP_STR) {
7327 /* if this is remateriazable */
7328 if (AOP_TYPE(left) == AOP_IMMD)
7329 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7330 else { /* we need to get it byte by byte */
7331 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7332 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7333 if (options.model == MODEL_FLAT24)
7335 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7339 /* so dptr know contains the address */
7340 freeAsmop(left,NULL,ic,TRUE);
7341 aopOp(result,ic,FALSE);
7343 /* if bit then unpack */
7344 if (IS_BITVAR(retype))
7345 genUnpackBits(result,"dptr",CPOINTER);
7347 size = AOP_SIZE(result);
7351 pic14_emitcode("clr","a");
7352 pic14_emitcode("movc","a,@a+dptr");
7353 aopPut(AOP(result),"a",offset++);
7355 pic14_emitcode("inc","dptr");
7359 freeAsmop(result,NULL,ic,TRUE);
7362 /*-----------------------------------------------------------------*/
7363 /* genGenPointerGet - gget value from generic pointer space */
7364 /*-----------------------------------------------------------------*/
7365 static void genGenPointerGet (operand *left,
7366 operand *result, iCode *ic)
7369 sym_link *retype = getSpec(operandType(result));
7371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7372 aopOp(left,ic,FALSE);
7373 aopOp(result,ic,FALSE);
7376 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7378 /* if the operand is already in dptr
7379 then we do nothing else we move the value to dptr */
7380 if (AOP_TYPE(left) != AOP_STR) {
7381 /* if this is remateriazable */
7382 if (AOP_TYPE(left) == AOP_IMMD) {
7383 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7384 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7386 else { /* we need to get it byte by byte */
7388 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7389 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7391 size = AOP_SIZE(result);
7395 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7396 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7398 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7403 /* so dptr know contains the address */
7405 /* if bit then unpack */
7406 if (IS_BITVAR(retype))
7407 genUnpackBits(result,"dptr",GPOINTER);
7410 freeAsmop(left,NULL,ic,TRUE);
7411 freeAsmop(result,NULL,ic,TRUE);
7415 /*-----------------------------------------------------------------*/
7416 /* genPointerGet - generate code for pointer get */
7417 /*-----------------------------------------------------------------*/
7418 static void genPointerGet (iCode *ic)
7420 operand *left, *result ;
7421 sym_link *type, *etype;
7424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7427 result = IC_RESULT(ic) ;
7429 /* depending on the type of pointer we need to
7430 move it to the correct pointer register */
7431 type = operandType(left);
7432 etype = getSpec(type);
7433 /* if left is of type of pointer then it is simple */
7434 if (IS_PTR(type) && !IS_FUNC(type->next))
7435 p_type = DCL_TYPE(type);
7437 /* we have to go by the storage class */
7438 p_type = PTR_TYPE(SPEC_OCLS(etype));
7440 /* if (SPEC_OCLS(etype)->codesp ) { */
7441 /* p_type = CPOINTER ; */
7444 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7445 /* p_type = FPOINTER ; */
7447 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7448 /* p_type = PPOINTER; */
7450 /* if (SPEC_OCLS(etype) == idata ) */
7451 /* p_type = IPOINTER; */
7453 /* p_type = POINTER ; */
7456 /* now that we have the pointer type we assign
7457 the pointer values */
7462 genNearPointerGet (left,result,ic);
7466 genPagedPointerGet(left,result,ic);
7470 genFarPointerGet (left,result,ic);
7474 pic14_emitcodePointerGet (left,result,ic);
7478 genGenPointerGet (left,result,ic);
7484 /*-----------------------------------------------------------------*/
7485 /* genPackBits - generates code for packed bit storage */
7486 /*-----------------------------------------------------------------*/
7487 static void genPackBits (sym_link *etype ,
7489 char *rname, int p_type)
7497 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7498 blen = SPEC_BLEN(etype);
7499 bstr = SPEC_BSTR(etype);
7501 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7504 /* if the bit lenth is less than or */
7505 /* it exactly fits a byte then */
7506 if (SPEC_BLEN(etype) <= 8 ) {
7507 shCount = SPEC_BSTR(etype) ;
7509 /* shift left acc */
7512 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7517 pic14_emitcode ("mov","b,a");
7518 pic14_emitcode("mov","a,@%s",rname);
7522 pic14_emitcode ("mov","b,a");
7523 pic14_emitcode("movx","a,@dptr");
7527 pic14_emitcode ("push","b");
7528 pic14_emitcode ("push","acc");
7529 pic14_emitcode ("lcall","__gptrget");
7530 pic14_emitcode ("pop","b");
7534 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7535 ((unsigned char)(0xFF << (blen+bstr)) |
7536 (unsigned char)(0xFF >> (8-bstr)) ) );
7537 pic14_emitcode ("orl","a,b");
7538 if (p_type == GPOINTER)
7539 pic14_emitcode("pop","b");
7545 pic14_emitcode("mov","@%s,a",rname);
7549 pic14_emitcode("movx","@dptr,a");
7553 DEBUGpic14_emitcode(";lcall","__gptrput");
7558 if ( SPEC_BLEN(etype) <= 8 )
7561 pic14_emitcode("inc","%s",rname);
7562 rLen = SPEC_BLEN(etype) ;
7564 /* now generate for lengths greater than one byte */
7567 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7577 pic14_emitcode("mov","@%s,a",rname);
7579 pic14_emitcode("mov","@%s,%s",rname,l);
7584 pic14_emitcode("movx","@dptr,a");
7589 DEBUGpic14_emitcode(";lcall","__gptrput");
7592 pic14_emitcode ("inc","%s",rname);
7597 /* last last was not complete */
7599 /* save the byte & read byte */
7602 pic14_emitcode ("mov","b,a");
7603 pic14_emitcode("mov","a,@%s",rname);
7607 pic14_emitcode ("mov","b,a");
7608 pic14_emitcode("movx","a,@dptr");
7612 pic14_emitcode ("push","b");
7613 pic14_emitcode ("push","acc");
7614 pic14_emitcode ("lcall","__gptrget");
7615 pic14_emitcode ("pop","b");
7619 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7620 pic14_emitcode ("orl","a,b");
7623 if (p_type == GPOINTER)
7624 pic14_emitcode("pop","b");
7629 pic14_emitcode("mov","@%s,a",rname);
7633 pic14_emitcode("movx","@dptr,a");
7637 DEBUGpic14_emitcode(";lcall","__gptrput");
7641 /*-----------------------------------------------------------------*/
7642 /* genDataPointerSet - remat pointer to data space */
7643 /*-----------------------------------------------------------------*/
7644 static void genDataPointerSet(operand *right,
7648 int size, offset = 0 ;
7649 char *l, buffer[256];
7651 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7652 aopOp(right,ic,FALSE);
7654 l = aopGet(AOP(result),0,FALSE,TRUE);
7655 size = AOP_SIZE(right);
7656 // tsd, was l+1 - the underline `_' prefix was being stripped
7659 sprintf(buffer,"(%s + %d)",l,offset);
7661 sprintf(buffer,"%s",l);
7663 if (AOP_TYPE(right) == AOP_LIT) {
7664 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7665 lit = lit >> (8*offset);
7667 pic14_emitcode("movlw","%d",lit);
7668 pic14_emitcode("movwf","%s",buffer);
7670 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7671 emitpcode(POC_MOVWF, popRegFromString(buffer));
7674 pic14_emitcode("clrf","%s",buffer);
7675 emitpcode(POC_CLRF, popRegFromString(buffer));
7678 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7679 pic14_emitcode("movwf","%s",buffer);
7681 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
7682 emitpcode(POC_MOVWF, popRegFromString(buffer));
7689 freeAsmop(right,NULL,ic,TRUE);
7690 freeAsmop(result,NULL,ic,TRUE);
7693 /*-----------------------------------------------------------------*/
7694 /* genNearPointerSet - pic14_emitcode for near pointer put */
7695 /*-----------------------------------------------------------------*/
7696 static void genNearPointerSet (operand *right,
7703 sym_link *ptype = operandType(result);
7706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7707 retype= getSpec(operandType(right));
7709 aopOp(result,ic,FALSE);
7711 /* if the result is rematerializable &
7712 in data space & not a bit variable */
7713 if (AOP_TYPE(result) == AOP_IMMD &&
7714 DCL_TYPE(ptype) == POINTER &&
7715 !IS_BITVAR(retype)) {
7716 genDataPointerSet (right,result,ic);
7720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7722 /* if the value is already in a pointer register
7723 then don't need anything more */
7724 if (!AOP_INPREG(AOP(result))) {
7725 /* otherwise get a free pointer register */
7726 //aop = newAsmop(0);
7727 //preg = getFreePtr(ic,&aop,FALSE);
7728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7729 //pic14_emitcode("mov","%s,%s",
7731 // aopGet(AOP(result),0,FALSE,TRUE));
7732 //rname = preg->name ;
7733 pic14_emitcode("movwf","fsr");
7735 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7737 freeAsmop(result,NULL,ic,TRUE);
7738 aopOp (right,ic,FALSE);
7739 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7741 /* if bitfield then unpack the bits */
7742 if (IS_BITVAR(retype)) {
7743 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7744 "The programmer is obviously confused");
7745 //genPackBits (retype,right,rname,POINTER);
7749 /* we have can just get the values */
7750 int size = AOP_SIZE(right);
7753 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7755 l = aopGet(AOP(right),offset,FALSE,TRUE);
7758 //pic14_emitcode("mov","@%s,a",rname);
7759 pic14_emitcode("movf","indf,w ;1");
7762 if (AOP_TYPE(right) == AOP_LIT) {
7763 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7765 pic14_emitcode("movlw","%s",l);
7766 pic14_emitcode("movwf","indf ;2");
7768 pic14_emitcode("clrf","indf");
7770 pic14_emitcode("movf","%s,w",l);
7771 pic14_emitcode("movwf","indf ;2");
7773 //pic14_emitcode("mov","@%s,%s",rname,l);
7776 pic14_emitcode("incf","fsr,f ;3");
7777 //pic14_emitcode("inc","%s",rname);
7782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7783 /* now some housekeeping stuff */
7785 /* we had to allocate for this iCode */
7786 freeAsmop(NULL,aop,ic,TRUE);
7788 /* we did not allocate which means left
7789 already in a pointer register, then
7790 if size > 0 && this could be used again
7791 we have to point it back to where it
7793 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7794 if (AOP_SIZE(right) > 1 &&
7795 !OP_SYMBOL(result)->remat &&
7796 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7798 int size = AOP_SIZE(right) - 1;
7800 pic14_emitcode("decf","fsr,f");
7801 //pic14_emitcode("dec","%s",rname);
7805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7807 freeAsmop(right,NULL,ic,TRUE);
7812 /*-----------------------------------------------------------------*/
7813 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7814 /*-----------------------------------------------------------------*/
7815 static void genPagedPointerSet (operand *right,
7824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7826 retype= getSpec(operandType(right));
7828 aopOp(result,ic,FALSE);
7830 /* if the value is already in a pointer register
7831 then don't need anything more */
7832 if (!AOP_INPREG(AOP(result))) {
7833 /* otherwise get a free pointer register */
7835 preg = getFreePtr(ic,&aop,FALSE);
7836 pic14_emitcode("mov","%s,%s",
7838 aopGet(AOP(result),0,FALSE,TRUE));
7839 rname = preg->name ;
7841 rname = aopGet(AOP(result),0,FALSE,FALSE);
7843 freeAsmop(result,NULL,ic,TRUE);
7844 aopOp (right,ic,FALSE);
7846 /* if bitfield then unpack the bits */
7847 if (IS_BITVAR(retype))
7848 genPackBits (retype,right,rname,PPOINTER);
7850 /* we have can just get the values */
7851 int size = AOP_SIZE(right);
7855 l = aopGet(AOP(right),offset,FALSE,TRUE);
7858 pic14_emitcode("movx","@%s,a",rname);
7861 pic14_emitcode("inc","%s",rname);
7867 /* now some housekeeping stuff */
7869 /* we had to allocate for this iCode */
7870 freeAsmop(NULL,aop,ic,TRUE);
7872 /* we did not allocate which means left
7873 already in a pointer register, then
7874 if size > 0 && this could be used again
7875 we have to point it back to where it
7877 if (AOP_SIZE(right) > 1 &&
7878 !OP_SYMBOL(result)->remat &&
7879 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7881 int size = AOP_SIZE(right) - 1;
7883 pic14_emitcode("dec","%s",rname);
7888 freeAsmop(right,NULL,ic,TRUE);
7893 /*-----------------------------------------------------------------*/
7894 /* genFarPointerSet - set value from far space */
7895 /*-----------------------------------------------------------------*/
7896 static void genFarPointerSet (operand *right,
7897 operand *result, iCode *ic)
7900 sym_link *retype = getSpec(operandType(right));
7902 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7903 aopOp(result,ic,FALSE);
7905 /* if the operand is already in dptr
7906 then we do nothing else we move the value to dptr */
7907 if (AOP_TYPE(result) != AOP_STR) {
7908 /* if this is remateriazable */
7909 if (AOP_TYPE(result) == AOP_IMMD)
7910 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7911 else { /* we need to get it byte by byte */
7912 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
7913 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
7914 if (options.model == MODEL_FLAT24)
7916 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
7920 /* so dptr know contains the address */
7921 freeAsmop(result,NULL,ic,TRUE);
7922 aopOp(right,ic,FALSE);
7924 /* if bit then unpack */
7925 if (IS_BITVAR(retype))
7926 genPackBits(retype,right,"dptr",FPOINTER);
7928 size = AOP_SIZE(right);
7932 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
7934 pic14_emitcode("movx","@dptr,a");
7936 pic14_emitcode("inc","dptr");
7940 freeAsmop(right,NULL,ic,TRUE);
7943 /*-----------------------------------------------------------------*/
7944 /* genGenPointerSet - set value from generic pointer space */
7945 /*-----------------------------------------------------------------*/
7946 static void genGenPointerSet (operand *right,
7947 operand *result, iCode *ic)
7950 sym_link *retype = getSpec(operandType(right));
7952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7954 aopOp(result,ic,FALSE);
7955 aopOp(right,ic,FALSE);
7956 size = AOP_SIZE(right);
7958 DEBUGpic14_AopType(__LINE__,NULL,right,result);
7960 /* if the operand is already in dptr
7961 then we do nothing else we move the value to dptr */
7962 if (AOP_TYPE(result) != AOP_STR) {
7963 /* if this is remateriazable */
7964 if (AOP_TYPE(result) == AOP_IMMD) {
7965 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
7966 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
7968 else { /* we need to get it byte by byte */
7969 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
7970 size = AOP_SIZE(right);
7973 /* hack hack! see if this the FSR. If so don't load W */
7974 if(AOP_TYPE(right) != AOP_ACC) {
7976 emitpcode(POC_MOVFW,popGet(AOP(result),0));
7977 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7980 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
7982 // emitpcode(POC_MOVLW,popGetLit(0xfd));
7983 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
7987 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
7988 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
7991 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7998 if(aopIdx(AOP(result),0) != 4) {
8000 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8004 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8009 /* so dptr know contains the address */
8012 /* if bit then unpack */
8013 if (IS_BITVAR(retype))
8014 genPackBits(retype,right,"dptr",GPOINTER);
8016 size = AOP_SIZE(right);
8020 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8022 pic14_emitcode("incf","fsr,f");
8023 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8024 pic14_emitcode("movwf","indf");
8026 //DEBUGpic14_emitcode(";lcall","__gptrput");
8028 // pic14_emitcode("inc","dptr");
8033 freeAsmop(right,NULL,ic,TRUE);
8034 freeAsmop(result,NULL,ic,TRUE);
8037 /*-----------------------------------------------------------------*/
8038 /* genPointerSet - stores the value into a pointer location */
8039 /*-----------------------------------------------------------------*/
8040 static void genPointerSet (iCode *ic)
8042 operand *right, *result ;
8043 sym_link *type, *etype;
8046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8048 right = IC_RIGHT(ic);
8049 result = IC_RESULT(ic) ;
8051 /* depending on the type of pointer we need to
8052 move it to the correct pointer register */
8053 type = operandType(result);
8054 etype = getSpec(type);
8055 /* if left is of type of pointer then it is simple */
8056 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8057 p_type = DCL_TYPE(type);
8060 /* we have to go by the storage class */
8061 p_type = PTR_TYPE(SPEC_OCLS(etype));
8063 /* if (SPEC_OCLS(etype)->codesp ) { */
8064 /* p_type = CPOINTER ; */
8067 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8068 /* p_type = FPOINTER ; */
8070 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8071 /* p_type = PPOINTER ; */
8073 /* if (SPEC_OCLS(etype) == idata ) */
8074 /* p_type = IPOINTER ; */
8076 /* p_type = POINTER ; */
8079 /* now that we have the pointer type we assign
8080 the pointer values */
8085 genNearPointerSet (right,result,ic);
8089 genPagedPointerSet (right,result,ic);
8093 genFarPointerSet (right,result,ic);
8097 genGenPointerSet (right,result,ic);
8103 /*-----------------------------------------------------------------*/
8104 /* genIfx - generate code for Ifx statement */
8105 /*-----------------------------------------------------------------*/
8106 static void genIfx (iCode *ic, iCode *popIc)
8108 operand *cond = IC_COND(ic);
8111 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8113 aopOp(cond,ic,FALSE);
8115 /* get the value into acc */
8116 if (AOP_TYPE(cond) != AOP_CRY)
8117 pic14_toBoolean(cond);
8120 /* the result is now in the accumulator */
8121 freeAsmop(cond,NULL,ic,TRUE);
8123 /* if there was something to be popped then do it */
8127 /* if the condition is a bit variable */
8128 if (isbit && IS_ITEMP(cond) &&
8130 genIfxJump(ic,SPIL_LOC(cond)->rname);
8131 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8134 if (isbit && !IS_ITEMP(cond))
8135 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8143 /*-----------------------------------------------------------------*/
8144 /* genAddrOf - generates code for address of */
8145 /*-----------------------------------------------------------------*/
8146 static void genAddrOf (iCode *ic)
8148 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8149 operand *right, *result, *left;
8150 //int size, offset ;
8152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8155 //aopOp(IC_RESULT(ic),ic,FALSE);
8157 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8158 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8159 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8161 DEBUGpic14_AopType(__LINE__,left,right,result);
8163 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8164 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8167 /* object not on stack then we need the name */
8168 size = AOP_SIZE(IC_RESULT(ic));
8172 char s[SDCC_NAME_MAX];
8174 sprintf(s,"#(%s >> %d)",
8178 sprintf(s,"#%s",sym->rname);
8179 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8184 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8185 freeAsmop(left,NULL,ic,FALSE);
8186 freeAsmop(result,NULL,ic,TRUE);
8191 /*-----------------------------------------------------------------*/
8192 /* genFarFarAssign - assignment when both are in far space */
8193 /*-----------------------------------------------------------------*/
8194 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8196 int size = AOP_SIZE(right);
8199 /* first push the right side on to the stack */
8201 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8203 pic14_emitcode ("push","acc");
8206 freeAsmop(right,NULL,ic,FALSE);
8207 /* now assign DPTR to result */
8208 aopOp(result,ic,FALSE);
8209 size = AOP_SIZE(result);
8211 pic14_emitcode ("pop","acc");
8212 aopPut(AOP(result),"a",--offset);
8214 freeAsmop(result,NULL,ic,FALSE);
8219 /*-----------------------------------------------------------------*/
8220 /* genAssign - generate code for assignment */
8221 /*-----------------------------------------------------------------*/
8222 static void genAssign (iCode *ic)
8224 operand *result, *right;
8225 int size, offset,know_W;
8226 unsigned long lit = 0L;
8228 result = IC_RESULT(ic);
8229 right = IC_RIGHT(ic) ;
8231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8233 /* if they are the same */
8234 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8237 aopOp(right,ic,FALSE);
8238 aopOp(result,ic,TRUE);
8240 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8242 /* if they are the same registers */
8243 if (pic14_sameRegs(AOP(right),AOP(result)))
8246 /* if the result is a bit */
8247 if (AOP_TYPE(result) == AOP_CRY) {
8249 /* if the right size is a literal then
8250 we know what the value is */
8251 if (AOP_TYPE(right) == AOP_LIT) {
8253 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8254 popGet(AOP(result),0));
8256 if (((int) operandLitValue(right)))
8257 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8258 AOP(result)->aopu.aop_dir,
8259 AOP(result)->aopu.aop_dir);
8261 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8262 AOP(result)->aopu.aop_dir,
8263 AOP(result)->aopu.aop_dir);
8267 /* the right is also a bit variable */
8268 if (AOP_TYPE(right) == AOP_CRY) {
8269 emitpcode(POC_BCF, popGet(AOP(result),0));
8270 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8271 emitpcode(POC_BSF, popGet(AOP(result),0));
8273 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8274 AOP(result)->aopu.aop_dir,
8275 AOP(result)->aopu.aop_dir);
8276 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8277 AOP(right)->aopu.aop_dir,
8278 AOP(right)->aopu.aop_dir);
8279 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8280 AOP(result)->aopu.aop_dir,
8281 AOP(result)->aopu.aop_dir);
8286 emitpcode(POC_BCF, popGet(AOP(result),0));
8287 pic14_toBoolean(right);
8289 emitpcode(POC_BSF, popGet(AOP(result),0));
8290 //aopPut(AOP(result),"a",0);
8294 /* bit variables done */
8296 size = AOP_SIZE(result);
8298 if(AOP_TYPE(right) == AOP_LIT)
8299 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8301 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8302 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8303 if(aopIdx(AOP(result),0) == 4) {
8304 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8305 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8306 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8309 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8315 if(AOP_TYPE(right) == AOP_LIT) {
8317 if(know_W != (lit&0xff))
8318 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8320 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8322 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8326 } else if (AOP_TYPE(right) == AOP_CRY) {
8327 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8329 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8330 emitpcode(POC_INCF, popGet(AOP(result),0));
8333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8334 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8335 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8343 freeAsmop (right,NULL,ic,FALSE);
8344 freeAsmop (result,NULL,ic,TRUE);
8347 /*-----------------------------------------------------------------*/
8348 /* genJumpTab - genrates code for jump table */
8349 /*-----------------------------------------------------------------*/
8350 static void genJumpTab (iCode *ic)
8355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8357 aopOp(IC_JTCOND(ic),ic,FALSE);
8358 /* get the condition into accumulator */
8359 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8361 /* multiply by three */
8362 pic14_emitcode("add","a,acc");
8363 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8365 jtab = newiTempLabel(NULL);
8366 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8367 pic14_emitcode("jmp","@a+dptr");
8368 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8370 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8371 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8373 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8374 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8375 emitpLabel(jtab->key);
8377 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8379 /* now generate the jump labels */
8380 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8381 jtab = setNextItem(IC_JTLABELS(ic))) {
8382 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8383 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8389 /*-----------------------------------------------------------------*/
8390 /* genMixedOperation - gen code for operators between mixed types */
8391 /*-----------------------------------------------------------------*/
8393 TSD - Written for the PIC port - but this unfortunately is buggy.
8394 This routine is good in that it is able to efficiently promote
8395 types to different (larger) sizes. Unfortunately, the temporary
8396 variables that are optimized out by this routine are sometimes
8397 used in other places. So until I know how to really parse the
8398 iCode tree, I'm going to not be using this routine :(.
8400 static int genMixedOperation (iCode *ic)
8403 operand *result = IC_RESULT(ic);
8404 sym_link *ctype = operandType(IC_LEFT(ic));
8405 operand *right = IC_RIGHT(ic);
8411 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8413 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8419 nextright = IC_RIGHT(nextic);
8420 nextleft = IC_LEFT(nextic);
8421 nextresult = IC_RESULT(nextic);
8423 aopOp(right,ic,FALSE);
8424 aopOp(result,ic,FALSE);
8425 aopOp(nextright, nextic, FALSE);
8426 aopOp(nextleft, nextic, FALSE);
8427 aopOp(nextresult, nextic, FALSE);
8429 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8435 pic14_emitcode(";remove right +","");
8437 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8443 pic14_emitcode(";remove left +","");
8447 big = AOP_SIZE(nextleft);
8448 small = AOP_SIZE(nextright);
8450 switch(nextic->op) {
8453 pic14_emitcode(";optimize a +","");
8454 /* if unsigned or not an integral type */
8455 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8456 pic14_emitcode(";add a bit to something","");
8459 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8461 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8462 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8463 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8465 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8473 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8474 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8475 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8478 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8480 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8481 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8482 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8483 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8484 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8487 pic14_emitcode("rlf","known_zero,w");
8494 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8495 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8496 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8498 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8508 freeAsmop(right,NULL,ic,TRUE);
8509 freeAsmop(result,NULL,ic,TRUE);
8510 freeAsmop(nextright,NULL,ic,TRUE);
8511 freeAsmop(nextleft,NULL,ic,TRUE);
8513 nextic->generated = 1;
8520 /*-----------------------------------------------------------------*/
8521 /* genCast - gen code for casting */
8522 /*-----------------------------------------------------------------*/
8523 static void genCast (iCode *ic)
8525 operand *result = IC_RESULT(ic);
8526 sym_link *ctype = operandType(IC_LEFT(ic));
8527 operand *right = IC_RIGHT(ic);
8530 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8531 /* if they are equivalent then do nothing */
8532 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8535 aopOp(right,ic,FALSE) ;
8536 aopOp(result,ic,FALSE);
8538 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8540 /* if the result is a bit */
8541 if (AOP_TYPE(result) == AOP_CRY) {
8542 /* if the right size is a literal then
8543 we know what the value is */
8544 if (AOP_TYPE(right) == AOP_LIT) {
8546 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8547 popGet(AOP(result),0));
8549 if (((int) operandLitValue(right)))
8550 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8551 AOP(result)->aopu.aop_dir,
8552 AOP(result)->aopu.aop_dir);
8554 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8555 AOP(result)->aopu.aop_dir,
8556 AOP(result)->aopu.aop_dir);
8561 /* the right is also a bit variable */
8562 if (AOP_TYPE(right) == AOP_CRY) {
8565 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8567 pic14_emitcode("clrc","");
8568 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8569 AOP(right)->aopu.aop_dir,
8570 AOP(right)->aopu.aop_dir);
8571 aopPut(AOP(result),"c",0);
8576 if (AOP_TYPE(right) == AOP_REG) {
8577 emitpcode(POC_BCF, popGet(AOP(result),0));
8578 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8579 emitpcode(POC_BSF, popGet(AOP(result),0));
8581 pic14_toBoolean(right);
8582 aopPut(AOP(result),"a",0);
8586 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
8588 size = AOP_SIZE(result);
8590 emitpcode(POC_CLRF, popGet(AOP(result),0));
8591 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8592 emitpcode(POC_INCF, popGet(AOP(result),0));
8595 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
8600 /* if they are the same size : or less */
8601 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8603 /* if they are in the same place */
8604 if (pic14_sameRegs(AOP(right),AOP(result)))
8607 /* if they in different places then copy */
8608 size = AOP_SIZE(result);
8612 aopGet(AOP(right),offset,FALSE,FALSE),
8620 /* if the result is of type pointer */
8621 if (IS_PTR(ctype)) {
8624 sym_link *type = operandType(right);
8625 sym_link *etype = getSpec(type);
8627 /* pointer to generic pointer */
8628 if (IS_GENPTR(ctype)) {
8632 p_type = DCL_TYPE(type);
8634 /* we have to go by the storage class */
8635 p_type = PTR_TYPE(SPEC_OCLS(etype));
8637 /* if (SPEC_OCLS(etype)->codesp ) */
8638 /* p_type = CPOINTER ; */
8640 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8641 /* p_type = FPOINTER ; */
8643 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8644 /* p_type = PPOINTER; */
8646 /* if (SPEC_OCLS(etype) == idata ) */
8647 /* p_type = IPOINTER ; */
8649 /* p_type = POINTER ; */
8652 /* the first two bytes are known */
8653 size = GPTRSIZE - 1;
8657 aopGet(AOP(right),offset,FALSE,FALSE),
8661 /* the last byte depending on type */
8678 /* this should never happen */
8679 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8680 "got unknown pointer type");
8683 aopPut(AOP(result),l, GPTRSIZE - 1);
8687 /* just copy the pointers */
8688 size = AOP_SIZE(result);
8692 aopGet(AOP(right),offset,FALSE,FALSE),
8701 /* so we now know that the size of destination is greater
8702 than the size of the source.
8703 Now, if the next iCode is an operator then we might be
8704 able to optimize the operation without performing a cast.
8706 if(genMixedOperation(ic))
8710 /* we move to result for the size of source */
8711 size = AOP_SIZE(right);
8714 pic14_emitcode(";","%d",__LINE__);
8715 /* aopPut(AOP(result),
8716 aopGet(AOP(right),offset,FALSE,FALSE),
8718 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8719 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8723 /* now depending on the sign of the destination */
8724 size = AOP_SIZE(result) - AOP_SIZE(right);
8725 /* if unsigned or not an integral type */
8726 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8728 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8729 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8733 /* we need to extend the sign :{ */
8735 emitpcodeNULLop(POC_CLRW);
8738 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8740 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8742 emitpcode(POC_MOVLW, popGetLit(0xff));
8744 pic14_emitcode("clrw","");
8745 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8746 AOP(right)->aopu.aop_dir,
8747 AOP(right)->aopu.aop_dir);
8748 pic14_emitcode("movlw","0xff");
8750 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8751 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8753 // aopPut(AOP(result),"a",offset++);
8758 /* we are done hurray !!!! */
8761 freeAsmop(right,NULL,ic,TRUE);
8762 freeAsmop(result,NULL,ic,TRUE);
8766 /*-----------------------------------------------------------------*/
8767 /* genDjnz - generate decrement & jump if not zero instrucion */
8768 /*-----------------------------------------------------------------*/
8769 static int genDjnz (iCode *ic, iCode *ifx)
8772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8777 /* if the if condition has a false label
8778 then we cannot save */
8782 /* if the minus is not of the form
8784 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8785 !IS_OP_LITERAL(IC_RIGHT(ic)))
8788 if (operandLitValue(IC_RIGHT(ic)) != 1)
8791 /* if the size of this greater than one then no
8793 if (getSize(operandType(IC_RESULT(ic))) > 1)
8796 /* otherwise we can save BIG */
8797 lbl = newiTempLabel(NULL);
8798 lbl1= newiTempLabel(NULL);
8800 aopOp(IC_RESULT(ic),ic,FALSE);
8802 if (IS_AOP_PREG(IC_RESULT(ic))) {
8803 pic14_emitcode("dec","%s",
8804 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8805 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8806 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8810 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
8811 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8813 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8814 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8817 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8818 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
8819 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
8820 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
8823 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8828 /*-----------------------------------------------------------------*/
8829 /* genReceive - generate code for a receive iCode */
8830 /*-----------------------------------------------------------------*/
8831 static void genReceive (iCode *ic)
8833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8835 if (isOperandInFarSpace(IC_RESULT(ic)) &&
8836 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
8837 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
8839 int size = getSize(operandType(IC_RESULT(ic)));
8840 int offset = fReturnSizePic - size;
8842 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
8843 fReturn[fReturnSizePic - offset - 1] : "acc"));
8846 aopOp(IC_RESULT(ic),ic,FALSE);
8847 size = AOP_SIZE(IC_RESULT(ic));
8850 pic14_emitcode ("pop","acc");
8851 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
8856 aopOp(IC_RESULT(ic),ic,FALSE);
8858 assignResultValue(IC_RESULT(ic));
8861 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8864 /*-----------------------------------------------------------------*/
8865 /* genpic14Code - generate code for pic14 based controllers */
8866 /*-----------------------------------------------------------------*/
8868 * At this point, ralloc.c has gone through the iCode and attempted
8869 * to optimize in a way suitable for a PIC. Now we've got to generate
8870 * PIC instructions that correspond to the iCode.
8872 * Once the instructions are generated, we'll pass through both the
8873 * peep hole optimizer and the pCode optimizer.
8874 *-----------------------------------------------------------------*/
8876 void genpic14Code (iCode *lic)
8881 lineHead = lineCurr = NULL;
8883 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
8886 /* if debug information required */
8887 /* if (options.debug && currFunc) { */
8889 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
8891 if (IS_STATIC(currFunc->etype)) {
8892 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
8893 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
8895 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
8896 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
8902 for (ic = lic ; ic ; ic = ic->next ) {
8904 DEBUGpic14_emitcode(";ic","");
8905 if ( cln != ic->lineno ) {
8906 if ( options.debug ) {
8908 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
8909 FileBaseName(ic->filename),ic->lineno,
8910 ic->level,ic->block);
8913 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
8916 /* if the result is marked as
8917 spilt and rematerializable or code for
8918 this has already been generated then
8920 if (resultRemat(ic) || ic->generated )
8923 /* depending on the operation */
8942 /* IPOP happens only when trying to restore a
8943 spilt live range, if there is an ifx statement
8944 following this pop then the if statement might
8945 be using some of the registers being popped which
8946 would destory the contents of the register so
8947 we need to check for this condition and handle it */
8949 ic->next->op == IFX &&
8950 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
8951 genIfx (ic->next,ic);
8969 genEndFunction (ic);
8989 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9006 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9010 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9017 /* note these two are xlated by algebraic equivalence
9018 during parsing SDCC.y */
9019 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9020 "got '>=' or '<=' shouldn't have come here");
9024 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9036 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9040 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9044 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9071 case GET_VALUE_AT_ADDRESS:
9076 if (POINTER_SET(ic))
9103 addSet(&_G.sendSet,ic);
9112 /* now we are ready to call the
9113 peep hole optimizer */
9114 if (!options.nopeep) {
9115 printf("peep hole optimizing\n");
9116 peepHole (&lineHead);
9118 /* now do the actual printing */
9119 printLine (lineHead,codeOutFile);
9121 printf("printing pBlock\n\n");
9122 printpBlock(stdout,pb);