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 if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
64 DEBUGpic14_emitcode ("; ","result %s",
65 AopType(AOP_TYPE(IC_RESULT(ic))));
67 if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
68 DEBUGpic14_emitcode ("; ","left %s",
69 AopType(AOP_TYPE(IC_LEFT(ic))));
71 if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
72 DEBUGpic14_emitcode ("; ","right %s",
73 AopType(AOP_TYPE(IC_RIGHT(ic))));
77 static int labelOffset=0;
78 static int debug_verbose=1;
79 static int optimized_for_speed = 0;
81 /* max_key keeps track of the largest label number used in
82 a function. This is then used to adjust the label offset
83 for the next function.
86 static int GpsuedoStkPtr=0;
88 unsigned int pic14aopLiteral (value *val, int offset);
89 const char *AopType(short type);
91 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
93 /* this is the down and dirty file with all kinds of
94 kludgy & hacky stuff. This is what it is all about
95 CODE GENERATION for a specific MCU . some of the
96 routines may be reusable, will have to see */
98 static char *zero = "#0x00";
99 static char *one = "#0x01";
100 static char *spname = "sp";
102 char *fReturnpic14[] = {"FSR","dph","b","a" };
103 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
104 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
105 static char **fReturn = fReturnpic14;
107 static char *accUse[] = {"a","b"};
109 //static short rbank = -1;
121 /* Resolved ifx structure. This structure stores information
122 about an iCode ifx that makes it easier to generate code.
124 typedef struct resolvedIfx {
125 symbol *lbl; /* pointer to a label */
126 int condition; /* true or false ifx */
127 int generated; /* set true when the code associated with the ifx
131 extern int pic14_ptrRegReq ;
132 extern int pic14_nRegs;
133 extern FILE *codeOutFile;
134 static void saverbank (int, iCode *,bool);
136 static lineNode *lineHead = NULL;
137 static lineNode *lineCurr = NULL;
139 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
140 0xE0, 0xC0, 0x80, 0x00};
141 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
142 0x07, 0x03, 0x01, 0x00};
146 /*-----------------------------------------------------------------*/
147 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
148 /* exponent of 2 is returned, otherwise -1 is */
150 /* note that this is similar to the function `powof2' in SDCCsymt */
154 /*-----------------------------------------------------------------*/
155 static int my_powof2 (unsigned long num)
158 if( (num & (num-1)) == 0) {
171 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
174 char lb[INITIAL_INLINEASM];
184 sprintf(lb,"%s\t",inst);
186 sprintf(lb,"%s",inst);
187 vsprintf(lb+(strlen(lb)),fmt,ap);
191 while (isspace(*lbp)) lbp++;
194 lineCurr = (lineCurr ?
195 connectLine(lineCurr,newLineNode(lb)) :
196 (lineHead = newLineNode(lb)));
197 lineCurr->isInline = _G.inLine;
198 lineCurr->isDebug = _G.debugLine;
200 addpCode2pBlock(pb,newpCodeCharP(lb));
206 static void emitpLabel(int key)
208 addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
211 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
215 addpCode2pBlock(pb,newpCode(poc,pcop));
217 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
220 void emitpcodeNULLop(PIC_OPCODE poc)
223 addpCode2pBlock(pb,newpCode(poc,NULL));
227 /*-----------------------------------------------------------------*/
228 /* pic14_emitcode - writes the code into a file : for now it is simple */
229 /*-----------------------------------------------------------------*/
230 void pic14_emitcode (char *inst,char *fmt, ...)
233 char lb[INITIAL_INLINEASM];
240 sprintf(lb,"%s\t",inst);
242 sprintf(lb,"%s",inst);
243 vsprintf(lb+(strlen(lb)),fmt,ap);
247 while (isspace(*lbp)) lbp++;
250 lineCurr = (lineCurr ?
251 connectLine(lineCurr,newLineNode(lb)) :
252 (lineHead = newLineNode(lb)));
253 lineCurr->isInline = _G.inLine;
254 lineCurr->isDebug = _G.debugLine;
257 addpCode2pBlock(pb,newpCodeCharP(lb));
263 /*-----------------------------------------------------------------*/
264 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
265 /*-----------------------------------------------------------------*/
266 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
268 bool r0iu = FALSE , r1iu = FALSE;
269 bool r0ou = FALSE , r1ou = FALSE;
271 /* the logic: if r0 & r1 used in the instruction
272 then we are in trouble otherwise */
274 /* first check if r0 & r1 are used by this
275 instruction, in which case we are in trouble */
276 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
277 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
282 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
283 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
285 /* if no usage of r0 then return it */
286 if (!r0iu && !r0ou) {
287 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
288 (*aopp)->type = AOP_R0;
290 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
293 /* if no usage of r1 then return it */
294 if (!r1iu && !r1ou) {
295 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
296 (*aopp)->type = AOP_R1;
298 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
301 /* now we know they both have usage */
302 /* if r0 not used in this instruction */
304 /* push it if not already pushed */
306 pic14_emitcode ("push","%s",
307 pic14_regWithIdx(R0_IDX)->dname);
311 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
312 (*aopp)->type = AOP_R0;
314 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
317 /* if r1 not used then */
320 /* push it if not already pushed */
322 pic14_emitcode ("push","%s",
323 pic14_regWithIdx(R1_IDX)->dname);
327 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
328 (*aopp)->type = AOP_R1;
329 return pic14_regWithIdx(R1_IDX);
333 /* I said end of world but not quite end of world yet */
334 /* if this is a result then we can push it on the stack*/
336 (*aopp)->type = AOP_STK;
340 /* other wise this is true end of the world */
341 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
342 "getFreePtr should never reach here");
346 /*-----------------------------------------------------------------*/
347 /* newAsmop - creates a new asmOp */
348 /*-----------------------------------------------------------------*/
349 asmop *newAsmop (short type)
353 aop = Safe_calloc(1,sizeof(asmop));
358 static void genSetDPTR(int n)
362 pic14_emitcode(";", "Select standard DPTR");
363 pic14_emitcode("mov", "dps, #0x00");
367 pic14_emitcode(";", "Select alternate DPTR");
368 pic14_emitcode("mov", "dps, #0x01");
372 /*-----------------------------------------------------------------*/
373 /* resolveIfx - converts an iCode ifx into a form more useful for */
374 /* generating code */
375 /*-----------------------------------------------------------------*/
376 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
381 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
383 resIfx->condition = 1; /* assume that the ifx is true */
384 resIfx->generated = 0; /* indicate that the ifx has not been used */
387 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
388 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
389 __FUNCTION__,__LINE__,resIfx->lbl->key);
392 resIfx->lbl = IC_TRUE(ifx);
394 resIfx->lbl = IC_FALSE(ifx);
395 resIfx->condition = 0;
398 DEBUGpic14_emitcode("; ***","ifx true is non-null");
400 DEBUGpic14_emitcode("; ***","ifx false is non-null");
403 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
406 /*-----------------------------------------------------------------*/
407 /* pointerCode - returns the code for a pointer type */
408 /*-----------------------------------------------------------------*/
409 static int pointerCode (sym_link *etype)
412 return PTR_TYPE(SPEC_OCLS(etype));
416 /*-----------------------------------------------------------------*/
417 /* aopForSym - for a true symbol */
418 /*-----------------------------------------------------------------*/
419 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
422 memmap *space= SPEC_OCLS(sym->etype);
424 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
425 /* if already has one */
429 /* assign depending on the storage class */
430 /* if it is on the stack or indirectly addressable */
431 /* space we need to assign either r0 or r1 to it */
432 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
433 sym->aop = aop = newAsmop(0);
434 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
435 aop->size = getSize(sym->type);
437 /* now assign the address of the variable to
438 the pointer register */
439 if (aop->type != AOP_STK) {
443 pic14_emitcode("push","acc");
445 pic14_emitcode("mov","a,_bp");
446 pic14_emitcode("add","a,#0x%02x",
448 ((char)(sym->stack - _G.nRegsSaved )) :
449 ((char)sym->stack)) & 0xff);
450 pic14_emitcode("mov","%s,a",
451 aop->aopu.aop_ptr->name);
454 pic14_emitcode("pop","acc");
456 pic14_emitcode("mov","%s,#%s",
457 aop->aopu.aop_ptr->name,
459 aop->paged = space->paged;
461 aop->aopu.aop_stk = sym->stack;
465 if (sym->onStack && options.stack10bit)
467 /* It's on the 10 bit stack, which is located in
471 //DEBUGpic14_emitcode(";","%d",__LINE__);
474 pic14_emitcode("push","acc");
476 pic14_emitcode("mov","a,_bp");
477 pic14_emitcode("add","a,#0x%02x",
479 ((char)(sym->stack - _G.nRegsSaved )) :
480 ((char)sym->stack)) & 0xff);
483 pic14_emitcode ("mov","dpx1,#0x40");
484 pic14_emitcode ("mov","dph1,#0x00");
485 pic14_emitcode ("mov","dpl1, a");
489 pic14_emitcode("pop","acc");
491 sym->aop = aop = newAsmop(AOP_DPTR2);
492 aop->size = getSize(sym->type);
496 //DEBUGpic14_emitcode(";","%d",__LINE__);
497 /* if in bit space */
498 if (IN_BITSPACE(space)) {
499 sym->aop = aop = newAsmop (AOP_CRY);
500 aop->aopu.aop_dir = sym->rname ;
501 aop->size = getSize(sym->type);
502 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
505 /* if it is in direct space */
506 if (IN_DIRSPACE(space)) {
507 sym->aop = aop = newAsmop (AOP_DIR);
508 aop->aopu.aop_dir = sym->rname ;
509 aop->size = getSize(sym->type);
510 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
514 /* special case for a function */
515 if (IS_FUNC(sym->type)) {
516 sym->aop = aop = newAsmop(AOP_IMMD);
517 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
518 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
519 strcpy(aop->aopu.aop_immd,sym->rname);
520 aop->size = FPTRSIZE;
525 /* only remaining is far space */
526 /* in which case DPTR gets the address */
527 sym->aop = aop = newAsmop(AOP_DPTR);
528 pic14_emitcode ("mov","dptr,#%s", sym->rname);
529 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
532 /* if it is in code space */
533 if (IN_CODESPACE(space))
539 /*-----------------------------------------------------------------*/
540 /* aopForRemat - rematerialzes an object */
541 /*-----------------------------------------------------------------*/
542 static asmop *aopForRemat (symbol *sym)
544 iCode *ic = sym->rematiCode;
545 asmop *aop = newAsmop(AOP_IMMD);
547 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
550 val += (int) operandLitValue(IC_RIGHT(ic));
551 else if (ic->op == '-')
552 val -= (int) operandLitValue(IC_RIGHT(ic));
556 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
560 sprintf(buffer,"(%s %c 0x%04x)",
561 OP_SYMBOL(IC_LEFT(ic))->rname,
562 val >= 0 ? '+' : '-',
565 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
567 //DEBUGpic14_emitcode(";","%s",buffer);
568 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
569 strcpy(aop->aopu.aop_immd,buffer);
573 int aopIdx (asmop *aop, int offset)
578 if(aop->type != AOP_REG)
581 return aop->aopu.aop_reg[offset]->rIdx;
584 /*-----------------------------------------------------------------*/
585 /* regsInCommon - two operands have some registers in common */
586 /*-----------------------------------------------------------------*/
587 static bool regsInCommon (operand *op1, operand *op2)
592 /* if they have registers in common */
593 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
596 sym1 = OP_SYMBOL(op1);
597 sym2 = OP_SYMBOL(op2);
599 if (sym1->nRegs == 0 || sym2->nRegs == 0)
602 for (i = 0 ; i < sym1->nRegs ; i++) {
607 for (j = 0 ; j < sym2->nRegs ;j++ ) {
611 if (sym2->regs[j] == sym1->regs[i])
619 /*-----------------------------------------------------------------*/
620 /* operandsEqu - equivalent */
621 /*-----------------------------------------------------------------*/
622 static bool operandsEqu ( operand *op1, operand *op2)
626 /* if they not symbols */
627 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
630 sym1 = OP_SYMBOL(op1);
631 sym2 = OP_SYMBOL(op2);
633 /* if both are itemps & one is spilt
634 and the other is not then false */
635 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
636 sym1->isspilt != sym2->isspilt )
639 /* if they are the same */
643 if (strcmp(sym1->rname,sym2->rname) == 0)
647 /* if left is a tmp & right is not */
651 (sym1->usl.spillLoc == sym2))
658 (sym2->usl.spillLoc == sym1))
664 /*-----------------------------------------------------------------*/
665 /* pic14_sameRegs - two asmops have the same registers */
666 /*-----------------------------------------------------------------*/
667 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
674 if (aop1->type != AOP_REG ||
675 aop2->type != AOP_REG )
678 if (aop1->size != aop2->size )
681 for (i = 0 ; i < aop1->size ; i++ )
682 if (aop1->aopu.aop_reg[i] !=
683 aop2->aopu.aop_reg[i] )
689 /*-----------------------------------------------------------------*/
690 /* aopOp - allocates an asmop for an operand : */
691 /*-----------------------------------------------------------------*/
692 void aopOp (operand *op, iCode *ic, bool result)
701 DEBUGpic14_emitcode(";","%d",__LINE__);
702 /* if this a literal */
703 if (IS_OP_LITERAL(op)) {
704 op->aop = aop = newAsmop(AOP_LIT);
705 aop->aopu.aop_lit = op->operand.valOperand;
706 aop->size = getSize(operandType(op));
707 DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
711 /* if already has a asmop then continue */
715 /* if the underlying symbol has a aop */
716 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
717 DEBUGpic14_emitcode(";","%d",__LINE__);
718 op->aop = OP_SYMBOL(op)->aop;
722 /* if this is a true symbol */
723 if (IS_TRUE_SYMOP(op)) {
724 DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
725 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
729 /* this is a temporary : this has
735 e) can be a return use only */
740 /* if the type is a conditional */
741 if (sym->regType == REG_CND) {
742 DEBUGpic14_emitcode(";","%d",__LINE__);
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);
759 DEBUGpic14_emitcode(";","%d",__LINE__);
765 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
766 aop->size = getSize(sym->type);
767 for ( i = 0 ; i < 2 ; i++ )
768 aop->aopu.aop_str[i] = accUse[i];
769 DEBUGpic14_emitcode(";","%d",__LINE__);
775 aop = op->aop = sym->aop = newAsmop(AOP_STR);
776 aop->size = getSize(sym->type);
777 for ( i = 0 ; i < fReturnSizePic ; i++ )
778 aop->aopu.aop_str[i] = fReturn[i];
779 DEBUGpic14_emitcode(";","%d",__LINE__);
783 /* else spill location */
784 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
785 sym->aop = op->aop = aop =
786 aopForSym(ic,sym->usl.spillLoc,result);
787 aop->size = getSize(sym->type);
791 /* must be in a register */
792 sym->aop = op->aop = aop = newAsmop(AOP_REG);
793 aop->size = sym->nRegs;
794 for ( i = 0 ; i < sym->nRegs ;i++)
795 aop->aopu.aop_reg[i] = sym->regs[i];
798 /*-----------------------------------------------------------------*/
799 /* freeAsmop - free up the asmop given to an operand */
800 /*----------------------------------------------------------------*/
801 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
818 /* depending on the asmop type only three cases need work AOP_RO
819 , 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");
888 /* all other cases just dealloc */
892 OP_SYMBOL(op)->aop = NULL;
893 /* if the symbol has a spill */
895 SPIL_LOC(op)->aop = NULL;
900 /*-----------------------------------------------------------------*/
901 /* aopGet - for fetching value of the aop */
902 /*-----------------------------------------------------------------*/
903 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
908 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
909 /* offset is greater than
911 if (offset > (aop->size - 1) &&
912 aop->type != AOP_LIT)
915 /* depending on type */
920 DEBUGpic14_emitcode(";","%d",__LINE__);
921 /* if we need to increment it */
922 while (offset > aop->coff) {
923 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
927 while (offset < aop->coff) {
928 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
934 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
935 return (dname ? "acc" : "a");
937 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
938 rs = Safe_calloc(1,strlen(s)+1);
944 DEBUGpic14_emitcode(";","%d",__LINE__);
945 if (aop->type == AOP_DPTR2)
950 while (offset > aop->coff) {
951 pic14_emitcode ("inc","dptr");
955 while (offset < aop->coff) {
956 pic14_emitcode("lcall","__decdptr");
962 pic14_emitcode("clr","a");
963 pic14_emitcode("movc","a,@a+dptr");
966 pic14_emitcode("movx","a,@dptr");
969 if (aop->type == AOP_DPTR2)
974 return (dname ? "acc" : "a");
978 DEBUGpic14_emitcode(";","%d",__LINE__);
980 sprintf (s,"%s",aop->aopu.aop_immd);
983 sprintf(s,"(%s >> %d)",
989 rs = Safe_calloc(1,strlen(s)+1);
995 sprintf(s,"(%s + %d)",
999 sprintf(s,"%s",aop->aopu.aop_dir);
1000 rs = Safe_calloc(1,strlen(s)+1);
1005 DEBUGpic14_emitcode(";","%d",__LINE__);
1007 return aop->aopu.aop_reg[offset]->dname;
1009 return aop->aopu.aop_reg[offset]->name;
1012 pic14_emitcode(";","%d",__LINE__);
1013 //pic14_emitcode("clr","a");
1014 //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1015 //pic14_emitcode("rlc","a") ;
1016 //return (dname ? "acc" : "a");
1017 return aop->aopu.aop_dir;
1020 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1021 //if (!offset && dname)
1023 //return aop->aopu.aop_str[offset];
1024 return "AOP_accumulator_bug";
1027 DEBUGpic14_emitcode(";","%d",__LINE__);
1028 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1029 rs = Safe_calloc(1,strlen(s)+1);
1034 DEBUGpic14_emitcode(";","%d",__LINE__);
1035 aop->coff = offset ;
1036 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1040 return aop->aopu.aop_str[offset];
1044 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1045 "aopget got unsupported aop->type");
1049 /*-----------------------------------------------------------------*/
1050 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1051 /*-----------------------------------------------------------------*/
1052 pCodeOp *popGetLabel(unsigned int key)
1055 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1060 return newpCodeOpLabel(key+100+labelOffset);
1063 /*-----------------------------------------------------------------*/
1064 /* popCopyReg - copy a pcode operator */
1065 /*-----------------------------------------------------------------*/
1066 pCodeOp *popCopyReg(pCodeOpReg *pc)
1070 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1071 pcor->pcop.type = pc->pcop.type;
1072 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1073 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1075 pcor->rIdx = pc->rIdx;
1081 /*-----------------------------------------------------------------*/
1082 /* popCopy - copy a pcode operator */
1083 /*-----------------------------------------------------------------*/
1084 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1088 pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1089 pcop->type = PO_BIT;
1090 if(!(pcop->name = Safe_strdup(pc->name)))
1091 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1092 ((pCodeOpBit *)pcop)->bit = bitval;
1094 ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1099 /*-----------------------------------------------------------------*/
1100 /* popGet - asm operator to pcode operator conversion */
1101 /*-----------------------------------------------------------------*/
1102 pCodeOp *popGetLit(unsigned int lit)
1105 return newpCodeOpLit(lit);
1109 /*-----------------------------------------------------------------*/
1110 /* popGet - asm operator to pcode operator conversion */
1111 /*-----------------------------------------------------------------*/
1112 pCodeOp *popGetWithString(char *str)
1118 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1122 pcop = newpCodeOp(str,PO_STR);
1127 pCodeOp *popRegFromString(char *str)
1130 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1131 pcop->type = PO_GPR_REGISTER;
1133 PCOR(pcop)->rIdx = -1;
1134 PCOR(pcop)->r = NULL;
1136 DEBUGpic14_emitcode(";","%d",__LINE__);
1137 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1142 pCodeOp *popRegFromIdx(int rIdx)
1146 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1147 __FUNCTION__,__LINE__,rIdx);
1149 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1151 PCOR(pcop)->rIdx = rIdx;
1152 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1153 PCOR(pcop)->r->isFree = 0;
1154 PCOR(pcop)->r->wasUsed = 1;
1156 pcop->type = PCOR(pcop)->r->pc_type;
1161 /*-----------------------------------------------------------------*/
1162 /* popGet - asm operator to pcode operator conversion */
1163 /*-----------------------------------------------------------------*/
1164 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1171 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1172 /* offset is greater than
1175 if (offset > (aop->size - 1) &&
1176 aop->type != AOP_LIT)
1177 return NULL; //zero;
1179 /* depending on type */
1180 switch (aop->type) {
1187 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1188 //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1189 //pcop->type = PO_SFR_REGISTER;
1191 //PCOR(pcop)->rIdx = -1;
1192 //PCOR(pcop)->r = NULL;
1193 // Really nasty hack to check for temporary registers
1195 //pcop->name = Safe_strdup("BAD_REGISTER");
1200 DEBUGpic14_emitcode(";","%d",__LINE__);
1201 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1202 pcop->type = PO_IMMEDIATE;
1204 sprintf (s,"%s",aop->aopu.aop_immd);
1207 sprintf(s,"(%s >> %d)",
1212 aop->aopu.aop_immd);
1213 pcop->name = Safe_calloc(1,strlen(s)+1);
1214 strcpy(pcop->name,s);
1218 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1219 pcop->type = PO_DIR;
1221 sprintf(s,"(%s + %d)",
1225 sprintf(s,"%s",aop->aopu.aop_dir);
1226 pcop->name = Safe_calloc(1,strlen(s)+1);
1227 strcpy(pcop->name,s);
1232 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1234 DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1236 pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1238 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239 //pcop->type = PO_GPR_REGISTER;
1240 PCOR(pcop)->rIdx = rIdx;
1241 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1242 pcop->type = PCOR(pcop)->r->pc_type;
1245 rs = aop->aopu.aop_reg[offset]->dname;
1247 rs = aop->aopu.aop_reg[offset]->name;
1249 DEBUGpic14_emitcode(";","%d %s",__LINE__,rs);
1255 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1259 DEBUGpic14_emitcode(";","%d",__LINE__);
1260 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1263 DEBUGpic14_emitcode(";","%d",__LINE__);
1265 pcop = Safe_calloc(1,sizeof(pCodeOp) );
1266 pcop->type = PO_STR;
1268 //aop->coff = offset ;
1269 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1270 sprintf(s,"%s","acc");
1272 sprintf(s,"%s",aop->aopu.aop_str[offset]);
1273 pcop->name = Safe_calloc(1,strlen(s)+1);
1274 strcpy(pcop->name,s);
1279 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280 "popGet got unsupported aop->type");
1283 /*-----------------------------------------------------------------*/
1284 /* aopPut - puts a string for a aop */
1285 /*-----------------------------------------------------------------*/
1286 void aopPut (asmop *aop, char *s, int offset)
1291 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1293 if (aop->size && offset > ( aop->size - 1)) {
1294 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1295 "aopPut got offset > aop->size");
1299 /* will assign value to value */
1300 /* depending on where it is ofcourse */
1301 switch (aop->type) {
1304 sprintf(d,"(%s + %d)",
1305 aop->aopu.aop_dir,offset);
1307 sprintf(d,"%s",aop->aopu.aop_dir);
1310 DEBUGpic14_emitcode(";","%d",__LINE__);
1312 pic14_emitcode("movf","%s,w",s);
1313 pic14_emitcode("movwf","%s",d);
1316 pic14_emitcode(";BUG! should have this:movf","%s,w %d",s,__LINE__);
1317 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1324 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1325 strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1328 strcmp(s,"r0") == 0 ||
1329 strcmp(s,"r1") == 0 ||
1330 strcmp(s,"r2") == 0 ||
1331 strcmp(s,"r3") == 0 ||
1332 strcmp(s,"r4") == 0 ||
1333 strcmp(s,"r5") == 0 ||
1334 strcmp(s,"r6") == 0 ||
1335 strcmp(s,"r7") == 0 )
1336 pic14_emitcode("mov","%s,%s ; %d",
1337 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1342 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1344 pic14_emitcode("movwf","%s",
1345 aop->aopu.aop_reg[offset]->name);
1348 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1349 pcop->type = PO_GPR_REGISTER;
1351 PCOR(pcop)->rIdx = -1;
1352 PCOR(pcop)->r = NULL;
1354 DEBUGpic14_emitcode(";","%d",__LINE__);
1355 pcop->name = Safe_strdup(s);
1356 emitpcode(POC_MOVFW,pcop);
1358 emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1366 if (aop->type == AOP_DPTR2)
1372 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1373 "aopPut writting to code space");
1377 while (offset > aop->coff) {
1379 pic14_emitcode ("inc","dptr");
1382 while (offset < aop->coff) {
1384 pic14_emitcode("lcall","__decdptr");
1389 /* if not in accumulater */
1392 pic14_emitcode ("movx","@dptr,a");
1394 if (aop->type == AOP_DPTR2)
1402 while (offset > aop->coff) {
1404 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1406 while (offset < aop->coff) {
1408 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1414 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1419 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1421 if (strcmp(s,"r0") == 0 ||
1422 strcmp(s,"r1") == 0 ||
1423 strcmp(s,"r2") == 0 ||
1424 strcmp(s,"r3") == 0 ||
1425 strcmp(s,"r4") == 0 ||
1426 strcmp(s,"r5") == 0 ||
1427 strcmp(s,"r6") == 0 ||
1428 strcmp(s,"r7") == 0 ) {
1430 sprintf(buffer,"a%s",s);
1431 pic14_emitcode("mov","@%s,%s",
1432 aop->aopu.aop_ptr->name,buffer);
1434 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1439 if (strcmp(s,"a") == 0)
1440 pic14_emitcode("push","acc");
1442 pic14_emitcode("push","%s",s);
1447 /* if bit variable */
1448 if (!aop->aopu.aop_dir) {
1449 pic14_emitcode("clr","a");
1450 pic14_emitcode("rlc","a");
1453 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1456 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1459 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1461 lbl = newiTempLabel(NULL);
1463 if (strcmp(s,"a")) {
1466 pic14_emitcode("clr","c");
1467 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1468 pic14_emitcode("cpl","c");
1469 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1470 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1477 if (strcmp(aop->aopu.aop_str[offset],s))
1478 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1483 if (!offset && (strcmp(s,"acc") == 0))
1486 if (strcmp(aop->aopu.aop_str[offset],s))
1487 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1491 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1492 "aopPut got unsupported aop->type");
1498 /*-----------------------------------------------------------------*/
1499 /* reAdjustPreg - points a register back to where it should */
1500 /*-----------------------------------------------------------------*/
1501 static void reAdjustPreg (asmop *aop)
1505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1507 if ((size = aop->size) <= 1)
1510 switch (aop->type) {
1514 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1518 if (aop->type == AOP_DPTR2)
1524 pic14_emitcode("lcall","__decdptr");
1527 if (aop->type == AOP_DPTR2)
1537 /*-----------------------------------------------------------------*/
1538 /* genNotFloat - generates not for float operations */
1539 /*-----------------------------------------------------------------*/
1540 static void genNotFloat (operand *op, operand *res)
1546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1547 /* we will put 127 in the first byte of
1549 aopPut(AOP(res),"#127",0);
1550 size = AOP_SIZE(op) - 1;
1553 l = aopGet(op->aop,offset++,FALSE,FALSE);
1557 pic14_emitcode("orl","a,%s",
1559 offset++,FALSE,FALSE));
1561 tlbl = newiTempLabel(NULL);
1563 tlbl = newiTempLabel(NULL);
1564 aopPut(res->aop,one,1);
1565 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1566 aopPut(res->aop,zero,1);
1567 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1569 size = res->aop->size - 2;
1571 /* put zeros in the rest */
1573 aopPut(res->aop,zero,offset++);
1577 /*-----------------------------------------------------------------*/
1578 /* opIsGptr: returns non-zero if the passed operand is */
1579 /* a generic pointer type. */
1580 /*-----------------------------------------------------------------*/
1581 static int opIsGptr(operand *op)
1583 sym_link *type = operandType(op);
1585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1586 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1594 /*-----------------------------------------------------------------*/
1595 /* pic14_getDataSize - get the operand data size */
1596 /*-----------------------------------------------------------------*/
1597 int pic14_getDataSize(operand *op)
1599 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1602 return AOP_SIZE(op);
1604 // tsd- in the pic port, the genptr size is 1, so this code here
1605 // fails. ( in the 8051 port, the size was 4).
1608 size = AOP_SIZE(op);
1609 if (size == GPTRSIZE)
1611 sym_link *type = operandType(op);
1612 if (IS_GENPTR(type))
1614 /* generic pointer; arithmetic operations
1615 * should ignore the high byte (pointer type).
1618 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1625 /*-----------------------------------------------------------------*/
1626 /* pic14_outAcc - output Acc */
1627 /*-----------------------------------------------------------------*/
1628 void pic14_outAcc(operand *result)
1631 DEBUGpic14_emitcode ("; ***","%s %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1634 size = pic14_getDataSize(result);
1636 aopPut(AOP(result),"a",0);
1639 /* unsigned or positive */
1641 aopPut(AOP(result),zero,offset++);
1647 /*-----------------------------------------------------------------*/
1648 /* pic14_outBitC - output a bit C */
1649 /*-----------------------------------------------------------------*/
1650 void pic14_outBitC(operand *result)
1653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1654 /* if the result is bit */
1655 if (AOP_TYPE(result) == AOP_CRY)
1656 aopPut(AOP(result),"c",0);
1658 pic14_emitcode("clr","a ; %d", __LINE__);
1659 pic14_emitcode("rlc","a");
1660 pic14_outAcc(result);
1664 /*-----------------------------------------------------------------*/
1665 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1666 /*-----------------------------------------------------------------*/
1667 void pic14_toBoolean(operand *oper)
1669 int size = AOP_SIZE(oper) - 1;
1672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 if ( AOP_TYPE(oper) != AOP_ACC) {
1675 emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1676 pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1679 pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1680 emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1685 /*-----------------------------------------------------------------*/
1686 /* genNot - generate code for ! operation */
1687 /*-----------------------------------------------------------------*/
1688 static void genNot (iCode *ic)
1691 sym_link *optype = operandType(IC_LEFT(ic));
1693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1694 /* assign asmOps to operand & result */
1695 aopOp (IC_LEFT(ic),ic,FALSE);
1696 aopOp (IC_RESULT(ic),ic,TRUE);
1698 /* if in bit space then a special case */
1699 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1700 pic14_emitcode("movlw","1<<%s");
1701 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1702 //pic14_emitcode("cpl","c");
1703 //pic14_outBitC(IC_RESULT(ic));
1707 /* if type float then do float */
1708 if (IS_FLOAT(optype)) {
1709 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1713 pic14_toBoolean(IC_LEFT(ic));
1715 tlbl = newiTempLabel(NULL);
1716 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1717 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1718 pic14_outBitC(IC_RESULT(ic));
1721 /* release the aops */
1722 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1723 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1727 /*-----------------------------------------------------------------*/
1728 /* genCpl - generate code for complement */
1729 /*-----------------------------------------------------------------*/
1730 static void genCpl (iCode *ic)
1736 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1737 /* assign asmOps to operand & result */
1738 aopOp (IC_LEFT(ic),ic,FALSE);
1739 aopOp (IC_RESULT(ic),ic,TRUE);
1741 /* if both are in bit space then
1743 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1744 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1746 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1747 pic14_emitcode("cpl","c");
1748 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1752 size = AOP_SIZE(IC_RESULT(ic));
1754 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1756 pic14_emitcode("cpl","a");
1757 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1762 /* release the aops */
1763 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1764 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1767 /*-----------------------------------------------------------------*/
1768 /* genUminusFloat - unary minus for floating points */
1769 /*-----------------------------------------------------------------*/
1770 static void genUminusFloat(operand *op,operand *result)
1772 int size ,offset =0 ;
1775 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1776 /* for this we just need to flip the
1777 first it then copy the rest in place */
1778 size = AOP_SIZE(op) - 1;
1779 l = aopGet(AOP(op),3,FALSE,FALSE);
1783 pic14_emitcode("cpl","acc.7");
1784 aopPut(AOP(result),"a",3);
1788 aopGet(AOP(op),offset,FALSE,FALSE),
1794 /*-----------------------------------------------------------------*/
1795 /* genUminus - unary minus code generation */
1796 /*-----------------------------------------------------------------*/
1797 static void genUminus (iCode *ic)
1800 sym_link *optype, *rtype;
1803 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1805 aopOp(IC_LEFT(ic),ic,FALSE);
1806 aopOp(IC_RESULT(ic),ic,TRUE);
1808 /* if both in bit space then special
1810 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1811 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1813 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1814 pic14_emitcode("cpl","c");
1815 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1819 optype = operandType(IC_LEFT(ic));
1820 rtype = operandType(IC_RESULT(ic));
1822 /* if float then do float stuff */
1823 if (IS_FLOAT(optype)) {
1824 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1828 /* otherwise subtract from zero */
1829 size = AOP_SIZE(IC_LEFT(ic));
1833 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1834 if (!strcmp(l,"a")) {
1835 pic14_emitcode("cpl","a");
1836 pic14_emitcode("inc","a");
1838 pic14_emitcode("clr","a");
1839 pic14_emitcode("subb","a,%s",l);
1841 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1844 /* if any remaining bytes in the result */
1845 /* we just need to propagate the sign */
1846 if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1847 pic14_emitcode("rlc","a");
1848 pic14_emitcode("subb","a,acc");
1850 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1854 /* release the aops */
1855 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1856 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1859 /*-----------------------------------------------------------------*/
1860 /* saveRegisters - will look for a call and save the registers */
1861 /*-----------------------------------------------------------------*/
1862 static void saveRegisters(iCode *lic)
1869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1871 for (ic = lic ; ic ; ic = ic->next)
1872 if (ic->op == CALL || ic->op == PCALL)
1876 fprintf(stderr,"found parameter push with no function call\n");
1880 /* if the registers have been saved already then
1882 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1885 /* find the registers in use at this time
1886 and push them away to safety */
1887 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1891 if (options.useXstack) {
1892 if (bitVectBitValue(rsave,R0_IDX))
1893 pic14_emitcode("mov","b,r0");
1894 pic14_emitcode("mov","r0,%s",spname);
1895 for (i = 0 ; i < pic14_nRegs ; i++) {
1896 if (bitVectBitValue(rsave,i)) {
1898 pic14_emitcode("mov","a,b");
1900 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1901 pic14_emitcode("movx","@r0,a");
1902 pic14_emitcode("inc","r0");
1905 pic14_emitcode("mov","%s,r0",spname);
1906 if (bitVectBitValue(rsave,R0_IDX))
1907 pic14_emitcode("mov","r0,b");
1909 for (i = 0 ; i < pic14_nRegs ; i++) {
1910 if (bitVectBitValue(rsave,i))
1911 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1914 dtype = operandType(IC_LEFT(ic));
1916 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1917 IFFUNC_ISISR(currFunc->type) &&
1920 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1923 /*-----------------------------------------------------------------*/
1924 /* unsaveRegisters - pop the pushed registers */
1925 /*-----------------------------------------------------------------*/
1926 static void unsaveRegisters (iCode *ic)
1931 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1932 /* find the registers in use at this time
1933 and push them away to safety */
1934 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1937 if (options.useXstack) {
1938 pic14_emitcode("mov","r0,%s",spname);
1939 for (i = pic14_nRegs ; i >= 0 ; i--) {
1940 if (bitVectBitValue(rsave,i)) {
1941 pic14_emitcode("dec","r0");
1942 pic14_emitcode("movx","a,@r0");
1944 pic14_emitcode("mov","b,a");
1946 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1950 pic14_emitcode("mov","%s,r0",spname);
1951 if (bitVectBitValue(rsave,R0_IDX))
1952 pic14_emitcode("mov","r0,b");
1954 for (i = pic14_nRegs ; i >= 0 ; i--) {
1955 if (bitVectBitValue(rsave,i))
1956 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1962 /*-----------------------------------------------------------------*/
1964 /*-----------------------------------------------------------------*/
1965 static void pushSide(operand * oper, int size)
1969 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1972 if (AOP_TYPE(oper) != AOP_REG &&
1973 AOP_TYPE(oper) != AOP_DIR &&
1975 pic14_emitcode("mov","a,%s",l);
1976 pic14_emitcode("push","acc");
1978 pic14_emitcode("push","%s",l);
1983 /*-----------------------------------------------------------------*/
1984 /* assignResultValue - */
1985 /*-----------------------------------------------------------------*/
1986 static void assignResultValue(operand * oper)
1989 int size = AOP_SIZE(oper);
1991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1993 if(!GpsuedoStkPtr) {
1994 /* The last byte in the assignment is in W */
1995 //aopPut(AOP(oper),"W",size-1);
1996 emitpcode(POC_MOVWF, popGet(AOP(oper),0,FALSE,FALSE));
2005 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2006 emitpcode(POC_MOVWF, popGet(AOP(oper),offset,FALSE,FALSE));
2014 /*-----------------------------------------------------------------*/
2015 /* genXpush - pushes onto the external stack */
2016 /*-----------------------------------------------------------------*/
2017 static void genXpush (iCode *ic)
2019 asmop *aop = newAsmop(0);
2021 int size,offset = 0;
2023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2024 aopOp(IC_LEFT(ic),ic,FALSE);
2025 r = getFreePtr(ic,&aop,FALSE);
2028 pic14_emitcode("mov","%s,_spx",r->name);
2030 size = AOP_SIZE(IC_LEFT(ic));
2033 char *l = aopGet(AOP(IC_LEFT(ic)),
2034 offset++,FALSE,FALSE);
2036 pic14_emitcode("movx","@%s,a",r->name);
2037 pic14_emitcode("inc","%s",r->name);
2042 pic14_emitcode("mov","_spx,%s",r->name);
2044 freeAsmop(NULL,aop,ic,TRUE);
2045 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2048 /*-----------------------------------------------------------------*/
2049 /* genIpush - genrate code for pushing this gets a little complex */
2050 /*-----------------------------------------------------------------*/
2051 static void genIpush (iCode *ic)
2053 int size, offset = 0 ;
2057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2058 /* if this is not a parm push : ie. it is spill push
2059 and spill push is always done on the local stack */
2060 if (!ic->parmPush) {
2062 /* and the item is spilt then do nothing */
2063 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2066 aopOp(IC_LEFT(ic),ic,FALSE);
2067 size = AOP_SIZE(IC_LEFT(ic));
2068 /* push it on the stack */
2070 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2075 pic14_emitcode("push","%s",l);
2080 /* this is a paramter push: in this case we call
2081 the routine to find the call and save those
2082 registers that need to be saved */
2085 /* if use external stack then call the external
2086 stack pushing routine */
2087 if (options.useXstack) {
2092 /* then do the push */
2093 aopOp(IC_LEFT(ic),ic,FALSE);
2096 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2097 size = AOP_SIZE(IC_LEFT(ic));
2100 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2101 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2102 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2104 pic14_emitcode("mov","a,%s",l);
2105 pic14_emitcode("push","acc");
2107 pic14_emitcode("push","%s",l);
2110 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2113 /*-----------------------------------------------------------------*/
2114 /* genIpop - recover the registers: can happen only for spilling */
2115 /*-----------------------------------------------------------------*/
2116 static void genIpop (iCode *ic)
2121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2122 /* if the temp was not pushed then */
2123 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2126 aopOp(IC_LEFT(ic),ic,FALSE);
2127 size = AOP_SIZE(IC_LEFT(ic));
2130 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2133 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2136 /*-----------------------------------------------------------------*/
2137 /* unsaverbank - restores the resgister bank from stack */
2138 /*-----------------------------------------------------------------*/
2139 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2147 if (options.useXstack) {
2149 r = getFreePtr(ic,&aop,FALSE);
2152 pic14_emitcode("mov","%s,_spx",r->name);
2153 pic14_emitcode("movx","a,@%s",r->name);
2154 pic14_emitcode("mov","psw,a");
2155 pic14_emitcode("dec","%s",r->name);
2158 pic14_emitcode ("pop","psw");
2161 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2162 if (options.useXstack) {
2163 pic14_emitcode("movx","a,@%s",r->name);
2164 //pic14_emitcode("mov","(%s+%d),a",
2165 // regspic14[i].base,8*bank+regspic14[i].offset);
2166 pic14_emitcode("dec","%s",r->name);
2169 pic14_emitcode("pop",""); //"(%s+%d)",
2170 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2173 if (options.useXstack) {
2175 pic14_emitcode("mov","_spx,%s",r->name);
2176 freeAsmop(NULL,aop,ic,TRUE);
2181 /*-----------------------------------------------------------------*/
2182 /* saverbank - saves an entire register bank on the stack */
2183 /*-----------------------------------------------------------------*/
2184 static void saverbank (int bank, iCode *ic, bool pushPsw)
2190 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2191 if (options.useXstack) {
2194 r = getFreePtr(ic,&aop,FALSE);
2195 pic14_emitcode("mov","%s,_spx",r->name);
2199 for (i = 0 ; i < pic14_nRegs ;i++) {
2200 if (options.useXstack) {
2201 pic14_emitcode("inc","%s",r->name);
2202 //pic14_emitcode("mov","a,(%s+%d)",
2203 // regspic14[i].base,8*bank+regspic14[i].offset);
2204 pic14_emitcode("movx","@%s,a",r->name);
2206 pic14_emitcode("push","");// "(%s+%d)",
2207 //regspic14[i].base,8*bank+regspic14[i].offset);
2211 if (options.useXstack) {
2212 pic14_emitcode("mov","a,psw");
2213 pic14_emitcode("movx","@%s,a",r->name);
2214 pic14_emitcode("inc","%s",r->name);
2215 pic14_emitcode("mov","_spx,%s",r->name);
2216 freeAsmop (NULL,aop,ic,TRUE);
2219 pic14_emitcode("push","psw");
2221 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2227 /*-----------------------------------------------------------------*/
2228 /* genCall - generates a call statement */
2229 /*-----------------------------------------------------------------*/
2230 static void genCall (iCode *ic)
2234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2236 /* if caller saves & we have not saved then */
2240 /* if we are calling a function that is not using
2241 the same register bank then we need to save the
2242 destination registers on the stack */
2243 dtype = operandType(IC_LEFT(ic));
2245 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2246 IFFUNC_ISISR(currFunc->type) &&
2249 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2251 /* if send set is not empty the assign */
2254 /* For the Pic port, there is no data stack.
2255 * So parameters passed to functions are stored
2256 * in registers. (The pCode optimizer will get
2257 * rid of most of these :).
2260 int firstTimeThruLoop = 1;
2262 for (sic = setFirstItem(_G.sendSet) ; sic ;
2263 sic = setNextItem(_G.sendSet)) {
2264 int size, offset = 0;
2266 aopOp(IC_LEFT(sic),sic,FALSE);
2267 size = AOP_SIZE(IC_LEFT(sic));
2271 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2273 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2274 AopType(AOP_TYPE(IC_LEFT(sic))));
2276 if(!firstTimeThruLoop) {
2277 /* If is not the first time we've been through the loop
2278 * then we need to save the parameter in a temporary
2279 * register. The last byte of the last parameter is
2281 pic14_emitcode("movwf","%s",fReturn[offset]);
2282 emitpcode(POC_MOVWF,popRegFromIdx(psuedoStkPtr + Gstack_base_addr));
2284 DEBUGpic14_emitcode ("; ","%d save param in %d",__LINE__,
2285 psuedoStkPtr+Gstack_base_addr);
2287 firstTimeThruLoop=0;
2289 if (strcmp(l,fReturn[offset])) {
2291 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2292 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2293 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2294 //pic14_emitcode("movlw","%s",l);
2296 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2297 //pic14_emitcode("movf","%s,w",l);
2299 /* The last one is passed in W but all others are passed on
2303 pic14_emitcode("movwf","%s",fReturn[offset]);
2304 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2310 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2315 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2316 OP_SYMBOL(IC_LEFT(ic))->rname :
2317 OP_SYMBOL(IC_LEFT(ic))->name));
2320 /* if we need assign a result value */
2321 if ((IS_ITEMP(IC_RESULT(ic)) &&
2322 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2323 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2324 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2327 aopOp(IC_RESULT(ic),ic,FALSE);
2330 assignResultValue(IC_RESULT(ic));
2332 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2333 AopType(AOP_TYPE(IC_RESULT(ic))));
2335 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2338 /* adjust the stack for parameters if
2340 if (ic->parmBytes) {
2342 if (ic->parmBytes > 3) {
2343 pic14_emitcode("mov","a,%s",spname);
2344 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2345 pic14_emitcode("mov","%s,a",spname);
2347 for ( i = 0 ; i < ic->parmBytes ;i++)
2348 pic14_emitcode("dec","%s",spname);
2352 /* if register bank was saved then pop them */
2354 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2356 /* if we hade saved some registers then unsave them */
2357 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2358 unsaveRegisters (ic);
2363 /*-----------------------------------------------------------------*/
2364 /* genPcall - generates a call by pointer statement */
2365 /*-----------------------------------------------------------------*/
2366 static void genPcall (iCode *ic)
2369 symbol *rlbl = newiTempLabel(NULL);
2372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2373 /* if caller saves & we have not saved then */
2377 /* if we are calling a function that is not using
2378 the same register bank then we need to save the
2379 destination registers on the stack */
2380 dtype = operandType(IC_LEFT(ic));
2382 IFFUNC_ISISR(currFunc->type) &&
2383 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2384 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2387 /* push the return address on to the stack */
2388 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2389 pic14_emitcode("push","acc");
2390 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2391 pic14_emitcode("push","acc");
2393 if (options.model == MODEL_FLAT24)
2395 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2396 pic14_emitcode("push","acc");
2399 /* now push the calling address */
2400 aopOp(IC_LEFT(ic),ic,FALSE);
2402 pushSide(IC_LEFT(ic), FPTRSIZE);
2404 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2406 /* if send set is not empty the assign */
2410 for (sic = setFirstItem(_G.sendSet) ; sic ;
2411 sic = setNextItem(_G.sendSet)) {
2412 int size, offset = 0;
2413 aopOp(IC_LEFT(sic),sic,FALSE);
2414 size = AOP_SIZE(IC_LEFT(sic));
2416 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2418 if (strcmp(l,fReturn[offset]))
2419 pic14_emitcode("mov","%s,%s",
2424 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2429 pic14_emitcode("ret","");
2430 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2433 /* if we need assign a result value */
2434 if ((IS_ITEMP(IC_RESULT(ic)) &&
2435 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2436 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2437 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2440 aopOp(IC_RESULT(ic),ic,FALSE);
2443 assignResultValue(IC_RESULT(ic));
2445 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2448 /* adjust the stack for parameters if
2450 if (ic->parmBytes) {
2452 if (ic->parmBytes > 3) {
2453 pic14_emitcode("mov","a,%s",spname);
2454 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2455 pic14_emitcode("mov","%s,a",spname);
2457 for ( i = 0 ; i < ic->parmBytes ;i++)
2458 pic14_emitcode("dec","%s",spname);
2462 /* if register bank was saved then unsave them */
2464 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2465 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2467 /* if we hade saved some registers then
2470 unsaveRegisters (ic);
2474 /*-----------------------------------------------------------------*/
2475 /* resultRemat - result is rematerializable */
2476 /*-----------------------------------------------------------------*/
2477 static int resultRemat (iCode *ic)
2479 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2480 if (SKIP_IC(ic) || ic->op == IFX)
2483 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2484 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2485 if (sym->remat && !POINTER_SET(ic))
2492 #if defined(__BORLANDC__) || defined(_MSC_VER)
2493 #define STRCASECMP stricmp
2495 #define STRCASECMP strcasecmp
2498 /*-----------------------------------------------------------------*/
2499 /* inExcludeList - return 1 if the string is in exclude Reg list */
2500 /*-----------------------------------------------------------------*/
2501 static bool inExcludeList(char *s)
2505 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2506 if (options.excludeRegs[i] &&
2507 STRCASECMP(options.excludeRegs[i],"none") == 0)
2510 for ( i = 0 ; options.excludeRegs[i]; i++) {
2511 if (options.excludeRegs[i] &&
2512 STRCASECMP(s,options.excludeRegs[i]) == 0)
2518 /*-----------------------------------------------------------------*/
2519 /* genFunction - generated code for function entry */
2520 /*-----------------------------------------------------------------*/
2521 static void genFunction (iCode *ic)
2526 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2528 labelOffset += (max_key+4);
2532 /* create the function header */
2533 pic14_emitcode(";","-----------------------------------------");
2534 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2535 pic14_emitcode(";","-----------------------------------------");
2537 pic14_emitcode("","%s:",sym->rname);
2538 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2540 ftype = operandType(IC_LEFT(ic));
2542 /* if critical function then turn interrupts off */
2543 if (IFFUNC_ISCRITICAL(ftype))
2544 pic14_emitcode("clr","ea");
2546 /* here we need to generate the equates for the
2547 register bank if required */
2549 if (FUNC_REGBANK(ftype) != rbank) {
2552 rbank = FUNC_REGBANK(ftype);
2553 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2554 if (strcmp(regspic14[i].base,"0") == 0)
2555 pic14_emitcode("","%s = 0x%02x",
2557 8*rbank+regspic14[i].offset);
2559 pic14_emitcode ("","%s = %s + 0x%02x",
2562 8*rbank+regspic14[i].offset);
2567 /* if this is an interrupt service routine then
2568 save acc, b, dpl, dph */
2569 if (IFFUNC_ISISR(sym->type)) {
2571 if (!inExcludeList("acc"))
2572 pic14_emitcode ("push","acc");
2573 if (!inExcludeList("b"))
2574 pic14_emitcode ("push","b");
2575 if (!inExcludeList("dpl"))
2576 pic14_emitcode ("push","dpl");
2577 if (!inExcludeList("dph"))
2578 pic14_emitcode ("push","dph");
2579 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2581 pic14_emitcode ("push", "dpx");
2582 /* Make sure we're using standard DPTR */
2583 pic14_emitcode ("push", "dps");
2584 pic14_emitcode ("mov", "dps, #0x00");
2585 if (options.stack10bit)
2587 /* This ISR could conceivably use DPTR2. Better save it. */
2588 pic14_emitcode ("push", "dpl1");
2589 pic14_emitcode ("push", "dph1");
2590 pic14_emitcode ("push", "dpx1");
2593 /* if this isr has no bank i.e. is going to
2594 run with bank 0 , then we need to save more
2596 if (!FUNC_REGBANK(sym->type)) {
2598 /* if this function does not call any other
2599 function then we can be economical and
2600 save only those registers that are used */
2601 if (! IFFUNC_HASFCALL(sym->type)) {
2604 /* if any registers used */
2605 if (sym->regsUsed) {
2606 /* save the registers used */
2607 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2608 if (bitVectBitValue(sym->regsUsed,i) ||
2609 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2610 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2615 /* this function has a function call cannot
2616 determines register usage so we will have the
2618 saverbank(0,ic,FALSE);
2622 /* if callee-save to be used for this function
2623 then save the registers being used in this function */
2624 if (IFFUNC_CALLEESAVES(sym->type)) {
2627 /* if any registers used */
2628 if (sym->regsUsed) {
2629 /* save the registers used */
2630 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2631 if (bitVectBitValue(sym->regsUsed,i) ||
2632 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2633 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2641 /* set the register bank to the desired value */
2642 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2643 pic14_emitcode("push","psw");
2644 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2647 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2649 if (options.useXstack) {
2650 pic14_emitcode("mov","r0,%s",spname);
2651 pic14_emitcode("mov","a,_bp");
2652 pic14_emitcode("movx","@r0,a");
2653 pic14_emitcode("inc","%s",spname);
2657 /* set up the stack */
2658 pic14_emitcode ("push","_bp"); /* save the callers stack */
2660 pic14_emitcode ("mov","_bp,%s",spname);
2663 /* adjust the stack for the function */
2668 werror(W_STACK_OVERFLOW,sym->name);
2670 if (i > 3 && sym->recvSize < 4) {
2672 pic14_emitcode ("mov","a,sp");
2673 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2674 pic14_emitcode ("mov","sp,a");
2679 pic14_emitcode("inc","sp");
2684 pic14_emitcode ("mov","a,_spx");
2685 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2686 pic14_emitcode ("mov","_spx,a");
2691 /*-----------------------------------------------------------------*/
2692 /* genEndFunction - generates epilogue for functions */
2693 /*-----------------------------------------------------------------*/
2694 static void genEndFunction (iCode *ic)
2696 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2700 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2702 pic14_emitcode ("mov","%s,_bp",spname);
2705 /* if use external stack but some variables were
2706 added to the local stack then decrement the
2708 if (options.useXstack && sym->stack) {
2709 pic14_emitcode("mov","a,sp");
2710 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2711 pic14_emitcode("mov","sp,a");
2715 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2716 if (options.useXstack) {
2717 pic14_emitcode("mov","r0,%s",spname);
2718 pic14_emitcode("movx","a,@r0");
2719 pic14_emitcode("mov","_bp,a");
2720 pic14_emitcode("dec","%s",spname);
2724 pic14_emitcode ("pop","_bp");
2728 /* restore the register bank */
2729 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2730 pic14_emitcode ("pop","psw");
2732 if (IFFUNC_ISISR(sym->type)) {
2734 /* now we need to restore the registers */
2735 /* if this isr has no bank i.e. is going to
2736 run with bank 0 , then we need to save more
2738 if (!FUNC_REGBANK(sym->type)) {
2740 /* if this function does not call any other
2741 function then we can be economical and
2742 save only those registers that are used */
2743 if (! IFFUNC_HASFCALL(sym->type)) {
2746 /* if any registers used */
2747 if (sym->regsUsed) {
2748 /* save the registers used */
2749 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2750 if (bitVectBitValue(sym->regsUsed,i) ||
2751 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2752 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2757 /* this function has a function call cannot
2758 determines register usage so we will have the
2760 unsaverbank(0,ic,FALSE);
2764 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2766 if (options.stack10bit)
2768 pic14_emitcode ("pop", "dpx1");
2769 pic14_emitcode ("pop", "dph1");
2770 pic14_emitcode ("pop", "dpl1");
2772 pic14_emitcode ("pop", "dps");
2773 pic14_emitcode ("pop", "dpx");
2775 if (!inExcludeList("dph"))
2776 pic14_emitcode ("pop","dph");
2777 if (!inExcludeList("dpl"))
2778 pic14_emitcode ("pop","dpl");
2779 if (!inExcludeList("b"))
2780 pic14_emitcode ("pop","b");
2781 if (!inExcludeList("acc"))
2782 pic14_emitcode ("pop","acc");
2784 if (IFFUNC_ISCRITICAL(sym->type))
2785 pic14_emitcode("setb","ea");
2787 /* if debug then send end of function */
2788 /* if (options.debug && currFunc) { */
2791 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2792 FileBaseName(ic->filename),currFunc->lastLine,
2793 ic->level,ic->block);
2794 if (IS_STATIC(currFunc->etype))
2795 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2797 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2801 pic14_emitcode ("reti","");
2804 if (IFFUNC_ISCRITICAL(sym->type))
2805 pic14_emitcode("setb","ea");
2807 if (IFFUNC_CALLEESAVES(sym->type)) {
2810 /* if any registers used */
2811 if (sym->regsUsed) {
2812 /* save the registers used */
2813 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2814 if (bitVectBitValue(sym->regsUsed,i) ||
2815 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2816 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2822 /* if debug then send end of function */
2825 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2826 FileBaseName(ic->filename),currFunc->lastLine,
2827 ic->level,ic->block);
2828 if (IS_STATIC(currFunc->etype))
2829 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2831 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2835 pic14_emitcode ("return","");
2836 emitpcodeNULLop(POC_RETURN);
2838 /* Mark the end of a function */
2839 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2844 /*-----------------------------------------------------------------*/
2845 /* genRet - generate code for return statement */
2846 /*-----------------------------------------------------------------*/
2847 static void genRet (iCode *ic)
2849 int size,offset = 0 , pushed = 0;
2851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2852 /* if we have no return value then
2853 just generate the "ret" */
2857 /* we have something to return then
2858 move the return value into place */
2859 aopOp(IC_LEFT(ic),ic,FALSE);
2860 size = AOP_SIZE(IC_LEFT(ic));
2864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2866 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2868 pic14_emitcode("push","%s",l);
2871 l = aopGet(AOP(IC_LEFT(ic)),offset,
2873 if (strcmp(fReturn[offset],l)) {
2874 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2875 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2876 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
2877 pic14_emitcode("movlw","%s",l);
2879 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
2880 pic14_emitcode("movf","%s,w",l);
2883 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2884 pic14_emitcode("movwf","%s",fReturn[offset]);
2894 if (strcmp(fReturn[pushed],"a"))
2895 pic14_emitcode("pop",fReturn[pushed]);
2897 pic14_emitcode("pop","acc");
2900 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2903 /* generate a jump to the return label
2904 if the next is not the return statement */
2905 if (!(ic->next && ic->next->op == LABEL &&
2906 IC_LABEL(ic->next) == returnLabel)) {
2908 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2909 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2914 /*-----------------------------------------------------------------*/
2915 /* genLabel - generates a label */
2916 /*-----------------------------------------------------------------*/
2917 static void genLabel (iCode *ic)
2919 /* special case never generate */
2920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2921 if (IC_LABEL(ic) == entryLabel)
2924 emitpLabel(IC_LABEL(ic)->key);
2925 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2928 /*-----------------------------------------------------------------*/
2929 /* genGoto - generates a goto */
2930 /*-----------------------------------------------------------------*/
2932 static void genGoto (iCode *ic)
2934 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2935 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2938 /*-----------------------------------------------------------------*/
2939 /* findLabelBackwards: walks back through the iCode chain looking */
2940 /* for the given label. Returns number of iCode instructions */
2941 /* between that label and given ic. */
2942 /* Returns zero if label not found. */
2943 /*-----------------------------------------------------------------*/
2945 static int findLabelBackwards(iCode *ic, int key)
2949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2955 if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2957 /* printf("findLabelBackwards = %d\n", count); */
2966 /*-----------------------------------------------------------------*/
2967 /* genMultbits :- multiplication of bits */
2968 /*-----------------------------------------------------------------*/
2969 static void genMultbits (operand *left,
2973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2975 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2976 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2977 pic14_outBitC(result);
2981 /*-----------------------------------------------------------------*/
2982 /* genMultOneByte : 8 bit multiplication & division */
2983 /*-----------------------------------------------------------------*/
2984 static void genMultOneByte (operand *left,
2988 sym_link *opetype = operandType(result);
2993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2994 /* (if two literals, the value is computed before) */
2995 /* if one literal, literal on the right */
2996 if (AOP_TYPE(left) == AOP_LIT){
3002 size = AOP_SIZE(result);
3003 /* signed or unsigned */
3004 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3005 l = aopGet(AOP(left),0,FALSE,FALSE);
3007 pic14_emitcode("mul","ab");
3008 /* if result size = 1, mul signed = mul unsigned */
3009 aopPut(AOP(result),"a",0);
3011 if (SPEC_USIGN(opetype)){
3012 aopPut(AOP(result),"b",1);
3014 /* for filling the MSBs */
3015 pic14_emitcode("clr","a");
3018 pic14_emitcode("mov","a,b");
3020 /* adjust the MSB if left or right neg */
3022 /* if one literal */
3023 if (AOP_TYPE(right) == AOP_LIT){
3024 /* AND literal negative */
3025 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3026 /* adjust MSB (c==0 after mul) */
3027 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3031 lbl = newiTempLabel(NULL);
3032 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3033 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3034 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3035 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3036 lbl = newiTempLabel(NULL);
3037 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
3038 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3039 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3042 lbl = newiTempLabel(NULL);
3043 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3044 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3045 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3046 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3047 lbl = newiTempLabel(NULL);
3048 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
3049 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
3050 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3052 aopPut(AOP(result),"a",1);
3055 pic14_emitcode("rlc","a");
3056 pic14_emitcode("subb","a,acc");
3063 aopPut(AOP(result),"a",offset++);
3067 /*-----------------------------------------------------------------*/
3068 /* genMult - generates code for multiplication */
3069 /*-----------------------------------------------------------------*/
3070 static void genMult (iCode *ic)
3072 operand *left = IC_LEFT(ic);
3073 operand *right = IC_RIGHT(ic);
3074 operand *result= IC_RESULT(ic);
3076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3077 /* assign the amsops */
3078 aopOp (left,ic,FALSE);
3079 aopOp (right,ic,FALSE);
3080 aopOp (result,ic,TRUE);
3082 /* special cases first */
3084 if (AOP_TYPE(left) == AOP_CRY &&
3085 AOP_TYPE(right)== AOP_CRY) {
3086 genMultbits(left,right,result);
3090 /* if both are of size == 1 */
3091 if (AOP_SIZE(left) == 1 &&
3092 AOP_SIZE(right) == 1 ) {
3093 genMultOneByte(left,right,result);
3097 /* should have been converted to function call */
3101 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3102 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3103 freeAsmop(result,NULL,ic,TRUE);
3106 /*-----------------------------------------------------------------*/
3107 /* genDivbits :- division of bits */
3108 /*-----------------------------------------------------------------*/
3109 static void genDivbits (operand *left,
3116 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3117 /* the result must be bit */
3118 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3119 l = aopGet(AOP(left),0,FALSE,FALSE);
3123 pic14_emitcode("div","ab");
3124 pic14_emitcode("rrc","a");
3125 aopPut(AOP(result),"c",0);
3128 /*-----------------------------------------------------------------*/
3129 /* genDivOneByte : 8 bit division */
3130 /*-----------------------------------------------------------------*/
3131 static void genDivOneByte (operand *left,
3135 sym_link *opetype = operandType(result);
3140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3141 size = AOP_SIZE(result) - 1;
3143 /* signed or unsigned */
3144 if (SPEC_USIGN(opetype)) {
3145 /* unsigned is easy */
3146 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3147 l = aopGet(AOP(left),0,FALSE,FALSE);
3149 pic14_emitcode("div","ab");
3150 aopPut(AOP(result),"a",0);
3152 aopPut(AOP(result),zero,offset++);
3156 /* signed is a little bit more difficult */
3158 /* save the signs of the operands */
3159 l = aopGet(AOP(left),0,FALSE,FALSE);
3161 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3162 pic14_emitcode("push","acc"); /* save it on the stack */
3164 /* now sign adjust for both left & right */
3165 l = aopGet(AOP(right),0,FALSE,FALSE);
3167 lbl = newiTempLabel(NULL);
3168 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3169 pic14_emitcode("cpl","a");
3170 pic14_emitcode("inc","a");
3171 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3172 pic14_emitcode("mov","b,a");
3174 /* sign adjust left side */
3175 l = aopGet(AOP(left),0,FALSE,FALSE);
3178 lbl = newiTempLabel(NULL);
3179 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3180 pic14_emitcode("cpl","a");
3181 pic14_emitcode("inc","a");
3182 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3184 /* now the division */
3185 pic14_emitcode("div","ab");
3186 /* we are interested in the lower order
3188 pic14_emitcode("mov","b,a");
3189 lbl = newiTempLabel(NULL);
3190 pic14_emitcode("pop","acc");
3191 /* if there was an over flow we don't
3192 adjust the sign of the result */
3193 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3194 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3196 pic14_emitcode("clr","a");
3197 pic14_emitcode("subb","a,b");
3198 pic14_emitcode("mov","b,a");
3199 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3201 /* now we are done */
3202 aopPut(AOP(result),"b",0);
3204 pic14_emitcode("mov","c,b.7");
3205 pic14_emitcode("subb","a,acc");
3208 aopPut(AOP(result),"a",offset++);
3212 /*-----------------------------------------------------------------*/
3213 /* genDiv - generates code for division */
3214 /*-----------------------------------------------------------------*/
3215 static void genDiv (iCode *ic)
3217 operand *left = IC_LEFT(ic);
3218 operand *right = IC_RIGHT(ic);
3219 operand *result= IC_RESULT(ic);
3221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3222 /* assign the amsops */
3223 aopOp (left,ic,FALSE);
3224 aopOp (right,ic,FALSE);
3225 aopOp (result,ic,TRUE);
3227 /* special cases first */
3229 if (AOP_TYPE(left) == AOP_CRY &&
3230 AOP_TYPE(right)== AOP_CRY) {
3231 genDivbits(left,right,result);
3235 /* if both are of size == 1 */
3236 if (AOP_SIZE(left) == 1 &&
3237 AOP_SIZE(right) == 1 ) {
3238 genDivOneByte(left,right,result);
3242 /* should have been converted to function call */
3245 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3246 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247 freeAsmop(result,NULL,ic,TRUE);
3250 /*-----------------------------------------------------------------*/
3251 /* genModbits :- modulus of bits */
3252 /*-----------------------------------------------------------------*/
3253 static void genModbits (operand *left,
3260 /* the result must be bit */
3261 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3262 l = aopGet(AOP(left),0,FALSE,FALSE);
3266 pic14_emitcode("div","ab");
3267 pic14_emitcode("mov","a,b");
3268 pic14_emitcode("rrc","a");
3269 aopPut(AOP(result),"c",0);
3272 /*-----------------------------------------------------------------*/
3273 /* genModOneByte : 8 bit modulus */
3274 /*-----------------------------------------------------------------*/
3275 static void genModOneByte (operand *left,
3279 sym_link *opetype = operandType(result);
3283 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3284 /* signed or unsigned */
3285 if (SPEC_USIGN(opetype)) {
3286 /* unsigned is easy */
3287 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3288 l = aopGet(AOP(left),0,FALSE,FALSE);
3290 pic14_emitcode("div","ab");
3291 aopPut(AOP(result),"b",0);
3295 /* signed is a little bit more difficult */
3297 /* save the signs of the operands */
3298 l = aopGet(AOP(left),0,FALSE,FALSE);
3301 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3302 pic14_emitcode("push","acc"); /* save it on the stack */
3304 /* now sign adjust for both left & right */
3305 l = aopGet(AOP(right),0,FALSE,FALSE);
3308 lbl = newiTempLabel(NULL);
3309 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3310 pic14_emitcode("cpl","a");
3311 pic14_emitcode("inc","a");
3312 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3313 pic14_emitcode("mov","b,a");
3315 /* sign adjust left side */
3316 l = aopGet(AOP(left),0,FALSE,FALSE);
3319 lbl = newiTempLabel(NULL);
3320 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3321 pic14_emitcode("cpl","a");
3322 pic14_emitcode("inc","a");
3323 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3325 /* now the multiplication */
3326 pic14_emitcode("div","ab");
3327 /* we are interested in the lower order
3329 lbl = newiTempLabel(NULL);
3330 pic14_emitcode("pop","acc");
3331 /* if there was an over flow we don't
3332 adjust the sign of the result */
3333 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3334 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3336 pic14_emitcode("clr","a");
3337 pic14_emitcode("subb","a,b");
3338 pic14_emitcode("mov","b,a");
3339 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3341 /* now we are done */
3342 aopPut(AOP(result),"b",0);
3346 /*-----------------------------------------------------------------*/
3347 /* genMod - generates code for division */
3348 /*-----------------------------------------------------------------*/
3349 static void genMod (iCode *ic)
3351 operand *left = IC_LEFT(ic);
3352 operand *right = IC_RIGHT(ic);
3353 operand *result= IC_RESULT(ic);
3355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3356 /* assign the amsops */
3357 aopOp (left,ic,FALSE);
3358 aopOp (right,ic,FALSE);
3359 aopOp (result,ic,TRUE);
3361 /* special cases first */
3363 if (AOP_TYPE(left) == AOP_CRY &&
3364 AOP_TYPE(right)== AOP_CRY) {
3365 genModbits(left,right,result);
3369 /* if both are of size == 1 */
3370 if (AOP_SIZE(left) == 1 &&
3371 AOP_SIZE(right) == 1 ) {
3372 genModOneByte(left,right,result);
3376 /* should have been converted to function call */
3380 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3381 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3382 freeAsmop(result,NULL,ic,TRUE);
3385 /*-----------------------------------------------------------------*/
3386 /* genIfxJump :- will create a jump depending on the ifx */
3387 /*-----------------------------------------------------------------*/
3389 note: May need to add parameter to indicate when a variable is in bit space.
3391 static void genIfxJump (iCode *ic, char *jval)
3394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3395 /* if true label then we jump if condition
3397 if ( IC_TRUE(ic) ) {
3399 if(strcmp(jval,"a") == 0)
3401 else if (strcmp(jval,"c") == 0)
3404 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3405 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3408 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3409 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3413 /* false label is present */
3414 if(strcmp(jval,"a") == 0)
3416 else if (strcmp(jval,"c") == 0)
3419 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3420 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3423 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3424 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3429 /* mark the icode as generated */
3433 /*-----------------------------------------------------------------*/
3435 /*-----------------------------------------------------------------*/
3436 static void genSkip(iCode *ifx,int status_bit)
3441 if ( IC_TRUE(ifx) ) {
3442 switch(status_bit) {
3457 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3458 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3462 switch(status_bit) {
3476 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3477 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3483 /*-----------------------------------------------------------------*/
3485 /*-----------------------------------------------------------------*/
3486 static void genSkipc(resolvedIfx *rifx)
3496 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3497 rifx->generated = 1;
3500 /*-----------------------------------------------------------------*/
3502 /*-----------------------------------------------------------------*/
3503 static void genSkipz(iCode *ifx, int condition)
3514 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3516 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3519 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3521 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3524 /*-----------------------------------------------------------------*/
3525 /* genCmp :- greater or less than comparison */
3526 /*-----------------------------------------------------------------*/
3527 static void genCmp (operand *left,operand *right,
3528 operand *result, iCode *ifx, int sign)
3530 int size, offset = 0 ;
3531 unsigned long lit = 0L,i = 0;
3534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3536 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3537 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3540 resolveIfx(&rIfx,ifx);
3542 /* if left & right are bit variables */
3543 if (AOP_TYPE(left) == AOP_CRY &&
3544 AOP_TYPE(right) == AOP_CRY ) {
3545 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3546 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3548 /* subtract right from left if at the
3549 end the carry flag is set then we know that
3550 left is greater than right */
3551 size = max(AOP_SIZE(left),AOP_SIZE(right));
3553 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3554 if((size == 1) && !sign &&
3555 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3556 symbol *lbl = newiTempLabel(NULL);
3557 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3558 aopGet(AOP(left),offset,FALSE,FALSE),
3559 aopGet(AOP(right),offset,FALSE,FALSE),
3561 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3564 if(AOP_TYPE(right) == AOP_LIT) {
3565 symbol *lbl = newiTempLabel(NULL);
3567 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3569 DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3572 i = (lit >> (size*8)) & 0xff;
3575 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3577 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3579 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3582 emitpcode(POC_MOVLW, popGetLit(i));
3583 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3585 i = (lit >> (size*8)) & 0xff;
3586 emitpcode(POC_MOVLW, popGetLit(i));
3588 emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3593 //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3596 emitpLabel(lbl->key);
3603 if(AOP_TYPE(left) == AOP_LIT) {
3604 //symbol *lbl = newiTempLabel(NULL);
3606 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3608 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3613 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3615 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3618 if(IC_TRUE(ifx) != NULL)
3619 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3621 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3624 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3625 emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3626 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3627 rIfx.condition ^= 1;
3628 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3632 i = (lit >> (size*8)) & 0xff;
3636 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3638 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3641 if(IC_TRUE(ifx) != NULL)
3642 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3644 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3648 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3649 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3651 i = (lit >> (size*8)) & 0xff;
3652 emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3654 emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3657 genSkipc(&rIfx);// if(ifx) genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3662 emitpLabel(lbl->key);
3664 if(ifx) ifx->generated = 1;
3670 DEBUGpic14_emitcode(";sign","%d",sign);
3672 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3673 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3675 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3676 emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3681 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3683 emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3684 emitpcode(POC_SUBFW, popGet(AOP(left),offset,FALSE,FALSE));
3687 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3689 pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3690 pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3698 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3699 pic14_outBitC(result);
3701 /* if the result is used in the next
3702 ifx conditional branch then generate
3703 code a little differently */
3705 genIfxJump (ifx,"c");
3707 pic14_outBitC(result);
3708 /* leave the result in acc */
3713 /*-----------------------------------------------------------------*/
3714 /* genCmpGt :- greater than comparison */
3715 /*-----------------------------------------------------------------*/
3716 static void genCmpGt (iCode *ic, iCode *ifx)
3718 operand *left, *right, *result;
3719 sym_link *letype , *retype;
3722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3724 right= IC_RIGHT(ic);
3725 result = IC_RESULT(ic);
3727 letype = getSpec(operandType(left));
3728 retype =getSpec(operandType(right));
3729 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3730 /* assign the amsops */
3731 aopOp (left,ic,FALSE);
3732 aopOp (right,ic,FALSE);
3733 aopOp (result,ic,TRUE);
3735 genCmp(right, left, result, ifx, sign);
3737 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3738 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3739 freeAsmop(result,NULL,ic,TRUE);
3742 /*-----------------------------------------------------------------*/
3743 /* genCmpLt - less than comparisons */
3744 /*-----------------------------------------------------------------*/
3745 static void genCmpLt (iCode *ic, iCode *ifx)
3747 operand *left, *right, *result;
3748 sym_link *letype , *retype;
3751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3753 right= IC_RIGHT(ic);
3754 result = IC_RESULT(ic);
3756 letype = getSpec(operandType(left));
3757 retype =getSpec(operandType(right));
3758 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3760 /* assign the amsops */
3761 aopOp (left,ic,FALSE);
3762 aopOp (right,ic,FALSE);
3763 aopOp (result,ic,TRUE);
3765 genCmp(left, right, result, ifx, sign);
3767 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3768 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3769 freeAsmop(result,NULL,ic,TRUE);
3772 /*-----------------------------------------------------------------*/
3773 /* genc16bit2lit - compare a 16 bit value to a literal */
3774 /*-----------------------------------------------------------------*/
3775 static void genc16bit2lit(operand *op, int lit, int offset)
3779 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
3780 if( (lit&0xff) == 0)
3785 switch( BYTEofLONG(lit,i)) {
3787 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3790 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3793 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3796 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3797 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3802 switch( BYTEofLONG(lit,i)) {
3804 emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3808 emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3812 emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3815 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3817 emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3823 /*-----------------------------------------------------------------*/
3824 /* gencjneshort - compare and jump if not equal */
3825 /*-----------------------------------------------------------------*/
3826 static void gencjne(operand *left, operand *right, iCode *ifx)
3828 int size = max(AOP_SIZE(left),AOP_SIZE(right));
3833 unsigned long lit = 0L;
3834 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3835 DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3836 AopType(AOP_TYPE(left)),
3837 aopGet(AOP(left),0,TRUE,FALSE),
3838 AopType(AOP_TYPE(right)),
3839 aopGet(AOP(right),0,FALSE,FALSE),
3842 resolveIfx(&rIfx,ifx);
3843 lbl = newiTempLabel(NULL);
3846 /* if the left side is a literal or
3847 if the right is in a pointer register and left
3849 if ((AOP_TYPE(left) == AOP_LIT) ||
3850 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3855 if(AOP_TYPE(right) == AOP_LIT)
3856 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3858 /* if the right side is a literal then anything goes */
3859 if (AOP_TYPE(right) == AOP_LIT &&
3860 AOP_TYPE(left) != AOP_DIR ) {
3863 genc16bit2lit(left, lit, 0);
3865 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3866 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3871 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3872 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3873 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3874 pic14_emitcode("xorlw","0x%x",lit & 0xff);
3876 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3877 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3881 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3882 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3890 /* if the right side is in a register or in direct space or
3891 if the left is a pointer register & right is not */
3892 else if (AOP_TYPE(right) == AOP_REG ||
3893 AOP_TYPE(right) == AOP_DIR ||
3894 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3895 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3898 genc16bit2lit(left, lit, 0);
3900 pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3901 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3906 if((AOP_TYPE(left) == AOP_DIR) &&
3907 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3909 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3910 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3912 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3914 switch (lit & 0xff) {
3916 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3919 emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3920 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3924 emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3925 emitpcode(POC_GOTO,popGetLabel(lbl->key));
3929 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3930 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3935 emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3936 pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3939 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3944 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3953 } else if(AOP_TYPE(right) == AOP_REG &&
3954 AOP_TYPE(left) != AOP_DIR){
3957 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3958 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3959 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
3964 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3969 /* right is a pointer reg need both a & b */
3971 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3973 pic14_emitcode("mov","b,%s",l);
3974 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3975 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
3979 emitpLabel(lbl->key);
3986 /*-----------------------------------------------------------------*/
3987 /* gencjne - compare and jump if not equal */
3988 /*-----------------------------------------------------------------*/
3989 static void gencjne(operand *left, operand *right, iCode *ifx)
3991 symbol *tlbl = newiTempLabel(NULL);
3993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3994 gencjneshort(left, right, lbl);
3996 pic14_emitcode("mov","a,%s",one);
3997 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3998 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3999 pic14_emitcode("clr","a");
4000 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4002 emitpLabel(lbl->key);
4003 emitpLabel(tlbl->key);
4008 /*-----------------------------------------------------------------*/
4009 /* genCmpEq - generates code for equal to */
4010 /*-----------------------------------------------------------------*/
4011 static void genCmpEq (iCode *ic, iCode *ifx)
4013 operand *left, *right, *result;
4014 unsigned long lit = 0L;
4017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4020 DEBUGpic14_emitcode ("; ifx is non-null","");
4022 DEBUGpic14_emitcode ("; ifx is null","");
4024 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4025 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4026 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4029 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4030 AopType(AOP_TYPE(IC_RESULT(ic))),
4031 AopType(AOP_TYPE(IC_LEFT(ic))),
4032 AopType(AOP_TYPE(IC_RIGHT(ic))));
4034 size = max(AOP_SIZE(left),AOP_SIZE(right));
4035 DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4036 AopType(AOP_TYPE(result)),
4037 aopGet(AOP(result),0,TRUE,FALSE),
4038 AopType(AOP_TYPE(left)),
4039 aopGet(AOP(left),0,TRUE,FALSE),
4040 AopType(AOP_TYPE(right)),
4041 aopGet(AOP(right),0,FALSE,FALSE),
4045 /* if literal, literal on the right or
4046 if the right is in a pointer register and left
4048 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4049 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4050 operand *t = IC_RIGHT(ic);
4051 IC_RIGHT(ic) = IC_LEFT(ic);
4055 if(ifx && !AOP_SIZE(result)){
4057 /* if they are both bit variables */
4058 if (AOP_TYPE(left) == AOP_CRY &&
4059 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4060 if(AOP_TYPE(right) == AOP_LIT){
4061 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4063 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4064 pic14_emitcode("cpl","c");
4065 } else if(lit == 1L) {
4066 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4068 pic14_emitcode("clr","c");
4070 /* AOP_TYPE(right) == AOP_CRY */
4072 symbol *lbl = newiTempLabel(NULL);
4073 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4074 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4075 pic14_emitcode("cpl","c");
4076 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4078 /* if true label then we jump if condition
4080 tlbl = newiTempLabel(NULL);
4081 if ( IC_TRUE(ifx) ) {
4082 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4083 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4085 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4086 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4088 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4091 /* They're not both bit variables. Is the right a literal? */
4092 if(AOP_TYPE(right) == AOP_LIT) {
4093 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4099 switch(lit & 0xff) {
4101 if ( IC_TRUE(ifx) ) {
4102 emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4104 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4106 emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4107 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4111 if ( IC_TRUE(ifx) ) {
4112 emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4114 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4116 emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4117 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4121 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4123 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4128 /* end of size == 1 */
4132 genc16bit2lit(left,lit,offset);
4135 /* end of size == 2 */
4140 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4141 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4142 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4143 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4147 /* search for patterns that can be optimized */
4149 genc16bit2lit(left,lit,0);
4152 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4154 genc16bit2lit(left,lit,2);
4156 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4157 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4170 } else if(AOP_TYPE(right) == AOP_CRY ) {
4171 /* we know the left is not a bit, but that the right is */
4172 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4173 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4174 popGet(AOP(right),offset,FALSE,FALSE));
4175 emitpcode(POC_XORLW,popGetLit(1));
4177 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4179 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4180 AOP(right)->aopu.aop_dir,
4181 AOP(right)->aopu.aop_dir);
4183 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4184 AOP(right)->aopu.aop_dir,
4185 AOP(right)->aopu.aop_dir);
4187 pic14_emitcode("xorlw","1");
4189 /* if the two are equal, then W will be 0 and the Z bit is set
4190 * we could test Z now, or go ahead and check the high order bytes if
4191 * the variable we're comparing is larger than a byte. */
4194 emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4195 //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4197 if ( IC_TRUE(ifx) ) {
4199 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4200 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4203 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4204 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4208 /* They're both variables that are larger than bits */
4211 tlbl = newiTempLabel(NULL);
4214 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4215 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4217 pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4218 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4220 if ( IC_TRUE(ifx) ) {
4223 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4224 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4227 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4228 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4232 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4233 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4237 if(s>1 && IC_TRUE(ifx)) {
4238 emitpLabel(tlbl->key);
4239 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4243 /* mark the icode as generated */
4248 /* if they are both bit variables */
4249 if (AOP_TYPE(left) == AOP_CRY &&
4250 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4251 if(AOP_TYPE(right) == AOP_LIT){
4252 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4254 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4255 pic14_emitcode("cpl","c");
4256 } else if(lit == 1L) {
4257 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4259 pic14_emitcode("clr","c");
4261 /* AOP_TYPE(right) == AOP_CRY */
4263 symbol *lbl = newiTempLabel(NULL);
4264 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4265 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4266 pic14_emitcode("cpl","c");
4267 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4270 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4271 pic14_outBitC(result);
4275 genIfxJump (ifx,"c");
4278 /* if the result is used in an arithmetic operation
4279 then put the result in place */
4280 pic14_outBitC(result);
4283 gencjne(left,right,ifx);
4286 gencjne(left,right,newiTempLabel(NULL));
4288 if(IC_TRUE(ifx)->key)
4289 gencjne(left,right,IC_TRUE(ifx)->key);
4291 gencjne(left,right,IC_FALSE(ifx)->key);
4295 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4296 aopPut(AOP(result),"a",0);
4301 genIfxJump (ifx,"a");
4305 /* if the result is used in an arithmetic operation
4306 then put the result in place */
4307 if (AOP_TYPE(result) != AOP_CRY)
4308 pic14_outAcc(result);
4309 /* leave the result in acc */
4313 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4314 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4315 freeAsmop(result,NULL,ic,TRUE);
4318 /*-----------------------------------------------------------------*/
4319 /* ifxForOp - returns the icode containing the ifx for operand */
4320 /*-----------------------------------------------------------------*/
4321 static iCode *ifxForOp ( operand *op, iCode *ic )
4323 /* if true symbol then needs to be assigned */
4324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4325 if (IS_TRUE_SYMOP(op))
4328 /* if this has register type condition and
4329 the next instruction is ifx with the same operand
4330 and live to of the operand is upto the ifx only then */
4332 ic->next->op == IFX &&
4333 IC_COND(ic->next)->key == op->key &&
4334 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4338 ic->next->op == IFX &&
4339 IC_COND(ic->next)->key == op->key) {
4340 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4344 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4346 ic->next->op == IFX)
4347 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4350 ic->next->op == IFX &&
4351 IC_COND(ic->next)->key == op->key) {
4352 DEBUGpic14_emitcode ("; "," key is okay");
4353 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4354 OP_SYMBOL(op)->liveTo,
4361 /*-----------------------------------------------------------------*/
4362 /* genAndOp - for && operation */
4363 /*-----------------------------------------------------------------*/
4364 static void genAndOp (iCode *ic)
4366 operand *left,*right, *result;
4369 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4370 /* note here that && operations that are in an
4371 if statement are taken away by backPatchLabels
4372 only those used in arthmetic operations remain */
4373 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4374 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4375 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4377 /* if both are bit variables */
4378 if (AOP_TYPE(left) == AOP_CRY &&
4379 AOP_TYPE(right) == AOP_CRY ) {
4380 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4381 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4382 pic14_outBitC(result);
4384 tlbl = newiTempLabel(NULL);
4385 pic14_toBoolean(left);
4386 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4387 pic14_toBoolean(right);
4388 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4389 pic14_outBitAcc(result);
4392 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4394 freeAsmop(result,NULL,ic,TRUE);
4398 /*-----------------------------------------------------------------*/
4399 /* genOrOp - for || operation */
4400 /*-----------------------------------------------------------------*/
4403 modified this code, but it doesn't appear to ever get called
4406 static void genOrOp (iCode *ic)
4408 operand *left,*right, *result;
4411 /* note here that || operations that are in an
4412 if statement are taken away by backPatchLabels
4413 only those used in arthmetic operations remain */
4414 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4415 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4416 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4417 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4419 /* if both are bit variables */
4420 if (AOP_TYPE(left) == AOP_CRY &&
4421 AOP_TYPE(right) == AOP_CRY ) {
4422 pic14_emitcode("clrc","");
4423 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4424 AOP(left)->aopu.aop_dir,
4425 AOP(left)->aopu.aop_dir);
4426 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4427 AOP(right)->aopu.aop_dir,
4428 AOP(right)->aopu.aop_dir);
4429 pic14_emitcode("setc","");
4432 tlbl = newiTempLabel(NULL);
4433 pic14_toBoolean(left);
4435 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4436 pic14_toBoolean(right);
4437 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4439 pic14_outBitAcc(result);
4442 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4443 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4444 freeAsmop(result,NULL,ic,TRUE);
4447 /*-----------------------------------------------------------------*/
4448 /* isLiteralBit - test if lit == 2^n */
4449 /*-----------------------------------------------------------------*/
4450 static int isLiteralBit(unsigned long lit)
4452 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4453 0x100L,0x200L,0x400L,0x800L,
4454 0x1000L,0x2000L,0x4000L,0x8000L,
4455 0x10000L,0x20000L,0x40000L,0x80000L,
4456 0x100000L,0x200000L,0x400000L,0x800000L,
4457 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4458 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4462 for(idx = 0; idx < 32; idx++)
4468 /*-----------------------------------------------------------------*/
4469 /* continueIfTrue - */
4470 /*-----------------------------------------------------------------*/
4471 static void continueIfTrue (iCode *ic)
4473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4475 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4479 /*-----------------------------------------------------------------*/
4481 /*-----------------------------------------------------------------*/
4482 static void jumpIfTrue (iCode *ic)
4484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4486 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4490 /*-----------------------------------------------------------------*/
4491 /* jmpTrueOrFalse - */
4492 /*-----------------------------------------------------------------*/
4493 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4495 // ugly but optimized by peephole
4496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4498 symbol *nlbl = newiTempLabel(NULL);
4499 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4500 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4501 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4502 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4505 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4506 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4511 /*-----------------------------------------------------------------*/
4512 /* genAnd - code for and */
4513 /*-----------------------------------------------------------------*/
4514 static void genAnd (iCode *ic, iCode *ifx)
4516 operand *left, *right, *result;
4518 unsigned long lit = 0L;
4523 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4524 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4525 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4526 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4528 resolveIfx(&rIfx,ifx);
4530 /* if left is a literal & right is not then exchange them */
4531 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4532 AOP_NEEDSACC(left)) {
4533 operand *tmp = right ;
4538 /* if result = right then exchange them */
4539 if(pic14_sameRegs(AOP(result),AOP(right))){
4540 operand *tmp = right ;
4545 /* if right is bit then exchange them */
4546 if (AOP_TYPE(right) == AOP_CRY &&
4547 AOP_TYPE(left) != AOP_CRY){
4548 operand *tmp = right ;
4552 if(AOP_TYPE(right) == AOP_LIT)
4553 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4555 size = AOP_SIZE(result);
4557 DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4558 AopType(AOP_TYPE(result)),
4559 aopGet(AOP(result),0,TRUE,FALSE),
4560 AopType(AOP_TYPE(left)),
4561 aopGet(AOP(left),0,TRUE,FALSE),
4562 AopType(AOP_TYPE(right)),
4563 aopGet(AOP(right),0,FALSE,FALSE),
4566 // result = bit & yy;
4567 if (AOP_TYPE(left) == AOP_CRY){
4568 // c = bit & literal;
4569 if(AOP_TYPE(right) == AOP_LIT){
4571 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4574 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4577 if(size && (AOP_TYPE(result) == AOP_CRY)){
4578 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4581 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4585 pic14_emitcode("clr","c");
4588 if (AOP_TYPE(right) == AOP_CRY){
4590 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4591 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4594 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4596 pic14_emitcode("rrc","a");
4597 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4603 pic14_outBitC(result);
4605 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4606 genIfxJump(ifx, "c");
4610 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4611 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4612 if((AOP_TYPE(right) == AOP_LIT) &&
4613 (AOP_TYPE(result) == AOP_CRY) &&
4614 (AOP_TYPE(left) != AOP_CRY)){
4615 int posbit = isLiteralBit(lit);
4619 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4622 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4628 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4629 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4631 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4632 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4635 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4636 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4637 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4644 symbol *tlbl = newiTempLabel(NULL);
4645 int sizel = AOP_SIZE(left);
4647 pic14_emitcode("setb","c");
4649 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4650 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4652 if((posbit = isLiteralBit(bytelit)) != 0)
4653 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4655 if(bytelit != 0x0FFL)
4656 pic14_emitcode("anl","a,%s",
4657 aopGet(AOP(right),offset,FALSE,TRUE));
4658 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4663 // bit = left & literal
4665 pic14_emitcode("clr","c");
4666 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4668 // if(left & literal)
4671 jmpTrueOrFalse(ifx, tlbl);
4675 pic14_outBitC(result);
4679 /* if left is same as result */
4680 if(pic14_sameRegs(AOP(result),AOP(left))){
4682 for(;size--; offset++,lit>>=8) {
4683 if(AOP_TYPE(right) == AOP_LIT){
4684 switch(lit & 0xff) {
4686 /* and'ing with 0 has clears the result */
4687 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4688 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4691 /* and'ing with 0xff is a nop when the result and left are the same */
4696 int p = my_powof2( (~lit) & 0xff );
4698 /* only one bit is set in the literal, so use a bcf instruction */
4699 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4700 //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4701 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4704 pic14_emitcode("movlw","0x%x", (lit & 0xff));
4705 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4706 if(know_W != (lit&0xff))
4707 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4709 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4714 if (AOP_TYPE(left) == AOP_ACC) {
4715 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4717 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4718 emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4725 // left & result in different registers
4726 if(AOP_TYPE(result) == AOP_CRY){
4728 // if(size), result in bit
4729 // if(!size && ifx), conditional oper: if(left & right)
4730 symbol *tlbl = newiTempLabel(NULL);
4731 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4733 pic14_emitcode("setb","c");
4735 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4736 pic14_emitcode("anl","a,%s",
4737 aopGet(AOP(left),offset,FALSE,FALSE));
4738 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4743 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4744 pic14_outBitC(result);
4746 jmpTrueOrFalse(ifx, tlbl);
4748 for(;(size--);offset++) {
4750 // result = left & right
4751 if(AOP_TYPE(right) == AOP_LIT){
4752 int t = (lit >> (offset*8)) & 0x0FFL;
4755 pic14_emitcode("clrf","%s",
4756 aopGet(AOP(result),offset,FALSE,FALSE));
4757 emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4760 pic14_emitcode("movf","%s,w",
4761 aopGet(AOP(left),offset,FALSE,FALSE));
4762 pic14_emitcode("movwf","%s",
4763 aopGet(AOP(result),offset,FALSE,FALSE));
4764 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4765 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4768 pic14_emitcode("movlw","0x%x",t);
4769 pic14_emitcode("andwf","%s,w",
4770 aopGet(AOP(left),offset,FALSE,FALSE));
4771 pic14_emitcode("movwf","%s",
4772 aopGet(AOP(result),offset,FALSE,FALSE));
4774 emitpcode(POC_MOVLW, popGetLit(t));
4775 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4776 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4781 if (AOP_TYPE(left) == AOP_ACC) {
4782 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4783 emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4785 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4786 pic14_emitcode("andwf","%s,w",
4787 aopGet(AOP(left),offset,FALSE,FALSE));
4788 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4789 emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4791 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4792 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4798 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4799 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4800 freeAsmop(result,NULL,ic,TRUE);
4803 /*-----------------------------------------------------------------*/
4804 /* genOr - code for or */
4805 /*-----------------------------------------------------------------*/
4806 static void genOr (iCode *ic, iCode *ifx)
4808 operand *left, *right, *result;
4810 unsigned long lit = 0L;
4812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4814 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4815 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4816 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4819 /* if left is a literal & right is not then exchange them */
4820 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4821 AOP_NEEDSACC(left)) {
4822 operand *tmp = right ;
4827 /* if result = right then exchange them */
4828 if(pic14_sameRegs(AOP(result),AOP(right))){
4829 operand *tmp = right ;
4834 /* if right is bit then exchange them */
4835 if (AOP_TYPE(right) == AOP_CRY &&
4836 AOP_TYPE(left) != AOP_CRY){
4837 operand *tmp = right ;
4842 DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4843 AopType(AOP_TYPE(result)),
4844 AopType(AOP_TYPE(left)),
4845 AopType(AOP_TYPE(right)));
4847 if(AOP_TYPE(right) == AOP_LIT)
4848 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4850 size = AOP_SIZE(result);
4854 if (AOP_TYPE(left) == AOP_CRY){
4855 if(AOP_TYPE(right) == AOP_LIT){
4856 // c = bit & literal;
4858 // lit != 0 => result = 1
4859 if(AOP_TYPE(result) == AOP_CRY){
4861 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4862 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4863 // AOP(result)->aopu.aop_dir,
4864 // AOP(result)->aopu.aop_dir);
4866 continueIfTrue(ifx);
4870 // lit == 0 => result = left
4871 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4873 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4876 if (AOP_TYPE(right) == AOP_CRY){
4877 if(pic14_sameRegs(AOP(result),AOP(left))){
4879 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4880 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4881 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4883 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4884 AOP(result)->aopu.aop_dir,
4885 AOP(result)->aopu.aop_dir);
4886 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4887 AOP(right)->aopu.aop_dir,
4888 AOP(right)->aopu.aop_dir);
4889 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4890 AOP(result)->aopu.aop_dir,
4891 AOP(result)->aopu.aop_dir);
4893 if( AOP_TYPE(result) == AOP_ACC) {
4894 emitpcode(POC_MOVLW, popGetLit(0));
4895 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4896 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4897 emitpcode(POC_MOVLW, popGetLit(1));
4901 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4902 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4903 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4904 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4906 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4907 AOP(result)->aopu.aop_dir,
4908 AOP(result)->aopu.aop_dir);
4909 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4910 AOP(right)->aopu.aop_dir,
4911 AOP(right)->aopu.aop_dir);
4912 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4913 AOP(left)->aopu.aop_dir,
4914 AOP(left)->aopu.aop_dir);
4915 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4916 AOP(result)->aopu.aop_dir,
4917 AOP(result)->aopu.aop_dir);
4922 symbol *tlbl = newiTempLabel(NULL);
4923 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4926 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
4927 if( AOP_TYPE(right) == AOP_ACC) {
4928 emitpcode(POC_IORLW, popGetLit(0));
4930 emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4931 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4936 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4937 pic14_emitcode(";XXX setb","c");
4938 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4939 AOP(left)->aopu.aop_dir,tlbl->key+100);
4940 pic14_toBoolean(right);
4941 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4942 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4943 jmpTrueOrFalse(ifx, tlbl);
4947 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4954 pic14_outBitC(result);
4956 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4957 genIfxJump(ifx, "c");
4961 // if(val | 0xZZ) - size = 0, ifx != FALSE -
4962 // bit = val | 0xZZ - size = 1, ifx = FALSE -
4963 if((AOP_TYPE(right) == AOP_LIT) &&
4964 (AOP_TYPE(result) == AOP_CRY) &&
4965 (AOP_TYPE(left) != AOP_CRY)){
4967 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4970 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4972 continueIfTrue(ifx);
4975 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4976 // lit = 0, result = boolean(left)
4978 pic14_emitcode(";XXX setb","c");
4979 pic14_toBoolean(right);
4981 symbol *tlbl = newiTempLabel(NULL);
4982 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4984 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4986 genIfxJump (ifx,"a");
4990 pic14_outBitC(result);
4994 /* if left is same as result */
4995 if(pic14_sameRegs(AOP(result),AOP(left))){
4997 for(;size--; offset++,lit>>=8) {
4998 if(AOP_TYPE(right) == AOP_LIT){
4999 if((lit & 0xff) == 0)
5000 /* or'ing with 0 has no effect */
5003 int p = my_powof2(lit & 0xff);
5005 /* only one bit is set in the literal, so use a bsf instruction */
5007 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5009 if(know_W != (lit & 0xff))
5010 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5011 know_W = lit & 0xff;
5012 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
5017 if (AOP_TYPE(left) == AOP_ACC) {
5018 emitpcode(POC_IORFW, popGet(AOP(right),offset,FALSE,FALSE));
5019 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5021 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5022 emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
5024 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5025 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5031 // left & result in different registers
5032 if(AOP_TYPE(result) == AOP_CRY){
5034 // if(size), result in bit
5035 // if(!size && ifx), conditional oper: if(left | right)
5036 symbol *tlbl = newiTempLabel(NULL);
5037 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5038 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5042 pic14_emitcode(";XXX setb","c");
5044 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5045 pic14_emitcode(";XXX orl","a,%s",
5046 aopGet(AOP(left),offset,FALSE,FALSE));
5047 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5052 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5053 pic14_outBitC(result);
5055 jmpTrueOrFalse(ifx, tlbl);
5056 } else for(;(size--);offset++){
5058 // result = left & right
5059 if(AOP_TYPE(right) == AOP_LIT){
5060 int t = (lit >> (offset*8)) & 0x0FFL;
5063 emitpcode(POC_MOVFW, popGet(AOP(left),offset,FALSE,FALSE));
5064 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5066 pic14_emitcode("movf","%s,w",
5067 aopGet(AOP(left),offset,FALSE,FALSE));
5068 pic14_emitcode("movwf","%s",
5069 aopGet(AOP(result),offset,FALSE,FALSE));
5072 emitpcode(POC_MOVLW, popGetLit(t));
5073 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5074 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5076 pic14_emitcode("movlw","0x%x",t);
5077 pic14_emitcode("iorwf","%s,w",
5078 aopGet(AOP(left),offset,FALSE,FALSE));
5079 pic14_emitcode("movwf","%s",
5080 aopGet(AOP(result),offset,FALSE,FALSE));
5086 // faster than result <- left, anl result,right
5087 // and better if result is SFR
5088 if (AOP_TYPE(left) == AOP_ACC) {
5089 emitpcode(POC_IORWF, popGet(AOP(right),offset,FALSE,FALSE));
5090 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5092 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
5093 emitpcode(POC_IORFW, popGet(AOP(left),offset,FALSE,FALSE));
5095 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5096 pic14_emitcode("iorwf","%s,w",
5097 aopGet(AOP(left),offset,FALSE,FALSE));
5099 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
5100 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5105 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5106 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5107 freeAsmop(result,NULL,ic,TRUE);
5110 /*-----------------------------------------------------------------*/
5111 /* genXor - code for xclusive or */
5112 /*-----------------------------------------------------------------*/
5113 static void genXor (iCode *ic, iCode *ifx)
5115 operand *left, *right, *result;
5117 unsigned long lit = 0L;
5119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5121 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5122 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5123 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5125 /* if left is a literal & right is not ||
5126 if left needs acc & right does not */
5127 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5128 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5129 operand *tmp = right ;
5134 /* if result = right then exchange them */
5135 if(pic14_sameRegs(AOP(result),AOP(right))){
5136 operand *tmp = right ;
5141 /* if right is bit then exchange them */
5142 if (AOP_TYPE(right) == AOP_CRY &&
5143 AOP_TYPE(left) != AOP_CRY){
5144 operand *tmp = right ;
5148 if(AOP_TYPE(right) == AOP_LIT)
5149 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5151 size = AOP_SIZE(result);
5155 if (AOP_TYPE(left) == AOP_CRY){
5156 if(AOP_TYPE(right) == AOP_LIT){
5157 // c = bit & literal;
5159 // lit>>1 != 0 => result = 1
5160 if(AOP_TYPE(result) == AOP_CRY){
5162 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5164 continueIfTrue(ifx);
5167 pic14_emitcode("setb","c");
5171 // lit == 0, result = left
5172 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5174 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5176 // lit == 1, result = not(left)
5177 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5178 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5181 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5182 pic14_emitcode("cpl","c");
5189 symbol *tlbl = newiTempLabel(NULL);
5190 if (AOP_TYPE(right) == AOP_CRY){
5192 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5195 int sizer = AOP_SIZE(right);
5197 // if val>>1 != 0, result = 1
5198 pic14_emitcode("setb","c");
5200 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5202 // test the msb of the lsb
5203 pic14_emitcode("anl","a,#0xfe");
5204 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5208 pic14_emitcode("rrc","a");
5210 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5211 pic14_emitcode("cpl","c");
5212 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5217 pic14_outBitC(result);
5219 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5220 genIfxJump(ifx, "c");
5224 if(pic14_sameRegs(AOP(result),AOP(left))){
5225 /* if left is same as result */
5226 for(;size--; offset++) {
5227 if(AOP_TYPE(right) == AOP_LIT){
5228 int t = (lit >> (offset*8)) & 0x0FFL;
5232 if (IS_AOP_PREG(left)) {
5233 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5234 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5235 aopPut(AOP(result),"a",offset);
5237 emitpcode(POC_MOVLW, popGetLit(t));
5238 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5239 pic14_emitcode("xrl","%s,%s",
5240 aopGet(AOP(left),offset,FALSE,TRUE),
5241 aopGet(AOP(right),offset,FALSE,FALSE));
5244 if (AOP_TYPE(left) == AOP_ACC)
5245 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5247 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5248 emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5250 if (IS_AOP_PREG(left)) {
5251 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5252 aopPut(AOP(result),"a",offset);
5254 pic14_emitcode("xrl","%s,a",
5255 aopGet(AOP(left),offset,FALSE,TRUE));
5261 // left & result in different registers
5262 if(AOP_TYPE(result) == AOP_CRY){
5264 // if(size), result in bit
5265 // if(!size && ifx), conditional oper: if(left ^ right)
5266 symbol *tlbl = newiTempLabel(NULL);
5267 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5269 pic14_emitcode("setb","c");
5271 if((AOP_TYPE(right) == AOP_LIT) &&
5272 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5273 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5275 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5276 pic14_emitcode("xrl","a,%s",
5277 aopGet(AOP(left),offset,FALSE,FALSE));
5279 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5284 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5285 pic14_outBitC(result);
5287 jmpTrueOrFalse(ifx, tlbl);
5288 } else for(;(size--);offset++){
5290 // result = left & right
5291 if(AOP_TYPE(right) == AOP_LIT){
5292 int t = (lit >> (offset*8)) & 0x0FFL;
5295 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5296 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5297 pic14_emitcode("movf","%s,w",
5298 aopGet(AOP(left),offset,FALSE,FALSE));
5299 pic14_emitcode("movwf","%s",
5300 aopGet(AOP(result),offset,FALSE,FALSE));
5303 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5304 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5305 pic14_emitcode("comf","%s,w",
5306 aopGet(AOP(left),offset,FALSE,FALSE));
5307 pic14_emitcode("movwf","%s",
5308 aopGet(AOP(result),offset,FALSE,FALSE));
5311 emitpcode(POC_MOVLW, popGetLit(t));
5312 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5313 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5314 pic14_emitcode("movlw","0x%x",t);
5315 pic14_emitcode("xorwf","%s,w",
5316 aopGet(AOP(left),offset,FALSE,FALSE));
5317 pic14_emitcode("movwf","%s",
5318 aopGet(AOP(result),offset,FALSE,FALSE));
5324 // faster than result <- left, anl result,right
5325 // and better if result is SFR
5326 if (AOP_TYPE(left) == AOP_ACC) {
5327 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5328 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5330 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5331 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5332 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5333 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5335 if ( AOP_TYPE(result) != AOP_ACC){
5336 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5337 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5343 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5344 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5345 freeAsmop(result,NULL,ic,TRUE);
5348 /*-----------------------------------------------------------------*/
5349 /* genInline - write the inline code out */
5350 /*-----------------------------------------------------------------*/
5351 static void genInline (iCode *ic)
5353 char *buffer, *bp, *bp1;
5355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5357 _G.inLine += (!options.asmpeep);
5359 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5360 strcpy(buffer,IC_INLINE(ic));
5362 /* emit each line as a code */
5366 pic14_emitcode(bp1,"");
5373 pic14_emitcode(bp1,"");
5380 pic14_emitcode(bp1,"");
5381 /* pic14_emitcode("",buffer); */
5382 _G.inLine -= (!options.asmpeep);
5385 /*-----------------------------------------------------------------*/
5386 /* genRRC - rotate right with carry */
5387 /*-----------------------------------------------------------------*/
5388 static void genRRC (iCode *ic)
5390 operand *left , *result ;
5391 int size, offset = 0;
5394 /* rotate right with carry */
5396 result=IC_RESULT(ic);
5397 aopOp (left,ic,FALSE);
5398 aopOp (result,ic,FALSE);
5400 /* move it to the result */
5401 size = AOP_SIZE(result);
5405 l = aopGet(AOP(left),offset,FALSE,FALSE);
5407 pic14_emitcode("rrc","a");
5408 if (AOP_SIZE(result) > 1)
5409 aopPut(AOP(result),"a",offset--);
5411 /* now we need to put the carry into the
5412 highest order byte of the result */
5413 if (AOP_SIZE(result) > 1) {
5414 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5417 pic14_emitcode("mov","acc.7,c");
5418 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5419 freeAsmop(left,NULL,ic,TRUE);
5420 freeAsmop(result,NULL,ic,TRUE);
5423 /*-----------------------------------------------------------------*/
5424 /* genRLC - generate code for rotate left with carry */
5425 /*-----------------------------------------------------------------*/
5426 static void genRLC (iCode *ic)
5428 operand *left , *result ;
5429 int size, offset = 0;
5432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5433 /* rotate right with carry */
5435 result=IC_RESULT(ic);
5436 aopOp (left,ic,FALSE);
5437 aopOp (result,ic,FALSE);
5439 /* move it to the result */
5440 size = AOP_SIZE(result);
5443 l = aopGet(AOP(left),offset,FALSE,FALSE);
5445 pic14_emitcode("add","a,acc");
5446 if (AOP_SIZE(result) > 1)
5447 aopPut(AOP(result),"a",offset++);
5449 l = aopGet(AOP(left),offset,FALSE,FALSE);
5451 pic14_emitcode("rlc","a");
5452 if (AOP_SIZE(result) > 1)
5453 aopPut(AOP(result),"a",offset++);
5456 /* now we need to put the carry into the
5457 highest order byte of the result */
5458 if (AOP_SIZE(result) > 1) {
5459 l = aopGet(AOP(result),0,FALSE,FALSE);
5462 pic14_emitcode("mov","acc.0,c");
5463 aopPut(AOP(result),"a",0);
5464 freeAsmop(left,NULL,ic,TRUE);
5465 freeAsmop(result,NULL,ic,TRUE);
5468 /*-----------------------------------------------------------------*/
5469 /* genGetHbit - generates code get highest order bit */
5470 /*-----------------------------------------------------------------*/
5471 static void genGetHbit (iCode *ic)
5473 operand *left, *result;
5475 result=IC_RESULT(ic);
5476 aopOp (left,ic,FALSE);
5477 aopOp (result,ic,FALSE);
5479 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5480 /* get the highest order byte into a */
5481 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5482 if(AOP_TYPE(result) == AOP_CRY){
5483 pic14_emitcode("rlc","a");
5484 pic14_outBitC(result);
5487 pic14_emitcode("rl","a");
5488 pic14_emitcode("anl","a,#0x01");
5489 pic14_outAcc(result);
5493 freeAsmop(left,NULL,ic,TRUE);
5494 freeAsmop(result,NULL,ic,TRUE);
5497 /*-----------------------------------------------------------------*/
5498 /* AccRol - rotate left accumulator by known count */
5499 /*-----------------------------------------------------------------*/
5500 static void AccRol (int shCount)
5502 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5503 shCount &= 0x0007; // shCount : 0..7
5508 pic14_emitcode("rl","a");
5511 pic14_emitcode("rl","a");
5512 pic14_emitcode("rl","a");
5515 pic14_emitcode("swap","a");
5516 pic14_emitcode("rr","a");
5519 pic14_emitcode("swap","a");
5522 pic14_emitcode("swap","a");
5523 pic14_emitcode("rl","a");
5526 pic14_emitcode("rr","a");
5527 pic14_emitcode("rr","a");
5530 pic14_emitcode("rr","a");
5535 /*-----------------------------------------------------------------*/
5536 /* AccLsh - left shift accumulator by known count */
5537 /*-----------------------------------------------------------------*/
5538 static void AccLsh (int shCount)
5540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5543 pic14_emitcode("add","a,acc");
5546 pic14_emitcode("add","a,acc");
5547 pic14_emitcode("add","a,acc");
5549 /* rotate left accumulator */
5551 /* and kill the lower order bits */
5552 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5557 /*-----------------------------------------------------------------*/
5558 /* AccRsh - right shift accumulator by known count */
5559 /*-----------------------------------------------------------------*/
5560 static void AccRsh (int shCount)
5562 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5566 pic14_emitcode("rrc","a");
5568 /* rotate right accumulator */
5569 AccRol(8 - shCount);
5570 /* and kill the higher order bits */
5571 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5577 /*-----------------------------------------------------------------*/
5578 /* AccSRsh - signed right shift accumulator by known count */
5579 /*-----------------------------------------------------------------*/
5580 static void AccSRsh (int shCount)
5583 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5586 pic14_emitcode("mov","c,acc.7");
5587 pic14_emitcode("rrc","a");
5588 } else if(shCount == 2){
5589 pic14_emitcode("mov","c,acc.7");
5590 pic14_emitcode("rrc","a");
5591 pic14_emitcode("mov","c,acc.7");
5592 pic14_emitcode("rrc","a");
5594 tlbl = newiTempLabel(NULL);
5595 /* rotate right accumulator */
5596 AccRol(8 - shCount);
5597 /* and kill the higher order bits */
5598 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5599 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5600 pic14_emitcode("orl","a,#0x%02x",
5601 (unsigned char)~SRMask[shCount]);
5602 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5607 /*-----------------------------------------------------------------*/
5608 /* shiftR1Left2Result - shift right one byte from left to result */
5609 /*-----------------------------------------------------------------*/
5610 static void shiftR1Left2ResultSigned (operand *left, int offl,
5611 operand *result, int offr,
5616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5618 same = (left == result) || (AOP(left) == AOP(result));
5622 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5624 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5626 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5627 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5637 /*-----------------------------------------------------------------*/
5638 /* shiftR1Left2Result - shift right one byte from left to result */
5639 /*-----------------------------------------------------------------*/
5640 static void shiftR1Left2Result (operand *left, int offl,
5641 operand *result, int offr,
5642 int shCount, int sign)
5646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5648 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5650 /* Copy the msb into the carry if signed. */
5652 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5662 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5664 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5665 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5671 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5673 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5674 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5677 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5682 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5684 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5685 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5688 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5689 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5690 emitpcode(POC_ANDLW, popGetLit(0x1f));
5691 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5695 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5696 emitpcode(POC_ANDLW, popGetLit(0x0f));
5697 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5701 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5702 emitpcode(POC_ANDLW, popGetLit(0x0f));
5703 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5705 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5710 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5711 emitpcode(POC_ANDLW, popGetLit(0x80));
5712 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5713 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5714 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5719 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5720 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5721 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5732 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5734 /* shift right accumulator */
5739 aopPut(AOP(result),"a",offr);
5743 /*-----------------------------------------------------------------*/
5744 /* shiftL1Left2Result - shift left one byte from left to result */
5745 /*-----------------------------------------------------------------*/
5746 static void shiftL1Left2Result (operand *left, int offl,
5747 operand *result, int offr, int shCount)
5752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5754 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5755 DEBUGpic14_emitcode ("; ***","same = %d",same);
5756 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5758 /* shift left accumulator */
5759 //AccLsh(shCount); // don't comment out just yet...
5760 // aopPut(AOP(result),"a",offr);
5764 /* Shift left 1 bit position */
5765 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5767 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5769 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5770 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5774 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5775 emitpcode(POC_ANDLW,popGetLit(0x7e));
5776 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5777 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5780 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5781 emitpcode(POC_ANDLW,popGetLit(0x3e));
5782 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5783 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5784 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5787 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5788 emitpcode(POC_ANDLW, popGetLit(0xf0));
5789 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5792 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5793 emitpcode(POC_ANDLW, popGetLit(0xf0));
5794 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5795 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5798 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5799 emitpcode(POC_ANDLW, popGetLit(0x30));
5800 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5801 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5802 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5805 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5806 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5807 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5811 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5816 /*-----------------------------------------------------------------*/
5817 /* movLeft2Result - move byte from left to result */
5818 /*-----------------------------------------------------------------*/
5819 static void movLeft2Result (operand *left, int offl,
5820 operand *result, int offr, int sign)
5823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5824 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5825 l = aopGet(AOP(left),offl,FALSE,FALSE);
5827 if (*l == '@' && (IS_AOP_PREG(result))) {
5828 pic14_emitcode("mov","a,%s",l);
5829 aopPut(AOP(result),"a",offr);
5832 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5833 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5835 //aopPut(AOP(result),l,offr);
5837 /* MSB sign in acc.7 ! */
5838 if(pic14_getDataSize(left) == offl+1){
5839 pic14_emitcode("mov","a,%s",l);
5840 aopPut(AOP(result),"a",offr);
5847 /*-----------------------------------------------------------------*/
5848 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5849 /*-----------------------------------------------------------------*/
5850 static void AccAXRrl1 (char *x)
5852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5853 pic14_emitcode("rrc","a");
5854 pic14_emitcode("xch","a,%s", x);
5855 pic14_emitcode("rrc","a");
5856 pic14_emitcode("xch","a,%s", x);
5859 /*-----------------------------------------------------------------*/
5860 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5861 /*-----------------------------------------------------------------*/
5862 static void AccAXLrl1 (char *x)
5864 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5865 pic14_emitcode("xch","a,%s",x);
5866 pic14_emitcode("rlc","a");
5867 pic14_emitcode("xch","a,%s",x);
5868 pic14_emitcode("rlc","a");
5871 /*-----------------------------------------------------------------*/
5872 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5873 /*-----------------------------------------------------------------*/
5874 static void AccAXLsh1 (char *x)
5876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5877 pic14_emitcode("xch","a,%s",x);
5878 pic14_emitcode("add","a,acc");
5879 pic14_emitcode("xch","a,%s",x);
5880 pic14_emitcode("rlc","a");
5884 /*-----------------------------------------------------------------*/
5885 /* AccAXLsh - left shift a:x by known count (0..7) */
5886 /*-----------------------------------------------------------------*/
5887 static void AccAXLsh (char *x, int shCount)
5889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5902 case 5 : // AAAAABBB:CCCCCDDD
5903 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5904 pic14_emitcode("anl","a,#0x%02x",
5905 SLMask[shCount]); // BBB00000:CCCCCDDD
5906 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5907 AccRol(shCount); // DDDCCCCC:BBB00000
5908 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5909 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5910 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5911 pic14_emitcode("anl","a,#0x%02x",
5912 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5913 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5914 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5916 case 6 : // AAAAAABB:CCCCCCDD
5917 pic14_emitcode("anl","a,#0x%02x",
5918 SRMask[shCount]); // 000000BB:CCCCCCDD
5919 pic14_emitcode("mov","c,acc.0"); // c = B
5920 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5921 AccAXRrl1(x); // BCCCCCCD:D000000B
5922 AccAXRrl1(x); // BBCCCCCC:DD000000
5924 case 7 : // a:x <<= 7
5925 pic14_emitcode("anl","a,#0x%02x",
5926 SRMask[shCount]); // 0000000B:CCCCCCCD
5927 pic14_emitcode("mov","c,acc.0"); // c = B
5928 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5929 AccAXRrl1(x); // BCCCCCCC:D0000000
5937 /*-----------------------------------------------------------------*/
5938 /* AccAXRsh - right shift a:x known count (0..7) */
5939 /*-----------------------------------------------------------------*/
5940 static void AccAXRsh (char *x, int shCount)
5942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5948 AccAXRrl1(x); // 0->a:x
5952 AccAXRrl1(x); // 0->a:x
5954 AccAXRrl1(x); // 0->a:x
5958 case 5 : // AAAAABBB:CCCCCDDD = a:x
5959 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5960 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5961 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5962 pic14_emitcode("anl","a,#0x%02x",
5963 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5964 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5965 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5966 pic14_emitcode("anl","a,#0x%02x",
5967 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5968 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5969 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5970 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5972 case 6 : // AABBBBBB:CCDDDDDD
5973 pic14_emitcode("mov","c,acc.7");
5974 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5975 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5976 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5977 pic14_emitcode("anl","a,#0x%02x",
5978 SRMask[shCount]); // 000000AA:BBBBBBCC
5980 case 7 : // ABBBBBBB:CDDDDDDD
5981 pic14_emitcode("mov","c,acc.7"); // c = A
5982 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5983 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5984 pic14_emitcode("anl","a,#0x%02x",
5985 SRMask[shCount]); // 0000000A:BBBBBBBC
5992 /*-----------------------------------------------------------------*/
5993 /* AccAXRshS - right shift signed a:x known count (0..7) */
5994 /*-----------------------------------------------------------------*/
5995 static void AccAXRshS (char *x, int shCount)
5998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6003 pic14_emitcode("mov","c,acc.7");
6004 AccAXRrl1(x); // s->a:x
6007 pic14_emitcode("mov","c,acc.7");
6008 AccAXRrl1(x); // s->a:x
6009 pic14_emitcode("mov","c,acc.7");
6010 AccAXRrl1(x); // s->a:x
6014 case 5 : // AAAAABBB:CCCCCDDD = a:x
6015 tlbl = newiTempLabel(NULL);
6016 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
6017 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
6018 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
6019 pic14_emitcode("anl","a,#0x%02x",
6020 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6021 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
6022 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6023 pic14_emitcode("anl","a,#0x%02x",
6024 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6025 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
6026 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
6027 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
6028 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6029 pic14_emitcode("orl","a,#0x%02x",
6030 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
6031 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6032 break; // SSSSAAAA:BBBCCCCC
6033 case 6 : // AABBBBBB:CCDDDDDD
6034 tlbl = newiTempLabel(NULL);
6035 pic14_emitcode("mov","c,acc.7");
6036 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
6037 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
6038 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
6039 pic14_emitcode("anl","a,#0x%02x",
6040 SRMask[shCount]); // 000000AA:BBBBBBCC
6041 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6042 pic14_emitcode("orl","a,#0x%02x",
6043 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
6044 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6046 case 7 : // ABBBBBBB:CDDDDDDD
6047 tlbl = newiTempLabel(NULL);
6048 pic14_emitcode("mov","c,acc.7"); // c = A
6049 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
6050 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
6051 pic14_emitcode("anl","a,#0x%02x",
6052 SRMask[shCount]); // 0000000A:BBBBBBBC
6053 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6054 pic14_emitcode("orl","a,#0x%02x",
6055 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
6056 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6063 /*-----------------------------------------------------------------*/
6064 /* shiftL2Left2Result - shift left two bytes from left to result */
6065 /*-----------------------------------------------------------------*/
6066 static void shiftL2Left2Result (operand *left, int offl,
6067 operand *result, int offr, int shCount)
6071 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6073 if(pic14_sameRegs(AOP(result), AOP(left))) {
6081 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6082 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6083 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6087 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6088 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6094 emitpcode(POC_MOVLW, popGetLit(0x0f));
6095 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6096 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6097 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6098 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6099 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6100 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6102 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6103 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6107 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6108 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6109 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6110 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6111 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6112 emitpcode(POC_ANDLW,popGetLit(0xc0));
6113 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6114 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6115 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6116 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6119 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6120 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6121 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6122 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6123 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6133 /* note, use a mov/add for the shift since the mov has a
6134 chance of getting optimized out */
6135 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6136 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6137 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6138 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6139 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6143 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6144 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6150 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6151 emitpcode(POC_ANDLW, popGetLit(0xF0));
6152 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6153 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6154 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6155 emitpcode(POC_ANDLW, popGetLit(0xF0));
6156 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6157 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6161 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6162 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6166 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6167 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6168 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6169 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6171 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6172 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6173 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6174 emitpcode(POC_ANDLW,popGetLit(0xc0));
6175 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6176 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6177 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6178 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6181 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6182 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6183 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6185 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6190 /*-----------------------------------------------------------------*/
6191 /* shiftR2Left2Result - shift right two bytes from left to result */
6192 /*-----------------------------------------------------------------*/
6193 static void shiftR2Left2Result (operand *left, int offl,
6194 operand *result, int offr,
6195 int shCount, int sign)
6199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6200 same = pic14_sameRegs(AOP(result), AOP(left));
6202 if(same && ((offl + MSB16) == offr)){
6204 /* don't crash result[offr] */
6205 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6206 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6208 movLeft2Result(left,offl, result, offr, 0);
6209 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6211 /* a:x >> shCount (x = lsb(result))*/
6213 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6215 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6225 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6226 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6229 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6230 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6231 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6232 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6237 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6238 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6245 emitpcode(POC_MOVLW, popGetLit(0xf0));
6246 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6247 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6249 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6250 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6251 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6252 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6254 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6255 emitpcode(POC_ANDLW, popGetLit(0x0f));
6256 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6258 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6259 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6260 emitpcode(POC_ANDLW, popGetLit(0xf0));
6261 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6262 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6266 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6267 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6275 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6276 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6278 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6279 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6280 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6281 emitpcode(POC_ANDLW,popGetLit(0x03));
6282 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6283 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6284 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6285 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6287 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6288 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6289 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6290 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6291 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6292 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6293 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6294 emitpcode(POC_ANDLW,popGetLit(0x03));
6295 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6300 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6301 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6302 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6303 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6304 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6309 /*-----------------------------------------------------------------*/
6310 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6311 /*-----------------------------------------------------------------*/
6312 static void shiftLLeftOrResult (operand *left, int offl,
6313 operand *result, int offr, int shCount)
6315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6316 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6317 /* shift left accumulator */
6319 /* or with result */
6320 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6321 /* back to result */
6322 aopPut(AOP(result),"a",offr);
6325 /*-----------------------------------------------------------------*/
6326 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6327 /*-----------------------------------------------------------------*/
6328 static void shiftRLeftOrResult (operand *left, int offl,
6329 operand *result, int offr, int shCount)
6331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6332 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6333 /* shift right accumulator */
6335 /* or with result */
6336 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6337 /* back to result */
6338 aopPut(AOP(result),"a",offr);
6341 /*-----------------------------------------------------------------*/
6342 /* genlshOne - left shift a one byte quantity by known count */
6343 /*-----------------------------------------------------------------*/
6344 static void genlshOne (operand *result, operand *left, int shCount)
6346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6347 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6350 /*-----------------------------------------------------------------*/
6351 /* genlshTwo - left shift two bytes by known amount != 0 */
6352 /*-----------------------------------------------------------------*/
6353 static void genlshTwo (operand *result,operand *left, int shCount)
6357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6358 size = pic14_getDataSize(result);
6360 /* if shCount >= 8 */
6366 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6368 movLeft2Result(left, LSB, result, MSB16, 0);
6370 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6373 /* 1 <= shCount <= 7 */
6376 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6378 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6382 /*-----------------------------------------------------------------*/
6383 /* shiftLLong - shift left one long from left to result */
6384 /* offl = LSB or MSB16 */
6385 /*-----------------------------------------------------------------*/
6386 static void shiftLLong (operand *left, operand *result, int offr )
6389 int size = AOP_SIZE(result);
6391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6392 if(size >= LSB+offr){
6393 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6395 pic14_emitcode("add","a,acc");
6396 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6397 size >= MSB16+offr && offr != LSB )
6398 pic14_emitcode("xch","a,%s",
6399 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6401 aopPut(AOP(result),"a",LSB+offr);
6404 if(size >= MSB16+offr){
6405 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6406 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6409 pic14_emitcode("rlc","a");
6410 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6411 size >= MSB24+offr && offr != LSB)
6412 pic14_emitcode("xch","a,%s",
6413 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6415 aopPut(AOP(result),"a",MSB16+offr);
6418 if(size >= MSB24+offr){
6419 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6420 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6423 pic14_emitcode("rlc","a");
6424 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6425 size >= MSB32+offr && offr != LSB )
6426 pic14_emitcode("xch","a,%s",
6427 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6429 aopPut(AOP(result),"a",MSB24+offr);
6432 if(size > MSB32+offr){
6433 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6434 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6437 pic14_emitcode("rlc","a");
6438 aopPut(AOP(result),"a",MSB32+offr);
6441 aopPut(AOP(result),zero,LSB);
6444 /*-----------------------------------------------------------------*/
6445 /* genlshFour - shift four byte by a known amount != 0 */
6446 /*-----------------------------------------------------------------*/
6447 static void genlshFour (operand *result, operand *left, int shCount)
6451 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6452 size = AOP_SIZE(result);
6454 /* if shifting more that 3 bytes */
6455 if (shCount >= 24 ) {
6458 /* lowest order of left goes to the highest
6459 order of the destination */
6460 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6462 movLeft2Result(left, LSB, result, MSB32, 0);
6463 aopPut(AOP(result),zero,LSB);
6464 aopPut(AOP(result),zero,MSB16);
6465 aopPut(AOP(result),zero,MSB32);
6469 /* more than two bytes */
6470 else if ( shCount >= 16 ) {
6471 /* lower order two bytes goes to higher order two bytes */
6473 /* if some more remaining */
6475 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6477 movLeft2Result(left, MSB16, result, MSB32, 0);
6478 movLeft2Result(left, LSB, result, MSB24, 0);
6480 aopPut(AOP(result),zero,MSB16);
6481 aopPut(AOP(result),zero,LSB);
6485 /* if more than 1 byte */
6486 else if ( shCount >= 8 ) {
6487 /* lower order three bytes goes to higher order three bytes */
6491 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6493 movLeft2Result(left, LSB, result, MSB16, 0);
6495 else{ /* size = 4 */
6497 movLeft2Result(left, MSB24, result, MSB32, 0);
6498 movLeft2Result(left, MSB16, result, MSB24, 0);
6499 movLeft2Result(left, LSB, result, MSB16, 0);
6500 aopPut(AOP(result),zero,LSB);
6502 else if(shCount == 1)
6503 shiftLLong(left, result, MSB16);
6505 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6506 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6507 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6508 aopPut(AOP(result),zero,LSB);
6513 /* 1 <= shCount <= 7 */
6514 else if(shCount <= 2){
6515 shiftLLong(left, result, LSB);
6517 shiftLLong(result, result, LSB);
6519 /* 3 <= shCount <= 7, optimize */
6521 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6522 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6523 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6527 /*-----------------------------------------------------------------*/
6528 /* genLeftShiftLiteral - left shifting by known count */
6529 /*-----------------------------------------------------------------*/
6530 static void genLeftShiftLiteral (operand *left,
6535 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6539 freeAsmop(right,NULL,ic,TRUE);
6541 aopOp(left,ic,FALSE);
6542 aopOp(result,ic,FALSE);
6544 size = getSize(operandType(result));
6547 pic14_emitcode("; shift left ","result %d, left %d",size,
6551 /* I suppose that the left size >= result size */
6554 movLeft2Result(left, size, result, size, 0);
6558 else if(shCount >= (size * 8))
6560 aopPut(AOP(result),zero,size);
6564 genlshOne (result,left,shCount);
6569 genlshTwo (result,left,shCount);
6573 genlshFour (result,left,shCount);
6577 freeAsmop(left,NULL,ic,TRUE);
6578 freeAsmop(result,NULL,ic,TRUE);
6581 /*-----------------------------------------------------------------*/
6582 /* genLeftShift - generates code for left shifting */
6583 /*-----------------------------------------------------------------*/
6584 static void genLeftShift (iCode *ic)
6586 operand *left,*right, *result;
6589 symbol *tlbl , *tlbl1;
6591 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6593 right = IC_RIGHT(ic);
6595 result = IC_RESULT(ic);
6597 aopOp(right,ic,FALSE);
6599 /* if the shift count is known then do it
6600 as efficiently as possible */
6601 if (AOP_TYPE(right) == AOP_LIT) {
6602 genLeftShiftLiteral (left,right,result,ic);
6606 /* shift count is unknown then we have to form
6607 a loop get the loop count in B : Note: we take
6608 only the lower order byte since shifting
6609 more that 32 bits make no sense anyway, ( the
6610 largest size of an object can be only 32 bits ) */
6613 aopOp(left,ic,FALSE);
6614 aopOp(result,ic,FALSE);
6616 /* now move the left to the result if they are not the
6618 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6619 AOP_SIZE(result) > 1) {
6621 size = AOP_SIZE(result);
6624 l = aopGet(AOP(left),offset,FALSE,TRUE);
6625 if (*l == '@' && (IS_AOP_PREG(result))) {
6627 pic14_emitcode("mov","a,%s",l);
6628 aopPut(AOP(result),"a",offset);
6630 aopPut(AOP(result),l,offset);
6635 size = AOP_SIZE(result);
6637 /* if it is only one byte then */
6639 if(optimized_for_speed) {
6640 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6641 emitpcode(POC_ANDLW, popGetLit(0xf0));
6642 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6643 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6644 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6645 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6646 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6647 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6648 emitpcode(POC_ANDLW, popGetLit(0xfe));
6649 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6650 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6651 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6654 tlbl = newiTempLabel(NULL);
6655 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6656 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6657 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6660 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6661 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6662 emitpLabel(tlbl->key);
6663 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6664 emitpcode(POC_ADDLW, popGetLit(1));
6666 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6672 tlbl = newiTempLabel(NULL);
6674 tlbl1 = newiTempLabel(NULL);
6676 reAdjustPreg(AOP(result));
6678 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6679 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6680 l = aopGet(AOP(result),offset,FALSE,FALSE);
6682 pic14_emitcode("add","a,acc");
6683 aopPut(AOP(result),"a",offset++);
6685 l = aopGet(AOP(result),offset,FALSE,FALSE);
6687 pic14_emitcode("rlc","a");
6688 aopPut(AOP(result),"a",offset++);
6690 reAdjustPreg(AOP(result));
6692 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6693 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6695 freeAsmop (right,NULL,ic,TRUE);
6696 freeAsmop(left,NULL,ic,TRUE);
6697 freeAsmop(result,NULL,ic,TRUE);
6700 /*-----------------------------------------------------------------*/
6701 /* genrshOne - right shift a one byte quantity by known count */
6702 /*-----------------------------------------------------------------*/
6703 static void genrshOne (operand *result, operand *left,
6704 int shCount, int sign)
6706 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6707 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6710 /*-----------------------------------------------------------------*/
6711 /* genrshTwo - right shift two bytes by known amount != 0 */
6712 /*-----------------------------------------------------------------*/
6713 static void genrshTwo (operand *result,operand *left,
6714 int shCount, int sign)
6716 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6717 /* if shCount >= 8 */
6721 shiftR1Left2Result(left, MSB16, result, LSB,
6724 movLeft2Result(left, MSB16, result, LSB, sign);
6726 addSign(result, MSB16, sign);
6728 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6732 /* 1 <= shCount <= 7 */
6734 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6737 /*-----------------------------------------------------------------*/
6738 /* shiftRLong - shift right one long from left to result */
6739 /* offl = LSB or MSB16 */
6740 /*-----------------------------------------------------------------*/
6741 static void shiftRLong (operand *left, int offl,
6742 operand *result, int sign)
6744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6746 pic14_emitcode("clr","c");
6747 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6749 pic14_emitcode("mov","c,acc.7");
6750 pic14_emitcode("rrc","a");
6751 aopPut(AOP(result),"a",MSB32-offl);
6753 /* add sign of "a" */
6754 addSign(result, MSB32, sign);
6756 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6757 pic14_emitcode("rrc","a");
6758 aopPut(AOP(result),"a",MSB24-offl);
6760 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6761 pic14_emitcode("rrc","a");
6762 aopPut(AOP(result),"a",MSB16-offl);
6765 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6766 pic14_emitcode("rrc","a");
6767 aopPut(AOP(result),"a",LSB);
6771 /*-----------------------------------------------------------------*/
6772 /* genrshFour - shift four byte by a known amount != 0 */
6773 /*-----------------------------------------------------------------*/
6774 static void genrshFour (operand *result, operand *left,
6775 int shCount, int sign)
6777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6778 /* if shifting more that 3 bytes */
6779 if(shCount >= 24 ) {
6782 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6784 movLeft2Result(left, MSB32, result, LSB, sign);
6785 addSign(result, MSB16, sign);
6787 else if(shCount >= 16){
6790 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6792 movLeft2Result(left, MSB24, result, LSB, 0);
6793 movLeft2Result(left, MSB32, result, MSB16, sign);
6795 addSign(result, MSB24, sign);
6797 else if(shCount >= 8){
6800 shiftRLong(left, MSB16, result, sign);
6801 else if(shCount == 0){
6802 movLeft2Result(left, MSB16, result, LSB, 0);
6803 movLeft2Result(left, MSB24, result, MSB16, 0);
6804 movLeft2Result(left, MSB32, result, MSB24, sign);
6805 addSign(result, MSB32, sign);
6808 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6809 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6810 /* the last shift is signed */
6811 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6812 addSign(result, MSB32, sign);
6815 else{ /* 1 <= shCount <= 7 */
6817 shiftRLong(left, LSB, result, sign);
6819 shiftRLong(result, LSB, result, sign);
6822 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6823 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6824 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6829 /*-----------------------------------------------------------------*/
6830 /* genRightShiftLiteral - right shifting by known count */
6831 /*-----------------------------------------------------------------*/
6832 static void genRightShiftLiteral (operand *left,
6838 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6842 freeAsmop(right,NULL,ic,TRUE);
6844 aopOp(left,ic,FALSE);
6845 aopOp(result,ic,FALSE);
6848 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6852 size = pic14_getDataSize(left);
6853 /* test the LEFT size !!! */
6855 /* I suppose that the left size >= result size */
6857 size = pic14_getDataSize(result);
6859 movLeft2Result(left, size, result, size, 0);
6862 else if(shCount >= (size * 8)){
6864 /* get sign in acc.7 */
6865 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6866 addSign(result, LSB, sign);
6870 genrshOne (result,left,shCount,sign);
6874 genrshTwo (result,left,shCount,sign);
6878 genrshFour (result,left,shCount,sign);
6884 freeAsmop(left,NULL,ic,TRUE);
6885 freeAsmop(result,NULL,ic,TRUE);
6889 /*-----------------------------------------------------------------*/
6890 /* genSignedRightShift - right shift of signed number */
6891 /*-----------------------------------------------------------------*/
6892 static void genSignedRightShift (iCode *ic)
6894 operand *right, *left, *result;
6897 symbol *tlbl, *tlbl1 ;
6899 /* we do it the hard way put the shift count in b
6900 and loop thru preserving the sign */
6901 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6903 right = IC_RIGHT(ic);
6905 result = IC_RESULT(ic);
6907 aopOp(right,ic,FALSE);
6910 if ( AOP_TYPE(right) == AOP_LIT) {
6911 genRightShiftLiteral (left,right,result,ic,1);
6914 /* shift count is unknown then we have to form
6915 a loop get the loop count in B : Note: we take
6916 only the lower order byte since shifting
6917 more that 32 bits make no sense anyway, ( the
6918 largest size of an object can be only 32 bits ) */
6920 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6921 pic14_emitcode("inc","b");
6922 freeAsmop (right,NULL,ic,TRUE);
6923 aopOp(left,ic,FALSE);
6924 aopOp(result,ic,FALSE);
6926 /* now move the left to the result if they are not the
6928 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6929 AOP_SIZE(result) > 1) {
6931 size = AOP_SIZE(result);
6934 l = aopGet(AOP(left),offset,FALSE,TRUE);
6935 if (*l == '@' && IS_AOP_PREG(result)) {
6937 pic14_emitcode("mov","a,%s",l);
6938 aopPut(AOP(result),"a",offset);
6940 aopPut(AOP(result),l,offset);
6945 /* mov the highest order bit to OVR */
6946 tlbl = newiTempLabel(NULL);
6947 tlbl1= newiTempLabel(NULL);
6949 size = AOP_SIZE(result);
6951 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6952 pic14_emitcode("rlc","a");
6953 pic14_emitcode("mov","ov,c");
6954 /* if it is only one byte then */
6956 l = aopGet(AOP(left),0,FALSE,FALSE);
6958 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6959 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6960 pic14_emitcode("mov","c,ov");
6961 pic14_emitcode("rrc","a");
6962 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6963 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6964 aopPut(AOP(result),"a",0);
6968 reAdjustPreg(AOP(result));
6969 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6970 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6971 pic14_emitcode("mov","c,ov");
6973 l = aopGet(AOP(result),offset,FALSE,FALSE);
6975 pic14_emitcode("rrc","a");
6976 aopPut(AOP(result),"a",offset--);
6978 reAdjustPreg(AOP(result));
6979 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6980 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6983 freeAsmop(left,NULL,ic,TRUE);
6984 freeAsmop(result,NULL,ic,TRUE);
6987 /*-----------------------------------------------------------------*/
6988 /* genRightShift - generate code for right shifting */
6989 /*-----------------------------------------------------------------*/
6990 static void genRightShift (iCode *ic)
6992 operand *right, *left, *result;
6996 symbol *tlbl, *tlbl1 ;
6998 /* if signed then we do it the hard way preserve the
6999 sign bit moving it inwards */
7000 retype = getSpec(operandType(IC_RESULT(ic)));
7001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7003 if (!SPEC_USIGN(retype)) {
7004 genSignedRightShift (ic);
7008 /* signed & unsigned types are treated the same : i.e. the
7009 signed is NOT propagated inwards : quoting from the
7010 ANSI - standard : "for E1 >> E2, is equivalent to division
7011 by 2**E2 if unsigned or if it has a non-negative value,
7012 otherwise the result is implementation defined ", MY definition
7013 is that the sign does not get propagated */
7015 right = IC_RIGHT(ic);
7017 result = IC_RESULT(ic);
7019 aopOp(right,ic,FALSE);
7021 /* if the shift count is known then do it
7022 as efficiently as possible */
7023 if (AOP_TYPE(right) == AOP_LIT) {
7024 genRightShiftLiteral (left,right,result,ic, 0);
7028 /* shift count is unknown then we have to form
7029 a loop get the loop count in B : Note: we take
7030 only the lower order byte since shifting
7031 more that 32 bits make no sense anyway, ( the
7032 largest size of an object can be only 32 bits ) */
7034 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7035 pic14_emitcode("inc","b");
7036 aopOp(left,ic,FALSE);
7037 aopOp(result,ic,FALSE);
7039 /* now move the left to the result if they are not the
7041 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7042 AOP_SIZE(result) > 1) {
7044 size = AOP_SIZE(result);
7047 l = aopGet(AOP(left),offset,FALSE,TRUE);
7048 if (*l == '@' && IS_AOP_PREG(result)) {
7050 pic14_emitcode("mov","a,%s",l);
7051 aopPut(AOP(result),"a",offset);
7053 aopPut(AOP(result),l,offset);
7058 tlbl = newiTempLabel(NULL);
7059 tlbl1= newiTempLabel(NULL);
7060 size = AOP_SIZE(result);
7063 /* if it is only one byte then */
7066 l = aopGet(AOP(left),0,FALSE,FALSE);
7068 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7069 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7071 pic14_emitcode("rrc","a");
7072 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7073 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7074 aopPut(AOP(result),"a",0);
7076 tlbl = newiTempLabel(NULL);
7077 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7078 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
7079 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
7082 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
7083 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
7084 emitpLabel(tlbl->key);
7085 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
7086 emitpcode(POC_ADDLW, popGetLit(1));
7088 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7093 reAdjustPreg(AOP(result));
7094 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7095 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7098 l = aopGet(AOP(result),offset,FALSE,FALSE);
7100 pic14_emitcode("rrc","a");
7101 aopPut(AOP(result),"a",offset--);
7103 reAdjustPreg(AOP(result));
7105 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7106 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7109 freeAsmop(left,NULL,ic,TRUE);
7110 freeAsmop (right,NULL,ic,TRUE);
7111 freeAsmop(result,NULL,ic,TRUE);
7114 /*-----------------------------------------------------------------*/
7115 /* genUnpackBits - generates code for unpacking bits */
7116 /*-----------------------------------------------------------------*/
7117 static void genUnpackBits (operand *result, char *rname, int ptype)
7124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7125 etype = getSpec(operandType(result));
7127 /* read the first byte */
7132 pic14_emitcode("mov","a,@%s",rname);
7136 pic14_emitcode("movx","a,@%s",rname);
7140 pic14_emitcode("movx","a,@dptr");
7144 pic14_emitcode("clr","a");
7145 pic14_emitcode("movc","a","@a+dptr");
7149 pic14_emitcode("lcall","__gptrget");
7153 /* if we have bitdisplacement then it fits */
7154 /* into this byte completely or if length is */
7155 /* less than a byte */
7156 if ((shCnt = SPEC_BSTR(etype)) ||
7157 (SPEC_BLEN(etype) <= 8)) {
7159 /* shift right acc */
7162 pic14_emitcode("anl","a,#0x%02x",
7163 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7164 aopPut(AOP(result),"a",offset);
7168 /* bit field did not fit in a byte */
7169 rlen = SPEC_BLEN(etype) - 8;
7170 aopPut(AOP(result),"a",offset++);
7177 pic14_emitcode("inc","%s",rname);
7178 pic14_emitcode("mov","a,@%s",rname);
7182 pic14_emitcode("inc","%s",rname);
7183 pic14_emitcode("movx","a,@%s",rname);
7187 pic14_emitcode("inc","dptr");
7188 pic14_emitcode("movx","a,@dptr");
7192 pic14_emitcode("clr","a");
7193 pic14_emitcode("inc","dptr");
7194 pic14_emitcode("movc","a","@a+dptr");
7198 pic14_emitcode("inc","dptr");
7199 pic14_emitcode("lcall","__gptrget");
7204 /* if we are done */
7208 aopPut(AOP(result),"a",offset++);
7213 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7214 aopPut(AOP(result),"a",offset);
7221 /*-----------------------------------------------------------------*/
7222 /* genDataPointerGet - generates code when ptr offset is known */
7223 /*-----------------------------------------------------------------*/
7224 static void genDataPointerGet (operand *left,
7228 int size , offset = 0;
7231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7234 /* optimization - most of the time, left and result are the same
7235 * address, but different types. for the pic code, we could omit
7239 aopOp(result,ic,TRUE);
7241 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7243 size = AOP_SIZE(result);
7246 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7250 freeAsmop(left,NULL,ic,TRUE);
7251 freeAsmop(result,NULL,ic,TRUE);
7254 /*-----------------------------------------------------------------*/
7255 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7256 /*-----------------------------------------------------------------*/
7257 static void genNearPointerGet (operand *left,
7264 sym_link *rtype, *retype;
7265 sym_link *ltype = operandType(left);
7268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7270 rtype = operandType(result);
7271 retype= getSpec(rtype);
7273 aopOp(left,ic,FALSE);
7275 /* if left is rematerialisable and
7276 result is not bit variable type and
7277 the left is pointer to data space i.e
7278 lower 128 bytes of space */
7279 if (AOP_TYPE(left) == AOP_IMMD &&
7280 !IS_BITVAR(retype) &&
7281 DCL_TYPE(ltype) == POINTER) {
7282 genDataPointerGet (left,result,ic);
7286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7288 /* if the value is already in a pointer register
7289 then don't need anything more */
7290 if (!AOP_INPREG(AOP(left))) {
7291 /* otherwise get a free pointer register */
7292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7294 preg = getFreePtr(ic,&aop,FALSE);
7295 pic14_emitcode("mov","%s,%s",
7297 aopGet(AOP(left),0,FALSE,TRUE));
7298 rname = preg->name ;
7300 rname = aopGet(AOP(left),0,FALSE,FALSE);
7302 freeAsmop(left,NULL,ic,TRUE);
7303 aopOp (result,ic,FALSE);
7305 /* if bitfield then unpack the bits */
7306 if (IS_BITVAR(retype))
7307 genUnpackBits (result,rname,POINTER);
7309 /* we have can just get the values */
7310 int size = AOP_SIZE(result);
7313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7315 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7317 pic14_emitcode("mov","a,@%s",rname);
7318 aopPut(AOP(result),"a",offset);
7320 sprintf(buffer,"@%s",rname);
7321 aopPut(AOP(result),buffer,offset);
7325 pic14_emitcode("inc","%s",rname);
7329 /* now some housekeeping stuff */
7331 /* we had to allocate for this iCode */
7332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7333 freeAsmop(NULL,aop,ic,TRUE);
7335 /* we did not allocate which means left
7336 already in a pointer register, then
7337 if size > 0 && this could be used again
7338 we have to point it back to where it
7340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7341 if (AOP_SIZE(result) > 1 &&
7342 !OP_SYMBOL(left)->remat &&
7343 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7345 int size = AOP_SIZE(result) - 1;
7347 pic14_emitcode("dec","%s",rname);
7352 freeAsmop(result,NULL,ic,TRUE);
7356 /*-----------------------------------------------------------------*/
7357 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7358 /*-----------------------------------------------------------------*/
7359 static void genPagedPointerGet (operand *left,
7366 sym_link *rtype, *retype;
7368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7370 rtype = operandType(result);
7371 retype= getSpec(rtype);
7373 aopOp(left,ic,FALSE);
7375 /* if the value is already in a pointer register
7376 then don't need anything more */
7377 if (!AOP_INPREG(AOP(left))) {
7378 /* otherwise get a free pointer register */
7380 preg = getFreePtr(ic,&aop,FALSE);
7381 pic14_emitcode("mov","%s,%s",
7383 aopGet(AOP(left),0,FALSE,TRUE));
7384 rname = preg->name ;
7386 rname = aopGet(AOP(left),0,FALSE,FALSE);
7388 freeAsmop(left,NULL,ic,TRUE);
7389 aopOp (result,ic,FALSE);
7391 /* if bitfield then unpack the bits */
7392 if (IS_BITVAR(retype))
7393 genUnpackBits (result,rname,PPOINTER);
7395 /* we have can just get the values */
7396 int size = AOP_SIZE(result);
7401 pic14_emitcode("movx","a,@%s",rname);
7402 aopPut(AOP(result),"a",offset);
7407 pic14_emitcode("inc","%s",rname);
7411 /* now some housekeeping stuff */
7413 /* we had to allocate for this iCode */
7414 freeAsmop(NULL,aop,ic,TRUE);
7416 /* we did not allocate which means left
7417 already in a pointer register, then
7418 if size > 0 && this could be used again
7419 we have to point it back to where it
7421 if (AOP_SIZE(result) > 1 &&
7422 !OP_SYMBOL(left)->remat &&
7423 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7425 int size = AOP_SIZE(result) - 1;
7427 pic14_emitcode("dec","%s",rname);
7432 freeAsmop(result,NULL,ic,TRUE);
7437 /*-----------------------------------------------------------------*/
7438 /* genFarPointerGet - gget value from far space */
7439 /*-----------------------------------------------------------------*/
7440 static void genFarPointerGet (operand *left,
7441 operand *result, iCode *ic)
7444 sym_link *retype = getSpec(operandType(result));
7446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7448 aopOp(left,ic,FALSE);
7450 /* if the operand is already in dptr
7451 then we do nothing else we move the value to dptr */
7452 if (AOP_TYPE(left) != AOP_STR) {
7453 /* if this is remateriazable */
7454 if (AOP_TYPE(left) == AOP_IMMD)
7455 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7456 else { /* we need to get it byte by byte */
7457 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7458 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7459 if (options.model == MODEL_FLAT24)
7461 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7465 /* so dptr know contains the address */
7466 freeAsmop(left,NULL,ic,TRUE);
7467 aopOp(result,ic,FALSE);
7469 /* if bit then unpack */
7470 if (IS_BITVAR(retype))
7471 genUnpackBits(result,"dptr",FPOINTER);
7473 size = AOP_SIZE(result);
7477 pic14_emitcode("movx","a,@dptr");
7478 aopPut(AOP(result),"a",offset++);
7480 pic14_emitcode("inc","dptr");
7484 freeAsmop(result,NULL,ic,TRUE);
7487 /*-----------------------------------------------------------------*/
7488 /* pic14_emitcodePointerGet - gget value from code space */
7489 /*-----------------------------------------------------------------*/
7490 static void pic14_emitcodePointerGet (operand *left,
7491 operand *result, iCode *ic)
7494 sym_link *retype = getSpec(operandType(result));
7496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7498 aopOp(left,ic,FALSE);
7500 /* if the operand is already in dptr
7501 then we do nothing else we move the value to dptr */
7502 if (AOP_TYPE(left) != AOP_STR) {
7503 /* if this is remateriazable */
7504 if (AOP_TYPE(left) == AOP_IMMD)
7505 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7506 else { /* we need to get it byte by byte */
7507 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7508 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7509 if (options.model == MODEL_FLAT24)
7511 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7515 /* so dptr know contains the address */
7516 freeAsmop(left,NULL,ic,TRUE);
7517 aopOp(result,ic,FALSE);
7519 /* if bit then unpack */
7520 if (IS_BITVAR(retype))
7521 genUnpackBits(result,"dptr",CPOINTER);
7523 size = AOP_SIZE(result);
7527 pic14_emitcode("clr","a");
7528 pic14_emitcode("movc","a,@a+dptr");
7529 aopPut(AOP(result),"a",offset++);
7531 pic14_emitcode("inc","dptr");
7535 freeAsmop(result,NULL,ic,TRUE);
7538 /*-----------------------------------------------------------------*/
7539 /* genGenPointerGet - gget value from generic pointer space */
7540 /*-----------------------------------------------------------------*/
7541 static void genGenPointerGet (operand *left,
7542 operand *result, iCode *ic)
7545 sym_link *retype = getSpec(operandType(result));
7547 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7548 aopOp(left,ic,FALSE);
7549 aopOp(result,ic,FALSE);
7552 DEBUGpic14_emitcode ("; ","result %s, left %s",
7553 AopType(AOP_TYPE(result)),
7554 AopType(AOP_TYPE(left)));
7556 /* if the operand is already in dptr
7557 then we do nothing else we move the value to dptr */
7558 if (AOP_TYPE(left) != AOP_STR) {
7559 /* if this is remateriazable */
7560 if (AOP_TYPE(left) == AOP_IMMD) {
7561 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7562 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7564 else { /* we need to get it byte by byte */
7566 size = AOP_SIZE(result);
7570 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7571 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7573 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7578 /* so dptr know contains the address */
7580 /* if bit then unpack */
7581 if (IS_BITVAR(retype))
7582 genUnpackBits(result,"dptr",GPOINTER);
7585 freeAsmop(left,NULL,ic,TRUE);
7586 freeAsmop(result,NULL,ic,TRUE);
7590 /*-----------------------------------------------------------------*/
7591 /* genPointerGet - generate code for pointer get */
7592 /*-----------------------------------------------------------------*/
7593 static void genPointerGet (iCode *ic)
7595 operand *left, *result ;
7596 sym_link *type, *etype;
7599 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7602 result = IC_RESULT(ic) ;
7604 /* depending on the type of pointer we need to
7605 move it to the correct pointer register */
7606 type = operandType(left);
7607 etype = getSpec(type);
7608 /* if left is of type of pointer then it is simple */
7609 if (IS_PTR(type) && !IS_FUNC(type->next))
7610 p_type = DCL_TYPE(type);
7612 /* we have to go by the storage class */
7613 p_type = PTR_TYPE(SPEC_OCLS(etype));
7615 /* if (SPEC_OCLS(etype)->codesp ) { */
7616 /* p_type = CPOINTER ; */
7619 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7620 /* p_type = FPOINTER ; */
7622 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7623 /* p_type = PPOINTER; */
7625 /* if (SPEC_OCLS(etype) == idata ) */
7626 /* p_type = IPOINTER; */
7628 /* p_type = POINTER ; */
7631 /* now that we have the pointer type we assign
7632 the pointer values */
7637 genNearPointerGet (left,result,ic);
7641 genPagedPointerGet(left,result,ic);
7645 genFarPointerGet (left,result,ic);
7649 pic14_emitcodePointerGet (left,result,ic);
7653 genGenPointerGet (left,result,ic);
7659 /*-----------------------------------------------------------------*/
7660 /* genPackBits - generates code for packed bit storage */
7661 /*-----------------------------------------------------------------*/
7662 static void genPackBits (sym_link *etype ,
7664 char *rname, int p_type)
7672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7673 blen = SPEC_BLEN(etype);
7674 bstr = SPEC_BSTR(etype);
7676 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7679 /* if the bit lenth is less than or */
7680 /* it exactly fits a byte then */
7681 if (SPEC_BLEN(etype) <= 8 ) {
7682 shCount = SPEC_BSTR(etype) ;
7684 /* shift left acc */
7687 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7692 pic14_emitcode ("mov","b,a");
7693 pic14_emitcode("mov","a,@%s",rname);
7697 pic14_emitcode ("mov","b,a");
7698 pic14_emitcode("movx","a,@dptr");
7702 pic14_emitcode ("push","b");
7703 pic14_emitcode ("push","acc");
7704 pic14_emitcode ("lcall","__gptrget");
7705 pic14_emitcode ("pop","b");
7709 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7710 ((unsigned char)(0xFF << (blen+bstr)) |
7711 (unsigned char)(0xFF >> (8-bstr)) ) );
7712 pic14_emitcode ("orl","a,b");
7713 if (p_type == GPOINTER)
7714 pic14_emitcode("pop","b");
7720 pic14_emitcode("mov","@%s,a",rname);
7724 pic14_emitcode("movx","@dptr,a");
7728 DEBUGpic14_emitcode(";lcall","__gptrput");
7733 if ( SPEC_BLEN(etype) <= 8 )
7736 pic14_emitcode("inc","%s",rname);
7737 rLen = SPEC_BLEN(etype) ;
7739 /* now generate for lengths greater than one byte */
7742 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7752 pic14_emitcode("mov","@%s,a",rname);
7754 pic14_emitcode("mov","@%s,%s",rname,l);
7759 pic14_emitcode("movx","@dptr,a");
7764 DEBUGpic14_emitcode(";lcall","__gptrput");
7767 pic14_emitcode ("inc","%s",rname);
7772 /* last last was not complete */
7774 /* save the byte & read byte */
7777 pic14_emitcode ("mov","b,a");
7778 pic14_emitcode("mov","a,@%s",rname);
7782 pic14_emitcode ("mov","b,a");
7783 pic14_emitcode("movx","a,@dptr");
7787 pic14_emitcode ("push","b");
7788 pic14_emitcode ("push","acc");
7789 pic14_emitcode ("lcall","__gptrget");
7790 pic14_emitcode ("pop","b");
7794 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7795 pic14_emitcode ("orl","a,b");
7798 if (p_type == GPOINTER)
7799 pic14_emitcode("pop","b");
7804 pic14_emitcode("mov","@%s,a",rname);
7808 pic14_emitcode("movx","@dptr,a");
7812 DEBUGpic14_emitcode(";lcall","__gptrput");
7816 /*-----------------------------------------------------------------*/
7817 /* genDataPointerSet - remat pointer to data space */
7818 /*-----------------------------------------------------------------*/
7819 static void genDataPointerSet(operand *right,
7823 int size, offset = 0 ;
7824 char *l, buffer[256];
7826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7827 aopOp(right,ic,FALSE);
7829 l = aopGet(AOP(result),0,FALSE,TRUE);
7830 size = AOP_SIZE(right);
7831 // tsd, was l+1 - the underline `_' prefix was being stripped
7834 sprintf(buffer,"(%s + %d)",l,offset);
7836 sprintf(buffer,"%s",l);
7838 if (AOP_TYPE(right) == AOP_LIT) {
7839 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7840 lit = lit >> (8*offset);
7842 pic14_emitcode("movlw","%d",lit);
7843 pic14_emitcode("movwf","%s",buffer);
7845 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7846 emitpcode(POC_MOVWF, popRegFromString(buffer));
7849 pic14_emitcode("clrf","%s",buffer);
7850 emitpcode(POC_CLRF, popRegFromString(buffer));
7853 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7854 pic14_emitcode("movwf","%s",buffer);
7856 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7857 emitpcode(POC_MOVWF, popRegFromString(buffer));
7864 freeAsmop(right,NULL,ic,TRUE);
7865 freeAsmop(result,NULL,ic,TRUE);
7868 /*-----------------------------------------------------------------*/
7869 /* genNearPointerSet - pic14_emitcode for near pointer put */
7870 /*-----------------------------------------------------------------*/
7871 static void genNearPointerSet (operand *right,
7878 sym_link *ptype = operandType(result);
7881 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7882 retype= getSpec(operandType(right));
7884 aopOp(result,ic,FALSE);
7886 /* if the result is rematerializable &
7887 in data space & not a bit variable */
7888 if (AOP_TYPE(result) == AOP_IMMD &&
7889 DCL_TYPE(ptype) == POINTER &&
7890 !IS_BITVAR(retype)) {
7891 genDataPointerSet (right,result,ic);
7895 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7897 /* if the value is already in a pointer register
7898 then don't need anything more */
7899 if (!AOP_INPREG(AOP(result))) {
7900 /* otherwise get a free pointer register */
7901 //aop = newAsmop(0);
7902 //preg = getFreePtr(ic,&aop,FALSE);
7903 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7904 //pic14_emitcode("mov","%s,%s",
7906 // aopGet(AOP(result),0,FALSE,TRUE));
7907 //rname = preg->name ;
7908 pic14_emitcode("movwf","fsr");
7910 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7912 freeAsmop(result,NULL,ic,TRUE);
7913 aopOp (right,ic,FALSE);
7914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7916 /* if bitfield then unpack the bits */
7917 if (IS_BITVAR(retype)) {
7918 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7919 "The programmer is obviously confused");
7920 //genPackBits (retype,right,rname,POINTER);
7924 /* we have can just get the values */
7925 int size = AOP_SIZE(right);
7928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7930 l = aopGet(AOP(right),offset,FALSE,TRUE);
7933 //pic14_emitcode("mov","@%s,a",rname);
7934 pic14_emitcode("movf","indf,w ;1");
7937 if (AOP_TYPE(right) == AOP_LIT) {
7938 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7940 pic14_emitcode("movlw","%s",l);
7941 pic14_emitcode("movwf","indf ;2");
7943 pic14_emitcode("clrf","indf");
7945 pic14_emitcode("movf","%s,w",l);
7946 pic14_emitcode("movwf","indf ;2");
7948 //pic14_emitcode("mov","@%s,%s",rname,l);
7951 pic14_emitcode("incf","fsr,f ;3");
7952 //pic14_emitcode("inc","%s",rname);
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 /* now some housekeeping stuff */
7960 /* we had to allocate for this iCode */
7961 freeAsmop(NULL,aop,ic,TRUE);
7963 /* we did not allocate which means left
7964 already in a pointer register, then
7965 if size > 0 && this could be used again
7966 we have to point it back to where it
7968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7969 if (AOP_SIZE(right) > 1 &&
7970 !OP_SYMBOL(result)->remat &&
7971 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7973 int size = AOP_SIZE(right) - 1;
7975 pic14_emitcode("decf","fsr,f");
7976 //pic14_emitcode("dec","%s",rname);
7980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7982 freeAsmop(right,NULL,ic,TRUE);
7987 /*-----------------------------------------------------------------*/
7988 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7989 /*-----------------------------------------------------------------*/
7990 static void genPagedPointerSet (operand *right,
7999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 retype= getSpec(operandType(right));
8003 aopOp(result,ic,FALSE);
8005 /* if the value is already in a pointer register
8006 then don't need anything more */
8007 if (!AOP_INPREG(AOP(result))) {
8008 /* otherwise get a free pointer register */
8010 preg = getFreePtr(ic,&aop,FALSE);
8011 pic14_emitcode("mov","%s,%s",
8013 aopGet(AOP(result),0,FALSE,TRUE));
8014 rname = preg->name ;
8016 rname = aopGet(AOP(result),0,FALSE,FALSE);
8018 freeAsmop(result,NULL,ic,TRUE);
8019 aopOp (right,ic,FALSE);
8021 /* if bitfield then unpack the bits */
8022 if (IS_BITVAR(retype))
8023 genPackBits (retype,right,rname,PPOINTER);
8025 /* we have can just get the values */
8026 int size = AOP_SIZE(right);
8030 l = aopGet(AOP(right),offset,FALSE,TRUE);
8033 pic14_emitcode("movx","@%s,a",rname);
8036 pic14_emitcode("inc","%s",rname);
8042 /* now some housekeeping stuff */
8044 /* we had to allocate for this iCode */
8045 freeAsmop(NULL,aop,ic,TRUE);
8047 /* we did not allocate which means left
8048 already in a pointer register, then
8049 if size > 0 && this could be used again
8050 we have to point it back to where it
8052 if (AOP_SIZE(right) > 1 &&
8053 !OP_SYMBOL(result)->remat &&
8054 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8056 int size = AOP_SIZE(right) - 1;
8058 pic14_emitcode("dec","%s",rname);
8063 freeAsmop(right,NULL,ic,TRUE);
8068 /*-----------------------------------------------------------------*/
8069 /* genFarPointerSet - set value from far space */
8070 /*-----------------------------------------------------------------*/
8071 static void genFarPointerSet (operand *right,
8072 operand *result, iCode *ic)
8075 sym_link *retype = getSpec(operandType(right));
8077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8078 aopOp(result,ic,FALSE);
8080 /* if the operand is already in dptr
8081 then we do nothing else we move the value to dptr */
8082 if (AOP_TYPE(result) != AOP_STR) {
8083 /* if this is remateriazable */
8084 if (AOP_TYPE(result) == AOP_IMMD)
8085 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8086 else { /* we need to get it byte by byte */
8087 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8088 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8089 if (options.model == MODEL_FLAT24)
8091 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8095 /* so dptr know contains the address */
8096 freeAsmop(result,NULL,ic,TRUE);
8097 aopOp(right,ic,FALSE);
8099 /* if bit then unpack */
8100 if (IS_BITVAR(retype))
8101 genPackBits(retype,right,"dptr",FPOINTER);
8103 size = AOP_SIZE(right);
8107 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8109 pic14_emitcode("movx","@dptr,a");
8111 pic14_emitcode("inc","dptr");
8115 freeAsmop(right,NULL,ic,TRUE);
8118 /*-----------------------------------------------------------------*/
8119 /* genGenPointerSet - set value from generic pointer space */
8120 /*-----------------------------------------------------------------*/
8121 static void genGenPointerSet (operand *right,
8122 operand *result, iCode *ic)
8125 sym_link *retype = getSpec(operandType(right));
8127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8129 aopOp(result,ic,FALSE);
8130 aopOp(right,ic,FALSE);
8131 size = AOP_SIZE(right);
8133 DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8134 AopType(AOP_TYPE(result)),
8135 aopGet(AOP(result),0,TRUE,FALSE),
8136 AopType(AOP_TYPE(right)),
8137 aopGet(AOP(right),0,FALSE,FALSE),
8140 /* if the operand is already in dptr
8141 then we do nothing else we move the value to dptr */
8142 if (AOP_TYPE(result) != AOP_STR) {
8143 /* if this is remateriazable */
8144 if (AOP_TYPE(result) == AOP_IMMD) {
8145 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8146 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8148 else { /* we need to get it byte by byte */
8149 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8150 size = AOP_SIZE(right);
8153 /* hack hack! see if this the FSR. If so don't load W */
8154 if(AOP_TYPE(right) != AOP_ACC) {
8157 emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8160 emitpcode(POC_MOVLW,popGetLit(0xfd));
8161 emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8165 emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8166 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8169 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8176 if(aopIdx(AOP(result),0) != 4) {
8178 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8182 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8187 /* so dptr know contains the address */
8190 /* if bit then unpack */
8191 if (IS_BITVAR(retype))
8192 genPackBits(retype,right,"dptr",GPOINTER);
8194 size = AOP_SIZE(right);
8198 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8200 pic14_emitcode("incf","fsr,f");
8201 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8202 pic14_emitcode("movwf","indf");
8204 //DEBUGpic14_emitcode(";lcall","__gptrput");
8206 // pic14_emitcode("inc","dptr");
8211 freeAsmop(right,NULL,ic,TRUE);
8212 freeAsmop(result,NULL,ic,TRUE);
8215 /*-----------------------------------------------------------------*/
8216 /* genPointerSet - stores the value into a pointer location */
8217 /*-----------------------------------------------------------------*/
8218 static void genPointerSet (iCode *ic)
8220 operand *right, *result ;
8221 sym_link *type, *etype;
8224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8226 right = IC_RIGHT(ic);
8227 result = IC_RESULT(ic) ;
8229 /* depending on the type of pointer we need to
8230 move it to the correct pointer register */
8231 type = operandType(result);
8232 etype = getSpec(type);
8233 /* if left is of type of pointer then it is simple */
8234 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8235 p_type = DCL_TYPE(type);
8238 /* we have to go by the storage class */
8239 p_type = PTR_TYPE(SPEC_OCLS(etype));
8241 /* if (SPEC_OCLS(etype)->codesp ) { */
8242 /* p_type = CPOINTER ; */
8245 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8246 /* p_type = FPOINTER ; */
8248 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8249 /* p_type = PPOINTER ; */
8251 /* if (SPEC_OCLS(etype) == idata ) */
8252 /* p_type = IPOINTER ; */
8254 /* p_type = POINTER ; */
8257 /* now that we have the pointer type we assign
8258 the pointer values */
8263 genNearPointerSet (right,result,ic);
8267 genPagedPointerSet (right,result,ic);
8271 genFarPointerSet (right,result,ic);
8275 genGenPointerSet (right,result,ic);
8281 /*-----------------------------------------------------------------*/
8282 /* genIfx - generate code for Ifx statement */
8283 /*-----------------------------------------------------------------*/
8284 static void genIfx (iCode *ic, iCode *popIc)
8286 operand *cond = IC_COND(ic);
8289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8291 aopOp(cond,ic,FALSE);
8293 /* get the value into acc */
8294 if (AOP_TYPE(cond) != AOP_CRY)
8295 pic14_toBoolean(cond);
8298 /* the result is now in the accumulator */
8299 freeAsmop(cond,NULL,ic,TRUE);
8301 /* if there was something to be popped then do it */
8305 /* if the condition is a bit variable */
8306 if (isbit && IS_ITEMP(cond) &&
8308 genIfxJump(ic,SPIL_LOC(cond)->rname);
8309 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8312 if (isbit && !IS_ITEMP(cond))
8313 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8321 /*-----------------------------------------------------------------*/
8322 /* genAddrOf - generates code for address of */
8323 /*-----------------------------------------------------------------*/
8324 static void genAddrOf (iCode *ic)
8326 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8327 operand *right, *result, *left;
8328 //int size, offset ;
8330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8333 //aopOp(IC_RESULT(ic),ic,FALSE);
8335 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8336 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8337 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8340 DEBUGpic14_emitcode ("; ","result %s",
8341 AopType(AOP_TYPE(IC_RESULT(ic))));
8344 DEBUGpic14_emitcode ("; ","left %s",
8345 AopType(AOP_TYPE(IC_LEFT(ic))));
8347 DEBUGpic14_emitcode ("; ","right %s",
8348 AopType(AOP_TYPE(IC_RIGHT(ic))));
8350 emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8351 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8354 /* object not on stack then we need the name */
8355 size = AOP_SIZE(IC_RESULT(ic));
8359 char s[SDCC_NAME_MAX];
8361 sprintf(s,"#(%s >> %d)",
8365 sprintf(s,"#%s",sym->rname);
8366 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8371 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8372 freeAsmop(left,NULL,ic,FALSE);
8373 freeAsmop(result,NULL,ic,TRUE);
8378 /*-----------------------------------------------------------------*/
8379 /* genFarFarAssign - assignment when both are in far space */
8380 /*-----------------------------------------------------------------*/
8381 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8383 int size = AOP_SIZE(right);
8386 /* first push the right side on to the stack */
8388 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8390 pic14_emitcode ("push","acc");
8393 freeAsmop(right,NULL,ic,FALSE);
8394 /* now assign DPTR to result */
8395 aopOp(result,ic,FALSE);
8396 size = AOP_SIZE(result);
8398 pic14_emitcode ("pop","acc");
8399 aopPut(AOP(result),"a",--offset);
8401 freeAsmop(result,NULL,ic,FALSE);
8406 /*-----------------------------------------------------------------*/
8407 /* genAssign - generate code for assignment */
8408 /*-----------------------------------------------------------------*/
8409 static void genAssign (iCode *ic)
8411 operand *result, *right;
8412 int size, offset,know_W;
8413 unsigned long lit = 0L;
8415 result = IC_RESULT(ic);
8416 right = IC_RIGHT(ic) ;
8418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8420 /* if they are the same */
8421 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8424 aopOp(right,ic,FALSE);
8425 aopOp(result,ic,TRUE);
8427 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8428 AopType(AOP_TYPE(IC_RESULT(ic))),
8429 AopType(AOP_TYPE(IC_RIGHT(ic))),
8432 /* if they are the same registers */
8433 if (pic14_sameRegs(AOP(right),AOP(result)))
8436 /* if the result is a bit */
8437 if (AOP_TYPE(result) == AOP_CRY) {
8439 /* if the right size is a literal then
8440 we know what the value is */
8441 if (AOP_TYPE(right) == AOP_LIT) {
8443 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8444 popGet(AOP(result),0,FALSE,FALSE));
8446 if (((int) operandLitValue(right)))
8447 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8448 AOP(result)->aopu.aop_dir,
8449 AOP(result)->aopu.aop_dir);
8451 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8452 AOP(result)->aopu.aop_dir,
8453 AOP(result)->aopu.aop_dir);
8457 /* the right is also a bit variable */
8458 if (AOP_TYPE(right) == AOP_CRY) {
8459 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8460 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8461 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8463 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8464 AOP(result)->aopu.aop_dir,
8465 AOP(result)->aopu.aop_dir);
8466 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8467 AOP(right)->aopu.aop_dir,
8468 AOP(right)->aopu.aop_dir);
8469 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8470 AOP(result)->aopu.aop_dir,
8471 AOP(result)->aopu.aop_dir);
8476 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8477 pic14_toBoolean(right);
8479 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8480 //aopPut(AOP(result),"a",0);
8484 /* bit variables done */
8486 size = AOP_SIZE(result);
8488 if(AOP_TYPE(right) == AOP_LIT)
8489 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8491 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8492 if(aopIdx(AOP(result),0) == 4) {
8493 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8494 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8497 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8502 if(AOP_TYPE(right) == AOP_LIT) {
8504 if(know_W != (lit&0xff))
8505 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8507 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8509 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8513 } else if (AOP_TYPE(right) == AOP_CRY) {
8514 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8516 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8517 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8520 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8521 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8529 freeAsmop (right,NULL,ic,FALSE);
8530 freeAsmop (result,NULL,ic,TRUE);
8533 /*-----------------------------------------------------------------*/
8534 /* genJumpTab - genrates code for jump table */
8535 /*-----------------------------------------------------------------*/
8536 static void genJumpTab (iCode *ic)
8541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8543 aopOp(IC_JTCOND(ic),ic,FALSE);
8544 /* get the condition into accumulator */
8545 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8547 /* multiply by three */
8548 pic14_emitcode("add","a,acc");
8549 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8551 jtab = newiTempLabel(NULL);
8552 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8553 pic14_emitcode("jmp","@a+dptr");
8554 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8556 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8557 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8559 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8560 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8561 emitpLabel(jtab->key);
8563 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8565 /* now generate the jump labels */
8566 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8567 jtab = setNextItem(IC_JTLABELS(ic))) {
8568 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8569 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8575 /*-----------------------------------------------------------------*/
8576 /* genMixedOperation - gen code for operators between mixed types */
8577 /*-----------------------------------------------------------------*/
8579 TSD - Written for the PIC port - but this unfortunately is buggy.
8580 This routine is good in that it is able to efficiently promote
8581 types to different (larger) sizes. Unfortunately, the temporary
8582 variables that are optimized out by this routine are sometimes
8583 used in other places. So until I know how to really parse the
8584 iCode tree, I'm going to not be using this routine :(.
8586 static int genMixedOperation (iCode *ic)
8589 operand *result = IC_RESULT(ic);
8590 sym_link *ctype = operandType(IC_LEFT(ic));
8591 operand *right = IC_RIGHT(ic);
8597 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8599 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8605 nextright = IC_RIGHT(nextic);
8606 nextleft = IC_LEFT(nextic);
8607 nextresult = IC_RESULT(nextic);
8609 aopOp(right,ic,FALSE);
8610 aopOp(result,ic,FALSE);
8611 aopOp(nextright, nextic, FALSE);
8612 aopOp(nextleft, nextic, FALSE);
8613 aopOp(nextresult, nextic, FALSE);
8615 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8621 pic14_emitcode(";remove right +","");
8623 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8629 pic14_emitcode(";remove left +","");
8633 big = AOP_SIZE(nextleft);
8634 small = AOP_SIZE(nextright);
8636 switch(nextic->op) {
8639 pic14_emitcode(";optimize a +","");
8640 /* if unsigned or not an integral type */
8641 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8642 pic14_emitcode(";add a bit to something","");
8645 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8647 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8648 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8649 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8651 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8659 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8660 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8661 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8664 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8666 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8667 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8668 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8669 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8670 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8673 pic14_emitcode("rlf","known_zero,w");
8680 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8681 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8682 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8684 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8694 freeAsmop(right,NULL,ic,TRUE);
8695 freeAsmop(result,NULL,ic,TRUE);
8696 freeAsmop(nextright,NULL,ic,TRUE);
8697 freeAsmop(nextleft,NULL,ic,TRUE);
8699 nextic->generated = 1;
8706 /*-----------------------------------------------------------------*/
8707 /* genCast - gen code for casting */
8708 /*-----------------------------------------------------------------*/
8709 static void genCast (iCode *ic)
8711 operand *result = IC_RESULT(ic);
8712 sym_link *ctype = operandType(IC_LEFT(ic));
8713 operand *right = IC_RIGHT(ic);
8716 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8717 /* if they are equivalent then do nothing */
8718 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8721 aopOp(right,ic,FALSE) ;
8722 aopOp(result,ic,FALSE);
8724 /* if the result is a bit */
8725 if (AOP_TYPE(result) == AOP_CRY) {
8726 /* if the right size is a literal then
8727 we know what the value is */
8728 if (AOP_TYPE(right) == AOP_LIT) {
8730 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8731 popGet(AOP(result),0,FALSE,FALSE));
8733 if (((int) operandLitValue(right)))
8734 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8735 AOP(result)->aopu.aop_dir,
8736 AOP(result)->aopu.aop_dir);
8738 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8739 AOP(result)->aopu.aop_dir,
8740 AOP(result)->aopu.aop_dir);
8745 /* the right is also a bit variable */
8746 if (AOP_TYPE(right) == AOP_CRY) {
8749 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8751 pic14_emitcode("clrc","");
8752 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8753 AOP(right)->aopu.aop_dir,
8754 AOP(right)->aopu.aop_dir);
8755 aopPut(AOP(result),"c",0);
8760 pic14_toBoolean(right);
8761 aopPut(AOP(result),"a",0);
8765 /* if they are the same size : or less */
8766 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8768 /* if they are in the same place */
8769 if (pic14_sameRegs(AOP(right),AOP(result)))
8772 /* if they in different places then copy */
8773 size = AOP_SIZE(result);
8777 aopGet(AOP(right),offset,FALSE,FALSE),
8785 /* if the result is of type pointer */
8786 if (IS_PTR(ctype)) {
8789 sym_link *type = operandType(right);
8790 sym_link *etype = getSpec(type);
8792 /* pointer to generic pointer */
8793 if (IS_GENPTR(ctype)) {
8797 p_type = DCL_TYPE(type);
8799 /* we have to go by the storage class */
8800 p_type = PTR_TYPE(SPEC_OCLS(etype));
8802 /* if (SPEC_OCLS(etype)->codesp ) */
8803 /* p_type = CPOINTER ; */
8805 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8806 /* p_type = FPOINTER ; */
8808 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8809 /* p_type = PPOINTER; */
8811 /* if (SPEC_OCLS(etype) == idata ) */
8812 /* p_type = IPOINTER ; */
8814 /* p_type = POINTER ; */
8817 /* the first two bytes are known */
8818 size = GPTRSIZE - 1;
8822 aopGet(AOP(right),offset,FALSE,FALSE),
8826 /* the last byte depending on type */
8843 /* this should never happen */
8844 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8845 "got unknown pointer type");
8848 aopPut(AOP(result),l, GPTRSIZE - 1);
8852 /* just copy the pointers */
8853 size = AOP_SIZE(result);
8857 aopGet(AOP(right),offset,FALSE,FALSE),
8865 if (AOP_TYPE(right) == AOP_CRY) {
8867 size = AOP_SIZE(right);
8869 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8870 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8871 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8873 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8874 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8875 AOP(right)->aopu.aop_dir,
8876 AOP(right)->aopu.aop_dir);
8877 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8879 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8880 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8885 /* so we now know that the size of destination is greater
8886 than the size of the source.
8887 Now, if the next iCode is an operator then we might be
8888 able to optimize the operation without performing a cast.
8890 if(genMixedOperation(ic))
8894 /* we move to result for the size of source */
8895 size = AOP_SIZE(right);
8898 pic14_emitcode(";","%d",__LINE__);
8899 /* aopPut(AOP(result),
8900 aopGet(AOP(right),offset,FALSE,FALSE),
8902 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8903 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8907 /* now depending on the sign of the destination */
8908 size = AOP_SIZE(result) - AOP_SIZE(right);
8909 /* if unsigned or not an integral type */
8910 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8912 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8913 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8917 /* we need to extend the sign :{ */
8919 emitpcodeNULLop(POC_CLRW);
8922 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8924 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8926 emitpcode(POC_MOVLW, popGetLit(0xff));
8928 pic14_emitcode("clrw","");
8929 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8930 AOP(right)->aopu.aop_dir,
8931 AOP(right)->aopu.aop_dir);
8932 pic14_emitcode("movlw","0xff");
8934 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8935 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8937 // aopPut(AOP(result),"a",offset++);
8942 /* we are done hurray !!!! */
8945 freeAsmop(right,NULL,ic,TRUE);
8946 freeAsmop(result,NULL,ic,TRUE);
8950 /*-----------------------------------------------------------------*/
8951 /* genDjnz - generate decrement & jump if not zero instrucion */
8952 /*-----------------------------------------------------------------*/
8953 static int genDjnz (iCode *ic, iCode *ifx)
8956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8961 /* if the if condition has a false label
8962 then we cannot save */
8966 /* if the minus is not of the form
8968 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8969 !IS_OP_LITERAL(IC_RIGHT(ic)))
8972 if (operandLitValue(IC_RIGHT(ic)) != 1)
8975 /* if the size of this greater than one then no
8977 if (getSize(operandType(IC_RESULT(ic))) > 1)
8980 /* otherwise we can save BIG */
8981 lbl = newiTempLabel(NULL);
8982 lbl1= newiTempLabel(NULL);
8984 aopOp(IC_RESULT(ic),ic,FALSE);
8986 if (IS_AOP_PREG(IC_RESULT(ic))) {
8987 pic14_emitcode("dec","%s",
8988 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8989 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8990 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8994 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8995 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8997 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8998 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9001 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9002 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9003 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9004 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9007 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9012 /*-----------------------------------------------------------------*/
9013 /* genReceive - generate code for a receive iCode */
9014 /*-----------------------------------------------------------------*/
9015 static void genReceive (iCode *ic)
9017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9019 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9020 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9021 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9023 int size = getSize(operandType(IC_RESULT(ic)));
9024 int offset = fReturnSizePic - size;
9026 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9027 fReturn[fReturnSizePic - offset - 1] : "acc"));
9030 aopOp(IC_RESULT(ic),ic,FALSE);
9031 size = AOP_SIZE(IC_RESULT(ic));
9034 pic14_emitcode ("pop","acc");
9035 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9040 aopOp(IC_RESULT(ic),ic,FALSE);
9042 assignResultValue(IC_RESULT(ic));
9045 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9048 /*-----------------------------------------------------------------*/
9049 /* genpic14Code - generate code for pic14 based controllers */
9050 /*-----------------------------------------------------------------*/
9052 * At this point, ralloc.c has gone through the iCode and attempted
9053 * to optimize in a way suitable for a PIC. Now we've got to generate
9054 * PIC instructions that correspond to the iCode.
9056 * Once the instructions are generated, we'll pass through both the
9057 * peep hole optimizer and the pCode optimizer.
9058 *-----------------------------------------------------------------*/
9060 void genpic14Code (iCode *lic)
9065 lineHead = lineCurr = NULL;
9067 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9070 /* if debug information required */
9071 /* if (options.debug && currFunc) { */
9073 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9075 if (IS_STATIC(currFunc->etype)) {
9076 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9077 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9079 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9080 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9086 for (ic = lic ; ic ; ic = ic->next ) {
9088 DEBUGpic14_emitcode(";ic","");
9089 if ( cln != ic->lineno ) {
9090 if ( options.debug ) {
9092 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9093 FileBaseName(ic->filename),ic->lineno,
9094 ic->level,ic->block);
9097 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9100 /* if the result is marked as
9101 spilt and rematerializable or code for
9102 this has already been generated then
9104 if (resultRemat(ic) || ic->generated )
9107 /* depending on the operation */
9126 /* IPOP happens only when trying to restore a
9127 spilt live range, if there is an ifx statement
9128 following this pop then the if statement might
9129 be using some of the registers being popped which
9130 would destory the contents of the register so
9131 we need to check for this condition and handle it */
9133 ic->next->op == IFX &&
9134 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9135 genIfx (ic->next,ic);
9153 genEndFunction (ic);
9173 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9190 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9194 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9201 /* note these two are xlated by algebraic equivalence
9202 during parsing SDCC.y */
9203 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9204 "got '>=' or '<=' shouldn't have come here");
9208 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9220 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9224 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9228 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9255 case GET_VALUE_AT_ADDRESS:
9260 if (POINTER_SET(ic))
9287 addSet(&_G.sendSet,ic);
9296 /* now we are ready to call the
9297 peep hole optimizer */
9298 if (!options.nopeep) {
9299 printf("peep hole optimizing\n");
9300 peepHole (&lineHead);
9302 /* now do the actual printing */
9303 printLine (lineHead,codeOutFile);
9305 printf("printing pBlock\n\n");
9306 printpBlock(stdout,pb);