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 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5248 if (IS_AOP_PREG(left)) {
5249 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5250 aopPut(AOP(result),"a",offset);
5252 pic14_emitcode("xrl","%s,a",
5253 aopGet(AOP(left),offset,FALSE,TRUE));
5258 // left & result in different registers
5259 if(AOP_TYPE(result) == AOP_CRY){
5261 // if(size), result in bit
5262 // if(!size && ifx), conditional oper: if(left ^ right)
5263 symbol *tlbl = newiTempLabel(NULL);
5264 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5266 pic14_emitcode("setb","c");
5268 if((AOP_TYPE(right) == AOP_LIT) &&
5269 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5270 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5272 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5273 pic14_emitcode("xrl","a,%s",
5274 aopGet(AOP(left),offset,FALSE,FALSE));
5276 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5281 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5282 pic14_outBitC(result);
5284 jmpTrueOrFalse(ifx, tlbl);
5285 } else for(;(size--);offset++){
5287 // result = left & right
5288 if(AOP_TYPE(right) == AOP_LIT){
5289 int t = (lit >> (offset*8)) & 0x0FFL;
5292 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5293 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5294 pic14_emitcode("movf","%s,w",
5295 aopGet(AOP(left),offset,FALSE,FALSE));
5296 pic14_emitcode("movwf","%s",
5297 aopGet(AOP(result),offset,FALSE,FALSE));
5300 emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5301 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5302 pic14_emitcode("comf","%s,w",
5303 aopGet(AOP(left),offset,FALSE,FALSE));
5304 pic14_emitcode("movwf","%s",
5305 aopGet(AOP(result),offset,FALSE,FALSE));
5308 emitpcode(POC_MOVLW, popGetLit(t));
5309 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5310 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5311 pic14_emitcode("movlw","0x%x",t);
5312 pic14_emitcode("xorwf","%s,w",
5313 aopGet(AOP(left),offset,FALSE,FALSE));
5314 pic14_emitcode("movwf","%s",
5315 aopGet(AOP(result),offset,FALSE,FALSE));
5321 // faster than result <- left, anl result,right
5322 // and better if result is SFR
5323 if (AOP_TYPE(left) == AOP_ACC) {
5324 emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5325 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5327 emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5328 emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5329 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5330 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5332 if ( AOP_TYPE(result) != AOP_ACC){
5333 emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5334 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5340 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5341 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5342 freeAsmop(result,NULL,ic,TRUE);
5345 /*-----------------------------------------------------------------*/
5346 /* genInline - write the inline code out */
5347 /*-----------------------------------------------------------------*/
5348 static void genInline (iCode *ic)
5350 char *buffer, *bp, *bp1;
5352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5354 _G.inLine += (!options.asmpeep);
5356 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5357 strcpy(buffer,IC_INLINE(ic));
5359 /* emit each line as a code */
5363 pic14_emitcode(bp1,"");
5370 pic14_emitcode(bp1,"");
5377 pic14_emitcode(bp1,"");
5378 /* pic14_emitcode("",buffer); */
5379 _G.inLine -= (!options.asmpeep);
5382 /*-----------------------------------------------------------------*/
5383 /* genRRC - rotate right with carry */
5384 /*-----------------------------------------------------------------*/
5385 static void genRRC (iCode *ic)
5387 operand *left , *result ;
5388 int size, offset = 0;
5391 /* rotate right with carry */
5393 result=IC_RESULT(ic);
5394 aopOp (left,ic,FALSE);
5395 aopOp (result,ic,FALSE);
5397 /* move it to the result */
5398 size = AOP_SIZE(result);
5402 l = aopGet(AOP(left),offset,FALSE,FALSE);
5404 pic14_emitcode("rrc","a");
5405 if (AOP_SIZE(result) > 1)
5406 aopPut(AOP(result),"a",offset--);
5408 /* now we need to put the carry into the
5409 highest order byte of the result */
5410 if (AOP_SIZE(result) > 1) {
5411 l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5414 pic14_emitcode("mov","acc.7,c");
5415 aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5416 freeAsmop(left,NULL,ic,TRUE);
5417 freeAsmop(result,NULL,ic,TRUE);
5420 /*-----------------------------------------------------------------*/
5421 /* genRLC - generate code for rotate left with carry */
5422 /*-----------------------------------------------------------------*/
5423 static void genRLC (iCode *ic)
5425 operand *left , *result ;
5426 int size, offset = 0;
5429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5430 /* rotate right with carry */
5432 result=IC_RESULT(ic);
5433 aopOp (left,ic,FALSE);
5434 aopOp (result,ic,FALSE);
5436 /* move it to the result */
5437 size = AOP_SIZE(result);
5440 l = aopGet(AOP(left),offset,FALSE,FALSE);
5442 pic14_emitcode("add","a,acc");
5443 if (AOP_SIZE(result) > 1)
5444 aopPut(AOP(result),"a",offset++);
5446 l = aopGet(AOP(left),offset,FALSE,FALSE);
5448 pic14_emitcode("rlc","a");
5449 if (AOP_SIZE(result) > 1)
5450 aopPut(AOP(result),"a",offset++);
5453 /* now we need to put the carry into the
5454 highest order byte of the result */
5455 if (AOP_SIZE(result) > 1) {
5456 l = aopGet(AOP(result),0,FALSE,FALSE);
5459 pic14_emitcode("mov","acc.0,c");
5460 aopPut(AOP(result),"a",0);
5461 freeAsmop(left,NULL,ic,TRUE);
5462 freeAsmop(result,NULL,ic,TRUE);
5465 /*-----------------------------------------------------------------*/
5466 /* genGetHbit - generates code get highest order bit */
5467 /*-----------------------------------------------------------------*/
5468 static void genGetHbit (iCode *ic)
5470 operand *left, *result;
5472 result=IC_RESULT(ic);
5473 aopOp (left,ic,FALSE);
5474 aopOp (result,ic,FALSE);
5476 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5477 /* get the highest order byte into a */
5478 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5479 if(AOP_TYPE(result) == AOP_CRY){
5480 pic14_emitcode("rlc","a");
5481 pic14_outBitC(result);
5484 pic14_emitcode("rl","a");
5485 pic14_emitcode("anl","a,#0x01");
5486 pic14_outAcc(result);
5490 freeAsmop(left,NULL,ic,TRUE);
5491 freeAsmop(result,NULL,ic,TRUE);
5494 /*-----------------------------------------------------------------*/
5495 /* AccRol - rotate left accumulator by known count */
5496 /*-----------------------------------------------------------------*/
5497 static void AccRol (int shCount)
5499 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5500 shCount &= 0x0007; // shCount : 0..7
5505 pic14_emitcode("rl","a");
5508 pic14_emitcode("rl","a");
5509 pic14_emitcode("rl","a");
5512 pic14_emitcode("swap","a");
5513 pic14_emitcode("rr","a");
5516 pic14_emitcode("swap","a");
5519 pic14_emitcode("swap","a");
5520 pic14_emitcode("rl","a");
5523 pic14_emitcode("rr","a");
5524 pic14_emitcode("rr","a");
5527 pic14_emitcode("rr","a");
5532 /*-----------------------------------------------------------------*/
5533 /* AccLsh - left shift accumulator by known count */
5534 /*-----------------------------------------------------------------*/
5535 static void AccLsh (int shCount)
5537 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5540 pic14_emitcode("add","a,acc");
5543 pic14_emitcode("add","a,acc");
5544 pic14_emitcode("add","a,acc");
5546 /* rotate left accumulator */
5548 /* and kill the lower order bits */
5549 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5554 /*-----------------------------------------------------------------*/
5555 /* AccRsh - right shift accumulator by known count */
5556 /*-----------------------------------------------------------------*/
5557 static void AccRsh (int shCount)
5559 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5563 pic14_emitcode("rrc","a");
5565 /* rotate right accumulator */
5566 AccRol(8 - shCount);
5567 /* and kill the higher order bits */
5568 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5574 /*-----------------------------------------------------------------*/
5575 /* AccSRsh - signed right shift accumulator by known count */
5576 /*-----------------------------------------------------------------*/
5577 static void AccSRsh (int shCount)
5580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5583 pic14_emitcode("mov","c,acc.7");
5584 pic14_emitcode("rrc","a");
5585 } else if(shCount == 2){
5586 pic14_emitcode("mov","c,acc.7");
5587 pic14_emitcode("rrc","a");
5588 pic14_emitcode("mov","c,acc.7");
5589 pic14_emitcode("rrc","a");
5591 tlbl = newiTempLabel(NULL);
5592 /* rotate right accumulator */
5593 AccRol(8 - shCount);
5594 /* and kill the higher order bits */
5595 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5596 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5597 pic14_emitcode("orl","a,#0x%02x",
5598 (unsigned char)~SRMask[shCount]);
5599 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5604 /*-----------------------------------------------------------------*/
5605 /* shiftR1Left2Result - shift right one byte from left to result */
5606 /*-----------------------------------------------------------------*/
5607 static void shiftR1Left2ResultSigned (operand *left, int offl,
5608 operand *result, int offr,
5613 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5615 same = (left == result) || (AOP(left) == AOP(result));
5619 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5621 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5623 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5624 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5634 /*-----------------------------------------------------------------*/
5635 /* shiftR1Left2Result - shift right one byte from left to result */
5636 /*-----------------------------------------------------------------*/
5637 static void shiftR1Left2Result (operand *left, int offl,
5638 operand *result, int offr,
5639 int shCount, int sign)
5643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5645 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5647 /* Copy the msb into the carry if signed. */
5649 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5659 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5661 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5662 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5668 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5670 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5671 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5674 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5679 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5681 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5682 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5685 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5686 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
5687 emitpcode(POC_ANDLW, popGetLit(0x1f));
5688 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5692 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5693 emitpcode(POC_ANDLW, popGetLit(0x0f));
5694 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5698 emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5699 emitpcode(POC_ANDLW, popGetLit(0x0f));
5700 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5702 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5707 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5708 emitpcode(POC_ANDLW, popGetLit(0x80));
5709 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5710 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5711 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5716 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5717 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5718 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5729 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5731 /* shift right accumulator */
5736 aopPut(AOP(result),"a",offr);
5740 /*-----------------------------------------------------------------*/
5741 /* shiftL1Left2Result - shift left one byte from left to result */
5742 /*-----------------------------------------------------------------*/
5743 static void shiftL1Left2Result (operand *left, int offl,
5744 operand *result, int offr, int shCount)
5749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5751 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5752 DEBUGpic14_emitcode ("; ***","same = %d",same);
5753 // l = aopGet(AOP(left),offl,FALSE,FALSE);
5755 /* shift left accumulator */
5756 //AccLsh(shCount); // don't comment out just yet...
5757 // aopPut(AOP(result),"a",offr);
5761 /* Shift left 1 bit position */
5762 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5764 emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5766 emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5767 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5771 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5772 emitpcode(POC_ANDLW,popGetLit(0x7e));
5773 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5774 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5777 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5778 emitpcode(POC_ANDLW,popGetLit(0x3e));
5779 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5780 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5781 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5784 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5785 emitpcode(POC_ANDLW, popGetLit(0xf0));
5786 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5789 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5790 emitpcode(POC_ANDLW, popGetLit(0xf0));
5791 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5792 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5795 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5796 emitpcode(POC_ANDLW, popGetLit(0x30));
5797 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5798 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5799 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
5802 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5803 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5804 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5808 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5813 /*-----------------------------------------------------------------*/
5814 /* movLeft2Result - move byte from left to result */
5815 /*-----------------------------------------------------------------*/
5816 static void movLeft2Result (operand *left, int offl,
5817 operand *result, int offr, int sign)
5820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5821 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5822 l = aopGet(AOP(left),offl,FALSE,FALSE);
5824 if (*l == '@' && (IS_AOP_PREG(result))) {
5825 pic14_emitcode("mov","a,%s",l);
5826 aopPut(AOP(result),"a",offr);
5829 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5830 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5832 //aopPut(AOP(result),l,offr);
5834 /* MSB sign in acc.7 ! */
5835 if(pic14_getDataSize(left) == offl+1){
5836 pic14_emitcode("mov","a,%s",l);
5837 aopPut(AOP(result),"a",offr);
5844 /*-----------------------------------------------------------------*/
5845 /* AccAXRrl1 - right rotate c->a:x->c by 1 */
5846 /*-----------------------------------------------------------------*/
5847 static void AccAXRrl1 (char *x)
5849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5850 pic14_emitcode("rrc","a");
5851 pic14_emitcode("xch","a,%s", x);
5852 pic14_emitcode("rrc","a");
5853 pic14_emitcode("xch","a,%s", x);
5856 /*-----------------------------------------------------------------*/
5857 /* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
5858 /*-----------------------------------------------------------------*/
5859 static void AccAXLrl1 (char *x)
5861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5862 pic14_emitcode("xch","a,%s",x);
5863 pic14_emitcode("rlc","a");
5864 pic14_emitcode("xch","a,%s",x);
5865 pic14_emitcode("rlc","a");
5868 /*-----------------------------------------------------------------*/
5869 /* AccAXLsh1 - left shift a:x<-0 by 1 */
5870 /*-----------------------------------------------------------------*/
5871 static void AccAXLsh1 (char *x)
5873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5874 pic14_emitcode("xch","a,%s",x);
5875 pic14_emitcode("add","a,acc");
5876 pic14_emitcode("xch","a,%s",x);
5877 pic14_emitcode("rlc","a");
5881 /*-----------------------------------------------------------------*/
5882 /* AccAXLsh - left shift a:x by known count (0..7) */
5883 /*-----------------------------------------------------------------*/
5884 static void AccAXLsh (char *x, int shCount)
5886 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5899 case 5 : // AAAAABBB:CCCCCDDD
5900 AccRol(shCount); // BBBAAAAA:CCCCCDDD
5901 pic14_emitcode("anl","a,#0x%02x",
5902 SLMask[shCount]); // BBB00000:CCCCCDDD
5903 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBB00000
5904 AccRol(shCount); // DDDCCCCC:BBB00000
5905 pic14_emitcode("xch","a,%s",x); // BBB00000:DDDCCCCC
5906 pic14_emitcode("xrl","a,%s",x); // (BBB^DDD)CCCCC:DDDCCCCC
5907 pic14_emitcode("xch","a,%s",x); // DDDCCCCC:(BBB^DDD)CCCCC
5908 pic14_emitcode("anl","a,#0x%02x",
5909 SLMask[shCount]); // DDD00000:(BBB^DDD)CCCCC
5910 pic14_emitcode("xch","a,%s",x); // (BBB^DDD)CCCCC:DDD00000
5911 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:DDD00000
5913 case 6 : // AAAAAABB:CCCCCCDD
5914 pic14_emitcode("anl","a,#0x%02x",
5915 SRMask[shCount]); // 000000BB:CCCCCCDD
5916 pic14_emitcode("mov","c,acc.0"); // c = B
5917 pic14_emitcode("xch","a,%s",x); // CCCCCCDD:000000BB
5918 AccAXRrl1(x); // BCCCCCCD:D000000B
5919 AccAXRrl1(x); // BBCCCCCC:DD000000
5921 case 7 : // a:x <<= 7
5922 pic14_emitcode("anl","a,#0x%02x",
5923 SRMask[shCount]); // 0000000B:CCCCCCCD
5924 pic14_emitcode("mov","c,acc.0"); // c = B
5925 pic14_emitcode("xch","a,%s",x); // CCCCCCCD:0000000B
5926 AccAXRrl1(x); // BCCCCCCC:D0000000
5934 /*-----------------------------------------------------------------*/
5935 /* AccAXRsh - right shift a:x known count (0..7) */
5936 /*-----------------------------------------------------------------*/
5937 static void AccAXRsh (char *x, int shCount)
5939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5945 AccAXRrl1(x); // 0->a:x
5949 AccAXRrl1(x); // 0->a:x
5951 AccAXRrl1(x); // 0->a:x
5955 case 5 : // AAAAABBB:CCCCCDDD = a:x
5956 AccRol(8 - shCount); // BBBAAAAA:DDDCCCCC
5957 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
5958 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
5959 pic14_emitcode("anl","a,#0x%02x",
5960 SRMask[shCount]); // 000CCCCC:BBBAAAAA
5961 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
5962 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
5963 pic14_emitcode("anl","a,#0x%02x",
5964 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
5965 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
5966 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
5967 pic14_emitcode("xch","a,%s",x); // 000AAAAA:BBBCCCCC
5969 case 6 : // AABBBBBB:CCDDDDDD
5970 pic14_emitcode("mov","c,acc.7");
5971 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
5972 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
5973 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
5974 pic14_emitcode("anl","a,#0x%02x",
5975 SRMask[shCount]); // 000000AA:BBBBBBCC
5977 case 7 : // ABBBBBBB:CDDDDDDD
5978 pic14_emitcode("mov","c,acc.7"); // c = A
5979 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
5980 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
5981 pic14_emitcode("anl","a,#0x%02x",
5982 SRMask[shCount]); // 0000000A:BBBBBBBC
5989 /*-----------------------------------------------------------------*/
5990 /* AccAXRshS - right shift signed a:x known count (0..7) */
5991 /*-----------------------------------------------------------------*/
5992 static void AccAXRshS (char *x, int shCount)
5995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6000 pic14_emitcode("mov","c,acc.7");
6001 AccAXRrl1(x); // s->a:x
6004 pic14_emitcode("mov","c,acc.7");
6005 AccAXRrl1(x); // s->a:x
6006 pic14_emitcode("mov","c,acc.7");
6007 AccAXRrl1(x); // s->a:x
6011 case 5 : // AAAAABBB:CCCCCDDD = a:x
6012 tlbl = newiTempLabel(NULL);
6013 AccRol(8 - shCount); // BBBAAAAA:CCCCCDDD
6014 pic14_emitcode("xch","a,%s",x); // CCCCCDDD:BBBAAAAA
6015 AccRol(8 - shCount); // DDDCCCCC:BBBAAAAA
6016 pic14_emitcode("anl","a,#0x%02x",
6017 SRMask[shCount]); // 000CCCCC:BBBAAAAA
6018 pic14_emitcode("xrl","a,%s",x); // BBB(CCCCC^AAAAA):BBBAAAAA
6019 pic14_emitcode("xch","a,%s",x); // BBBAAAAA:BBB(CCCCC^AAAAA)
6020 pic14_emitcode("anl","a,#0x%02x",
6021 SRMask[shCount]); // 000AAAAA:BBB(CCCCC^AAAAA)
6022 pic14_emitcode("xch","a,%s",x); // BBB(CCCCC^AAAAA):000AAAAA
6023 pic14_emitcode("xrl","a,%s",x); // BBBCCCCC:000AAAAA
6024 pic14_emitcode("xch","a,%s",x); // 000SAAAA:BBBCCCCC
6025 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6026 pic14_emitcode("orl","a,#0x%02x",
6027 (unsigned char)~SRMask[shCount]); // 111AAAAA:BBBCCCCC
6028 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6029 break; // SSSSAAAA:BBBCCCCC
6030 case 6 : // AABBBBBB:CCDDDDDD
6031 tlbl = newiTempLabel(NULL);
6032 pic14_emitcode("mov","c,acc.7");
6033 AccAXLrl1(x); // ABBBBBBC:CDDDDDDA
6034 AccAXLrl1(x); // BBBBBBCC:DDDDDDAA
6035 pic14_emitcode("xch","a,%s",x); // DDDDDDAA:BBBBBBCC
6036 pic14_emitcode("anl","a,#0x%02x",
6037 SRMask[shCount]); // 000000AA:BBBBBBCC
6038 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6039 pic14_emitcode("orl","a,#0x%02x",
6040 (unsigned char)~SRMask[shCount]); // 111111AA:BBBBBBCC
6041 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6043 case 7 : // ABBBBBBB:CDDDDDDD
6044 tlbl = newiTempLabel(NULL);
6045 pic14_emitcode("mov","c,acc.7"); // c = A
6046 AccAXLrl1(x); // BBBBBBBC:DDDDDDDA
6047 pic14_emitcode("xch","a,%s",x); // DDDDDDDA:BBBBBBCC
6048 pic14_emitcode("anl","a,#0x%02x",
6049 SRMask[shCount]); // 0000000A:BBBBBBBC
6050 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6051 pic14_emitcode("orl","a,#0x%02x",
6052 (unsigned char)~SRMask[shCount]); // 1111111A:BBBBBBBC
6053 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6060 /*-----------------------------------------------------------------*/
6061 /* shiftL2Left2Result - shift left two bytes from left to result */
6062 /*-----------------------------------------------------------------*/
6063 static void shiftL2Left2Result (operand *left, int offl,
6064 operand *result, int offr, int shCount)
6068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6070 if(pic14_sameRegs(AOP(result), AOP(left))) {
6078 emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6079 emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6080 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6084 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6085 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6091 emitpcode(POC_MOVLW, popGetLit(0x0f));
6092 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6093 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6094 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6095 emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6096 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6097 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6099 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6100 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6104 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6105 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6106 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6107 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6108 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6109 emitpcode(POC_ANDLW,popGetLit(0xc0));
6110 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6111 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6112 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6113 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6116 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6117 emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6118 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6119 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6120 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6130 /* note, use a mov/add for the shift since the mov has a
6131 chance of getting optimized out */
6132 emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6133 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6134 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6135 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6136 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6140 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6141 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6147 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6148 emitpcode(POC_ANDLW, popGetLit(0xF0));
6149 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6150 emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6151 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6152 emitpcode(POC_ANDLW, popGetLit(0xF0));
6153 emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6154 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6158 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6159 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6163 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6164 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6165 emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6166 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6168 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6169 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6170 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6171 emitpcode(POC_ANDLW,popGetLit(0xc0));
6172 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6173 emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6174 emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6175 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6178 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6179 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6180 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6181 emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6182 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6187 /*-----------------------------------------------------------------*/
6188 /* shiftR2Left2Result - shift right two bytes from left to result */
6189 /*-----------------------------------------------------------------*/
6190 static void shiftR2Left2Result (operand *left, int offl,
6191 operand *result, int offr,
6192 int shCount, int sign)
6196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 same = pic14_sameRegs(AOP(result), AOP(left));
6199 if(same && ((offl + MSB16) == offr)){
6201 /* don't crash result[offr] */
6202 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6203 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6205 movLeft2Result(left,offl, result, offr, 0);
6206 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6208 /* a:x >> shCount (x = lsb(result))*/
6210 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6212 //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6222 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6223 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6226 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6227 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6228 emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6229 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6234 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6235 emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6242 emitpcode(POC_MOVLW, popGetLit(0xf0));
6243 emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6244 emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6246 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6247 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6248 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6249 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6251 emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6252 emitpcode(POC_ANDLW, popGetLit(0x0f));
6253 emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6255 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6256 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6257 emitpcode(POC_ANDLW, popGetLit(0xf0));
6258 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6259 emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6263 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6264 emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6272 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6273 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6275 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6276 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6277 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6278 emitpcode(POC_ANDLW,popGetLit(0x03));
6279 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6280 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6281 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6282 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6284 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6285 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6286 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6287 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6288 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6289 emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6290 emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6291 emitpcode(POC_ANDLW,popGetLit(0x03));
6292 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6297 emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6298 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6299 emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6300 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6301 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6306 /*-----------------------------------------------------------------*/
6307 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6308 /*-----------------------------------------------------------------*/
6309 static void shiftLLeftOrResult (operand *left, int offl,
6310 operand *result, int offr, int shCount)
6312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6313 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6314 /* shift left accumulator */
6316 /* or with result */
6317 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6318 /* back to result */
6319 aopPut(AOP(result),"a",offr);
6322 /*-----------------------------------------------------------------*/
6323 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6324 /*-----------------------------------------------------------------*/
6325 static void shiftRLeftOrResult (operand *left, int offl,
6326 operand *result, int offr, int shCount)
6328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6329 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6330 /* shift right accumulator */
6332 /* or with result */
6333 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6334 /* back to result */
6335 aopPut(AOP(result),"a",offr);
6338 /*-----------------------------------------------------------------*/
6339 /* genlshOne - left shift a one byte quantity by known count */
6340 /*-----------------------------------------------------------------*/
6341 static void genlshOne (operand *result, operand *left, int shCount)
6343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6344 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6347 /*-----------------------------------------------------------------*/
6348 /* genlshTwo - left shift two bytes by known amount != 0 */
6349 /*-----------------------------------------------------------------*/
6350 static void genlshTwo (operand *result,operand *left, int shCount)
6354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6355 size = pic14_getDataSize(result);
6357 /* if shCount >= 8 */
6363 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6365 movLeft2Result(left, LSB, result, MSB16, 0);
6367 emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6370 /* 1 <= shCount <= 7 */
6373 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6375 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6379 /*-----------------------------------------------------------------*/
6380 /* shiftLLong - shift left one long from left to result */
6381 /* offl = LSB or MSB16 */
6382 /*-----------------------------------------------------------------*/
6383 static void shiftLLong (operand *left, operand *result, int offr )
6386 int size = AOP_SIZE(result);
6388 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6389 if(size >= LSB+offr){
6390 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6392 pic14_emitcode("add","a,acc");
6393 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6394 size >= MSB16+offr && offr != LSB )
6395 pic14_emitcode("xch","a,%s",
6396 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6398 aopPut(AOP(result),"a",LSB+offr);
6401 if(size >= MSB16+offr){
6402 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6403 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6406 pic14_emitcode("rlc","a");
6407 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6408 size >= MSB24+offr && offr != LSB)
6409 pic14_emitcode("xch","a,%s",
6410 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6412 aopPut(AOP(result),"a",MSB16+offr);
6415 if(size >= MSB24+offr){
6416 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6417 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6420 pic14_emitcode("rlc","a");
6421 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6422 size >= MSB32+offr && offr != LSB )
6423 pic14_emitcode("xch","a,%s",
6424 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6426 aopPut(AOP(result),"a",MSB24+offr);
6429 if(size > MSB32+offr){
6430 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6431 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6434 pic14_emitcode("rlc","a");
6435 aopPut(AOP(result),"a",MSB32+offr);
6438 aopPut(AOP(result),zero,LSB);
6441 /*-----------------------------------------------------------------*/
6442 /* genlshFour - shift four byte by a known amount != 0 */
6443 /*-----------------------------------------------------------------*/
6444 static void genlshFour (operand *result, operand *left, int shCount)
6448 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6449 size = AOP_SIZE(result);
6451 /* if shifting more that 3 bytes */
6452 if (shCount >= 24 ) {
6455 /* lowest order of left goes to the highest
6456 order of the destination */
6457 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6459 movLeft2Result(left, LSB, result, MSB32, 0);
6460 aopPut(AOP(result),zero,LSB);
6461 aopPut(AOP(result),zero,MSB16);
6462 aopPut(AOP(result),zero,MSB32);
6466 /* more than two bytes */
6467 else if ( shCount >= 16 ) {
6468 /* lower order two bytes goes to higher order two bytes */
6470 /* if some more remaining */
6472 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6474 movLeft2Result(left, MSB16, result, MSB32, 0);
6475 movLeft2Result(left, LSB, result, MSB24, 0);
6477 aopPut(AOP(result),zero,MSB16);
6478 aopPut(AOP(result),zero,LSB);
6482 /* if more than 1 byte */
6483 else if ( shCount >= 8 ) {
6484 /* lower order three bytes goes to higher order three bytes */
6488 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6490 movLeft2Result(left, LSB, result, MSB16, 0);
6492 else{ /* size = 4 */
6494 movLeft2Result(left, MSB24, result, MSB32, 0);
6495 movLeft2Result(left, MSB16, result, MSB24, 0);
6496 movLeft2Result(left, LSB, result, MSB16, 0);
6497 aopPut(AOP(result),zero,LSB);
6499 else if(shCount == 1)
6500 shiftLLong(left, result, MSB16);
6502 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6503 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6504 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6505 aopPut(AOP(result),zero,LSB);
6510 /* 1 <= shCount <= 7 */
6511 else if(shCount <= 2){
6512 shiftLLong(left, result, LSB);
6514 shiftLLong(result, result, LSB);
6516 /* 3 <= shCount <= 7, optimize */
6518 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6519 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6520 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6524 /*-----------------------------------------------------------------*/
6525 /* genLeftShiftLiteral - left shifting by known count */
6526 /*-----------------------------------------------------------------*/
6527 static void genLeftShiftLiteral (operand *left,
6532 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6536 freeAsmop(right,NULL,ic,TRUE);
6538 aopOp(left,ic,FALSE);
6539 aopOp(result,ic,FALSE);
6541 size = getSize(operandType(result));
6544 pic14_emitcode("; shift left ","result %d, left %d",size,
6548 /* I suppose that the left size >= result size */
6551 movLeft2Result(left, size, result, size, 0);
6555 else if(shCount >= (size * 8))
6557 aopPut(AOP(result),zero,size);
6561 genlshOne (result,left,shCount);
6566 genlshTwo (result,left,shCount);
6570 genlshFour (result,left,shCount);
6574 freeAsmop(left,NULL,ic,TRUE);
6575 freeAsmop(result,NULL,ic,TRUE);
6578 /*-----------------------------------------------------------------*/
6579 /* genLeftShift - generates code for left shifting */
6580 /*-----------------------------------------------------------------*/
6581 static void genLeftShift (iCode *ic)
6583 operand *left,*right, *result;
6586 symbol *tlbl , *tlbl1;
6588 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6590 right = IC_RIGHT(ic);
6592 result = IC_RESULT(ic);
6594 aopOp(right,ic,FALSE);
6596 /* if the shift count is known then do it
6597 as efficiently as possible */
6598 if (AOP_TYPE(right) == AOP_LIT) {
6599 genLeftShiftLiteral (left,right,result,ic);
6603 /* shift count is unknown then we have to form
6604 a loop get the loop count in B : Note: we take
6605 only the lower order byte since shifting
6606 more that 32 bits make no sense anyway, ( the
6607 largest size of an object can be only 32 bits ) */
6610 aopOp(left,ic,FALSE);
6611 aopOp(result,ic,FALSE);
6613 /* now move the left to the result if they are not the
6615 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6616 AOP_SIZE(result) > 1) {
6618 size = AOP_SIZE(result);
6621 l = aopGet(AOP(left),offset,FALSE,TRUE);
6622 if (*l == '@' && (IS_AOP_PREG(result))) {
6624 pic14_emitcode("mov","a,%s",l);
6625 aopPut(AOP(result),"a",offset);
6627 aopPut(AOP(result),l,offset);
6632 size = AOP_SIZE(result);
6634 /* if it is only one byte then */
6636 if(optimized_for_speed) {
6637 emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6638 emitpcode(POC_ANDLW, popGetLit(0xf0));
6639 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6640 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6641 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6642 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6643 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6644 emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE));
6645 emitpcode(POC_ANDLW, popGetLit(0xfe));
6646 emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE));
6647 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6648 emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
6651 tlbl = newiTempLabel(NULL);
6652 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6653 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
6654 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
6657 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
6658 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
6659 emitpLabel(tlbl->key);
6660 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
6661 emitpcode(POC_ADDLW, popGetLit(1));
6663 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6669 tlbl = newiTempLabel(NULL);
6671 tlbl1 = newiTempLabel(NULL);
6673 reAdjustPreg(AOP(result));
6675 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6676 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6677 l = aopGet(AOP(result),offset,FALSE,FALSE);
6679 pic14_emitcode("add","a,acc");
6680 aopPut(AOP(result),"a",offset++);
6682 l = aopGet(AOP(result),offset,FALSE,FALSE);
6684 pic14_emitcode("rlc","a");
6685 aopPut(AOP(result),"a",offset++);
6687 reAdjustPreg(AOP(result));
6689 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6690 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6692 freeAsmop (right,NULL,ic,TRUE);
6693 freeAsmop(left,NULL,ic,TRUE);
6694 freeAsmop(result,NULL,ic,TRUE);
6697 /*-----------------------------------------------------------------*/
6698 /* genrshOne - right shift a one byte quantity by known count */
6699 /*-----------------------------------------------------------------*/
6700 static void genrshOne (operand *result, operand *left,
6701 int shCount, int sign)
6703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6704 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6707 /*-----------------------------------------------------------------*/
6708 /* genrshTwo - right shift two bytes by known amount != 0 */
6709 /*-----------------------------------------------------------------*/
6710 static void genrshTwo (operand *result,operand *left,
6711 int shCount, int sign)
6713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6714 /* if shCount >= 8 */
6718 shiftR1Left2Result(left, MSB16, result, LSB,
6721 movLeft2Result(left, MSB16, result, LSB, sign);
6723 addSign(result, MSB16, sign);
6725 emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6729 /* 1 <= shCount <= 7 */
6731 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6734 /*-----------------------------------------------------------------*/
6735 /* shiftRLong - shift right one long from left to result */
6736 /* offl = LSB or MSB16 */
6737 /*-----------------------------------------------------------------*/
6738 static void shiftRLong (operand *left, int offl,
6739 operand *result, int sign)
6741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6743 pic14_emitcode("clr","c");
6744 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6746 pic14_emitcode("mov","c,acc.7");
6747 pic14_emitcode("rrc","a");
6748 aopPut(AOP(result),"a",MSB32-offl);
6750 /* add sign of "a" */
6751 addSign(result, MSB32, sign);
6753 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6754 pic14_emitcode("rrc","a");
6755 aopPut(AOP(result),"a",MSB24-offl);
6757 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6758 pic14_emitcode("rrc","a");
6759 aopPut(AOP(result),"a",MSB16-offl);
6762 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6763 pic14_emitcode("rrc","a");
6764 aopPut(AOP(result),"a",LSB);
6768 /*-----------------------------------------------------------------*/
6769 /* genrshFour - shift four byte by a known amount != 0 */
6770 /*-----------------------------------------------------------------*/
6771 static void genrshFour (operand *result, operand *left,
6772 int shCount, int sign)
6774 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6775 /* if shifting more that 3 bytes */
6776 if(shCount >= 24 ) {
6779 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6781 movLeft2Result(left, MSB32, result, LSB, sign);
6782 addSign(result, MSB16, sign);
6784 else if(shCount >= 16){
6787 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6789 movLeft2Result(left, MSB24, result, LSB, 0);
6790 movLeft2Result(left, MSB32, result, MSB16, sign);
6792 addSign(result, MSB24, sign);
6794 else if(shCount >= 8){
6797 shiftRLong(left, MSB16, result, sign);
6798 else if(shCount == 0){
6799 movLeft2Result(left, MSB16, result, LSB, 0);
6800 movLeft2Result(left, MSB24, result, MSB16, 0);
6801 movLeft2Result(left, MSB32, result, MSB24, sign);
6802 addSign(result, MSB32, sign);
6805 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6806 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6807 /* the last shift is signed */
6808 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6809 addSign(result, MSB32, sign);
6812 else{ /* 1 <= shCount <= 7 */
6814 shiftRLong(left, LSB, result, sign);
6816 shiftRLong(result, LSB, result, sign);
6819 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6820 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6821 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6826 /*-----------------------------------------------------------------*/
6827 /* genRightShiftLiteral - right shifting by known count */
6828 /*-----------------------------------------------------------------*/
6829 static void genRightShiftLiteral (operand *left,
6835 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6839 freeAsmop(right,NULL,ic,TRUE);
6841 aopOp(left,ic,FALSE);
6842 aopOp(result,ic,FALSE);
6845 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6849 size = pic14_getDataSize(left);
6850 /* test the LEFT size !!! */
6852 /* I suppose that the left size >= result size */
6854 size = pic14_getDataSize(result);
6856 movLeft2Result(left, size, result, size, 0);
6859 else if(shCount >= (size * 8)){
6861 /* get sign in acc.7 */
6862 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6863 addSign(result, LSB, sign);
6867 genrshOne (result,left,shCount,sign);
6871 genrshTwo (result,left,shCount,sign);
6875 genrshFour (result,left,shCount,sign);
6881 freeAsmop(left,NULL,ic,TRUE);
6882 freeAsmop(result,NULL,ic,TRUE);
6886 /*-----------------------------------------------------------------*/
6887 /* genSignedRightShift - right shift of signed number */
6888 /*-----------------------------------------------------------------*/
6889 static void genSignedRightShift (iCode *ic)
6891 operand *right, *left, *result;
6894 symbol *tlbl, *tlbl1 ;
6896 /* we do it the hard way put the shift count in b
6897 and loop thru preserving the sign */
6898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6900 right = IC_RIGHT(ic);
6902 result = IC_RESULT(ic);
6904 aopOp(right,ic,FALSE);
6907 if ( AOP_TYPE(right) == AOP_LIT) {
6908 genRightShiftLiteral (left,right,result,ic,1);
6911 /* shift count is unknown then we have to form
6912 a loop get the loop count in B : Note: we take
6913 only the lower order byte since shifting
6914 more that 32 bits make no sense anyway, ( the
6915 largest size of an object can be only 32 bits ) */
6917 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6918 pic14_emitcode("inc","b");
6919 freeAsmop (right,NULL,ic,TRUE);
6920 aopOp(left,ic,FALSE);
6921 aopOp(result,ic,FALSE);
6923 /* now move the left to the result if they are not the
6925 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6926 AOP_SIZE(result) > 1) {
6928 size = AOP_SIZE(result);
6931 l = aopGet(AOP(left),offset,FALSE,TRUE);
6932 if (*l == '@' && IS_AOP_PREG(result)) {
6934 pic14_emitcode("mov","a,%s",l);
6935 aopPut(AOP(result),"a",offset);
6937 aopPut(AOP(result),l,offset);
6942 /* mov the highest order bit to OVR */
6943 tlbl = newiTempLabel(NULL);
6944 tlbl1= newiTempLabel(NULL);
6946 size = AOP_SIZE(result);
6948 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6949 pic14_emitcode("rlc","a");
6950 pic14_emitcode("mov","ov,c");
6951 /* if it is only one byte then */
6953 l = aopGet(AOP(left),0,FALSE,FALSE);
6955 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6956 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6957 pic14_emitcode("mov","c,ov");
6958 pic14_emitcode("rrc","a");
6959 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6960 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6961 aopPut(AOP(result),"a",0);
6965 reAdjustPreg(AOP(result));
6966 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6967 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6968 pic14_emitcode("mov","c,ov");
6970 l = aopGet(AOP(result),offset,FALSE,FALSE);
6972 pic14_emitcode("rrc","a");
6973 aopPut(AOP(result),"a",offset--);
6975 reAdjustPreg(AOP(result));
6976 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6977 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6980 freeAsmop(left,NULL,ic,TRUE);
6981 freeAsmop(result,NULL,ic,TRUE);
6984 /*-----------------------------------------------------------------*/
6985 /* genRightShift - generate code for right shifting */
6986 /*-----------------------------------------------------------------*/
6987 static void genRightShift (iCode *ic)
6989 operand *right, *left, *result;
6993 symbol *tlbl, *tlbl1 ;
6995 /* if signed then we do it the hard way preserve the
6996 sign bit moving it inwards */
6997 retype = getSpec(operandType(IC_RESULT(ic)));
6998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7000 if (!SPEC_USIGN(retype)) {
7001 genSignedRightShift (ic);
7005 /* signed & unsigned types are treated the same : i.e. the
7006 signed is NOT propagated inwards : quoting from the
7007 ANSI - standard : "for E1 >> E2, is equivalent to division
7008 by 2**E2 if unsigned or if it has a non-negative value,
7009 otherwise the result is implementation defined ", MY definition
7010 is that the sign does not get propagated */
7012 right = IC_RIGHT(ic);
7014 result = IC_RESULT(ic);
7016 aopOp(right,ic,FALSE);
7018 /* if the shift count is known then do it
7019 as efficiently as possible */
7020 if (AOP_TYPE(right) == AOP_LIT) {
7021 genRightShiftLiteral (left,right,result,ic, 0);
7025 /* shift count is unknown then we have to form
7026 a loop get the loop count in B : Note: we take
7027 only the lower order byte since shifting
7028 more that 32 bits make no sense anyway, ( the
7029 largest size of an object can be only 32 bits ) */
7031 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7032 pic14_emitcode("inc","b");
7033 aopOp(left,ic,FALSE);
7034 aopOp(result,ic,FALSE);
7036 /* now move the left to the result if they are not the
7038 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7039 AOP_SIZE(result) > 1) {
7041 size = AOP_SIZE(result);
7044 l = aopGet(AOP(left),offset,FALSE,TRUE);
7045 if (*l == '@' && IS_AOP_PREG(result)) {
7047 pic14_emitcode("mov","a,%s",l);
7048 aopPut(AOP(result),"a",offset);
7050 aopPut(AOP(result),l,offset);
7055 tlbl = newiTempLabel(NULL);
7056 tlbl1= newiTempLabel(NULL);
7057 size = AOP_SIZE(result);
7060 /* if it is only one byte then */
7063 l = aopGet(AOP(left),0,FALSE,FALSE);
7065 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7066 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7068 pic14_emitcode("rrc","a");
7069 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7070 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7071 aopPut(AOP(result),"a",0);
7073 tlbl = newiTempLabel(NULL);
7074 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7075 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE));
7076 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
7079 emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE));
7080 emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE));
7081 emitpLabel(tlbl->key);
7082 emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE));
7083 emitpcode(POC_ADDLW, popGetLit(1));
7085 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7090 reAdjustPreg(AOP(result));
7091 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7092 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7095 l = aopGet(AOP(result),offset,FALSE,FALSE);
7097 pic14_emitcode("rrc","a");
7098 aopPut(AOP(result),"a",offset--);
7100 reAdjustPreg(AOP(result));
7102 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7103 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7106 freeAsmop(left,NULL,ic,TRUE);
7107 freeAsmop (right,NULL,ic,TRUE);
7108 freeAsmop(result,NULL,ic,TRUE);
7111 /*-----------------------------------------------------------------*/
7112 /* genUnpackBits - generates code for unpacking bits */
7113 /*-----------------------------------------------------------------*/
7114 static void genUnpackBits (operand *result, char *rname, int ptype)
7121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7122 etype = getSpec(operandType(result));
7124 /* read the first byte */
7129 pic14_emitcode("mov","a,@%s",rname);
7133 pic14_emitcode("movx","a,@%s",rname);
7137 pic14_emitcode("movx","a,@dptr");
7141 pic14_emitcode("clr","a");
7142 pic14_emitcode("movc","a","@a+dptr");
7146 pic14_emitcode("lcall","__gptrget");
7150 /* if we have bitdisplacement then it fits */
7151 /* into this byte completely or if length is */
7152 /* less than a byte */
7153 if ((shCnt = SPEC_BSTR(etype)) ||
7154 (SPEC_BLEN(etype) <= 8)) {
7156 /* shift right acc */
7159 pic14_emitcode("anl","a,#0x%02x",
7160 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7161 aopPut(AOP(result),"a",offset);
7165 /* bit field did not fit in a byte */
7166 rlen = SPEC_BLEN(etype) - 8;
7167 aopPut(AOP(result),"a",offset++);
7174 pic14_emitcode("inc","%s",rname);
7175 pic14_emitcode("mov","a,@%s",rname);
7179 pic14_emitcode("inc","%s",rname);
7180 pic14_emitcode("movx","a,@%s",rname);
7184 pic14_emitcode("inc","dptr");
7185 pic14_emitcode("movx","a,@dptr");
7189 pic14_emitcode("clr","a");
7190 pic14_emitcode("inc","dptr");
7191 pic14_emitcode("movc","a","@a+dptr");
7195 pic14_emitcode("inc","dptr");
7196 pic14_emitcode("lcall","__gptrget");
7201 /* if we are done */
7205 aopPut(AOP(result),"a",offset++);
7210 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7211 aopPut(AOP(result),"a",offset);
7218 /*-----------------------------------------------------------------*/
7219 /* genDataPointerGet - generates code when ptr offset is known */
7220 /*-----------------------------------------------------------------*/
7221 static void genDataPointerGet (operand *left,
7225 int size , offset = 0;
7228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7231 /* optimization - most of the time, left and result are the same
7232 * address, but different types. for the pic code, we could omit
7236 aopOp(result,ic,TRUE);
7238 emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7240 size = AOP_SIZE(result);
7243 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7247 freeAsmop(left,NULL,ic,TRUE);
7248 freeAsmop(result,NULL,ic,TRUE);
7251 /*-----------------------------------------------------------------*/
7252 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7253 /*-----------------------------------------------------------------*/
7254 static void genNearPointerGet (operand *left,
7261 sym_link *rtype, *retype;
7262 sym_link *ltype = operandType(left);
7265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7267 rtype = operandType(result);
7268 retype= getSpec(rtype);
7270 aopOp(left,ic,FALSE);
7272 /* if left is rematerialisable and
7273 result is not bit variable type and
7274 the left is pointer to data space i.e
7275 lower 128 bytes of space */
7276 if (AOP_TYPE(left) == AOP_IMMD &&
7277 !IS_BITVAR(retype) &&
7278 DCL_TYPE(ltype) == POINTER) {
7279 genDataPointerGet (left,result,ic);
7283 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7285 /* if the value is already in a pointer register
7286 then don't need anything more */
7287 if (!AOP_INPREG(AOP(left))) {
7288 /* otherwise get a free pointer register */
7289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7291 preg = getFreePtr(ic,&aop,FALSE);
7292 pic14_emitcode("mov","%s,%s",
7294 aopGet(AOP(left),0,FALSE,TRUE));
7295 rname = preg->name ;
7297 rname = aopGet(AOP(left),0,FALSE,FALSE);
7299 freeAsmop(left,NULL,ic,TRUE);
7300 aopOp (result,ic,FALSE);
7302 /* if bitfield then unpack the bits */
7303 if (IS_BITVAR(retype))
7304 genUnpackBits (result,rname,POINTER);
7306 /* we have can just get the values */
7307 int size = AOP_SIZE(result);
7310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7312 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7314 pic14_emitcode("mov","a,@%s",rname);
7315 aopPut(AOP(result),"a",offset);
7317 sprintf(buffer,"@%s",rname);
7318 aopPut(AOP(result),buffer,offset);
7322 pic14_emitcode("inc","%s",rname);
7326 /* now some housekeeping stuff */
7328 /* we had to allocate for this iCode */
7329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7330 freeAsmop(NULL,aop,ic,TRUE);
7332 /* we did not allocate which means left
7333 already in a pointer register, then
7334 if size > 0 && this could be used again
7335 we have to point it back to where it
7337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7338 if (AOP_SIZE(result) > 1 &&
7339 !OP_SYMBOL(left)->remat &&
7340 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7342 int size = AOP_SIZE(result) - 1;
7344 pic14_emitcode("dec","%s",rname);
7349 freeAsmop(result,NULL,ic,TRUE);
7353 /*-----------------------------------------------------------------*/
7354 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7355 /*-----------------------------------------------------------------*/
7356 static void genPagedPointerGet (operand *left,
7363 sym_link *rtype, *retype;
7365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7367 rtype = operandType(result);
7368 retype= getSpec(rtype);
7370 aopOp(left,ic,FALSE);
7372 /* if the value is already in a pointer register
7373 then don't need anything more */
7374 if (!AOP_INPREG(AOP(left))) {
7375 /* otherwise get a free pointer register */
7377 preg = getFreePtr(ic,&aop,FALSE);
7378 pic14_emitcode("mov","%s,%s",
7380 aopGet(AOP(left),0,FALSE,TRUE));
7381 rname = preg->name ;
7383 rname = aopGet(AOP(left),0,FALSE,FALSE);
7385 freeAsmop(left,NULL,ic,TRUE);
7386 aopOp (result,ic,FALSE);
7388 /* if bitfield then unpack the bits */
7389 if (IS_BITVAR(retype))
7390 genUnpackBits (result,rname,PPOINTER);
7392 /* we have can just get the values */
7393 int size = AOP_SIZE(result);
7398 pic14_emitcode("movx","a,@%s",rname);
7399 aopPut(AOP(result),"a",offset);
7404 pic14_emitcode("inc","%s",rname);
7408 /* now some housekeeping stuff */
7410 /* we had to allocate for this iCode */
7411 freeAsmop(NULL,aop,ic,TRUE);
7413 /* we did not allocate which means left
7414 already in a pointer register, then
7415 if size > 0 && this could be used again
7416 we have to point it back to where it
7418 if (AOP_SIZE(result) > 1 &&
7419 !OP_SYMBOL(left)->remat &&
7420 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7422 int size = AOP_SIZE(result) - 1;
7424 pic14_emitcode("dec","%s",rname);
7429 freeAsmop(result,NULL,ic,TRUE);
7434 /*-----------------------------------------------------------------*/
7435 /* genFarPointerGet - gget value from far space */
7436 /*-----------------------------------------------------------------*/
7437 static void genFarPointerGet (operand *left,
7438 operand *result, iCode *ic)
7441 sym_link *retype = getSpec(operandType(result));
7443 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7445 aopOp(left,ic,FALSE);
7447 /* if the operand is already in dptr
7448 then we do nothing else we move the value to dptr */
7449 if (AOP_TYPE(left) != AOP_STR) {
7450 /* if this is remateriazable */
7451 if (AOP_TYPE(left) == AOP_IMMD)
7452 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7453 else { /* we need to get it byte by byte */
7454 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7455 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7456 if (options.model == MODEL_FLAT24)
7458 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7462 /* so dptr know contains the address */
7463 freeAsmop(left,NULL,ic,TRUE);
7464 aopOp(result,ic,FALSE);
7466 /* if bit then unpack */
7467 if (IS_BITVAR(retype))
7468 genUnpackBits(result,"dptr",FPOINTER);
7470 size = AOP_SIZE(result);
7474 pic14_emitcode("movx","a,@dptr");
7475 aopPut(AOP(result),"a",offset++);
7477 pic14_emitcode("inc","dptr");
7481 freeAsmop(result,NULL,ic,TRUE);
7484 /*-----------------------------------------------------------------*/
7485 /* pic14_emitcodePointerGet - gget value from code space */
7486 /*-----------------------------------------------------------------*/
7487 static void pic14_emitcodePointerGet (operand *left,
7488 operand *result, iCode *ic)
7491 sym_link *retype = getSpec(operandType(result));
7493 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7495 aopOp(left,ic,FALSE);
7497 /* if the operand is already in dptr
7498 then we do nothing else we move the value to dptr */
7499 if (AOP_TYPE(left) != AOP_STR) {
7500 /* if this is remateriazable */
7501 if (AOP_TYPE(left) == AOP_IMMD)
7502 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7503 else { /* we need to get it byte by byte */
7504 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7505 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7506 if (options.model == MODEL_FLAT24)
7508 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7512 /* so dptr know contains the address */
7513 freeAsmop(left,NULL,ic,TRUE);
7514 aopOp(result,ic,FALSE);
7516 /* if bit then unpack */
7517 if (IS_BITVAR(retype))
7518 genUnpackBits(result,"dptr",CPOINTER);
7520 size = AOP_SIZE(result);
7524 pic14_emitcode("clr","a");
7525 pic14_emitcode("movc","a,@a+dptr");
7526 aopPut(AOP(result),"a",offset++);
7528 pic14_emitcode("inc","dptr");
7532 freeAsmop(result,NULL,ic,TRUE);
7535 /*-----------------------------------------------------------------*/
7536 /* genGenPointerGet - gget value from generic pointer space */
7537 /*-----------------------------------------------------------------*/
7538 static void genGenPointerGet (operand *left,
7539 operand *result, iCode *ic)
7542 sym_link *retype = getSpec(operandType(result));
7544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7545 aopOp(left,ic,FALSE);
7546 aopOp(result,ic,FALSE);
7549 DEBUGpic14_emitcode ("; ","result %s, left %s",
7550 AopType(AOP_TYPE(result)),
7551 AopType(AOP_TYPE(left)));
7553 /* if the operand is already in dptr
7554 then we do nothing else we move the value to dptr */
7555 if (AOP_TYPE(left) != AOP_STR) {
7556 /* if this is remateriazable */
7557 if (AOP_TYPE(left) == AOP_IMMD) {
7558 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7559 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7561 else { /* we need to get it byte by byte */
7563 size = AOP_SIZE(result);
7567 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7568 emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7570 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7575 /* so dptr know contains the address */
7577 /* if bit then unpack */
7578 if (IS_BITVAR(retype))
7579 genUnpackBits(result,"dptr",GPOINTER);
7582 freeAsmop(left,NULL,ic,TRUE);
7583 freeAsmop(result,NULL,ic,TRUE);
7587 /*-----------------------------------------------------------------*/
7588 /* genPointerGet - generate code for pointer get */
7589 /*-----------------------------------------------------------------*/
7590 static void genPointerGet (iCode *ic)
7592 operand *left, *result ;
7593 sym_link *type, *etype;
7596 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7599 result = IC_RESULT(ic) ;
7601 /* depending on the type of pointer we need to
7602 move it to the correct pointer register */
7603 type = operandType(left);
7604 etype = getSpec(type);
7605 /* if left is of type of pointer then it is simple */
7606 if (IS_PTR(type) && !IS_FUNC(type->next))
7607 p_type = DCL_TYPE(type);
7609 /* we have to go by the storage class */
7610 p_type = PTR_TYPE(SPEC_OCLS(etype));
7612 /* if (SPEC_OCLS(etype)->codesp ) { */
7613 /* p_type = CPOINTER ; */
7616 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7617 /* p_type = FPOINTER ; */
7619 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7620 /* p_type = PPOINTER; */
7622 /* if (SPEC_OCLS(etype) == idata ) */
7623 /* p_type = IPOINTER; */
7625 /* p_type = POINTER ; */
7628 /* now that we have the pointer type we assign
7629 the pointer values */
7634 genNearPointerGet (left,result,ic);
7638 genPagedPointerGet(left,result,ic);
7642 genFarPointerGet (left,result,ic);
7646 pic14_emitcodePointerGet (left,result,ic);
7650 genGenPointerGet (left,result,ic);
7656 /*-----------------------------------------------------------------*/
7657 /* genPackBits - generates code for packed bit storage */
7658 /*-----------------------------------------------------------------*/
7659 static void genPackBits (sym_link *etype ,
7661 char *rname, int p_type)
7669 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7670 blen = SPEC_BLEN(etype);
7671 bstr = SPEC_BSTR(etype);
7673 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7676 /* if the bit lenth is less than or */
7677 /* it exactly fits a byte then */
7678 if (SPEC_BLEN(etype) <= 8 ) {
7679 shCount = SPEC_BSTR(etype) ;
7681 /* shift left acc */
7684 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7689 pic14_emitcode ("mov","b,a");
7690 pic14_emitcode("mov","a,@%s",rname);
7694 pic14_emitcode ("mov","b,a");
7695 pic14_emitcode("movx","a,@dptr");
7699 pic14_emitcode ("push","b");
7700 pic14_emitcode ("push","acc");
7701 pic14_emitcode ("lcall","__gptrget");
7702 pic14_emitcode ("pop","b");
7706 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7707 ((unsigned char)(0xFF << (blen+bstr)) |
7708 (unsigned char)(0xFF >> (8-bstr)) ) );
7709 pic14_emitcode ("orl","a,b");
7710 if (p_type == GPOINTER)
7711 pic14_emitcode("pop","b");
7717 pic14_emitcode("mov","@%s,a",rname);
7721 pic14_emitcode("movx","@dptr,a");
7725 DEBUGpic14_emitcode(";lcall","__gptrput");
7730 if ( SPEC_BLEN(etype) <= 8 )
7733 pic14_emitcode("inc","%s",rname);
7734 rLen = SPEC_BLEN(etype) ;
7736 /* now generate for lengths greater than one byte */
7739 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7749 pic14_emitcode("mov","@%s,a",rname);
7751 pic14_emitcode("mov","@%s,%s",rname,l);
7756 pic14_emitcode("movx","@dptr,a");
7761 DEBUGpic14_emitcode(";lcall","__gptrput");
7764 pic14_emitcode ("inc","%s",rname);
7769 /* last last was not complete */
7771 /* save the byte & read byte */
7774 pic14_emitcode ("mov","b,a");
7775 pic14_emitcode("mov","a,@%s",rname);
7779 pic14_emitcode ("mov","b,a");
7780 pic14_emitcode("movx","a,@dptr");
7784 pic14_emitcode ("push","b");
7785 pic14_emitcode ("push","acc");
7786 pic14_emitcode ("lcall","__gptrget");
7787 pic14_emitcode ("pop","b");
7791 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7792 pic14_emitcode ("orl","a,b");
7795 if (p_type == GPOINTER)
7796 pic14_emitcode("pop","b");
7801 pic14_emitcode("mov","@%s,a",rname);
7805 pic14_emitcode("movx","@dptr,a");
7809 DEBUGpic14_emitcode(";lcall","__gptrput");
7813 /*-----------------------------------------------------------------*/
7814 /* genDataPointerSet - remat pointer to data space */
7815 /*-----------------------------------------------------------------*/
7816 static void genDataPointerSet(operand *right,
7820 int size, offset = 0 ;
7821 char *l, buffer[256];
7823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7824 aopOp(right,ic,FALSE);
7826 l = aopGet(AOP(result),0,FALSE,TRUE);
7827 size = AOP_SIZE(right);
7828 // tsd, was l+1 - the underline `_' prefix was being stripped
7831 sprintf(buffer,"(%s + %d)",l,offset);
7833 sprintf(buffer,"%s",l);
7835 if (AOP_TYPE(right) == AOP_LIT) {
7836 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7837 lit = lit >> (8*offset);
7839 pic14_emitcode("movlw","%d",lit);
7840 pic14_emitcode("movwf","%s",buffer);
7842 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7843 emitpcode(POC_MOVWF, popRegFromString(buffer));
7846 pic14_emitcode("clrf","%s",buffer);
7847 emitpcode(POC_CLRF, popRegFromString(buffer));
7850 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7851 pic14_emitcode("movwf","%s",buffer);
7853 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7854 emitpcode(POC_MOVWF, popRegFromString(buffer));
7861 freeAsmop(right,NULL,ic,TRUE);
7862 freeAsmop(result,NULL,ic,TRUE);
7865 /*-----------------------------------------------------------------*/
7866 /* genNearPointerSet - pic14_emitcode for near pointer put */
7867 /*-----------------------------------------------------------------*/
7868 static void genNearPointerSet (operand *right,
7875 sym_link *ptype = operandType(result);
7878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7879 retype= getSpec(operandType(right));
7881 aopOp(result,ic,FALSE);
7883 /* if the result is rematerializable &
7884 in data space & not a bit variable */
7885 if (AOP_TYPE(result) == AOP_IMMD &&
7886 DCL_TYPE(ptype) == POINTER &&
7887 !IS_BITVAR(retype)) {
7888 genDataPointerSet (right,result,ic);
7892 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7894 /* if the value is already in a pointer register
7895 then don't need anything more */
7896 if (!AOP_INPREG(AOP(result))) {
7897 /* otherwise get a free pointer register */
7898 //aop = newAsmop(0);
7899 //preg = getFreePtr(ic,&aop,FALSE);
7900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7901 //pic14_emitcode("mov","%s,%s",
7903 // aopGet(AOP(result),0,FALSE,TRUE));
7904 //rname = preg->name ;
7905 pic14_emitcode("movwf","fsr");
7907 // rname = aopGet(AOP(result),0,FALSE,FALSE);
7909 freeAsmop(result,NULL,ic,TRUE);
7910 aopOp (right,ic,FALSE);
7911 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7913 /* if bitfield then unpack the bits */
7914 if (IS_BITVAR(retype)) {
7915 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7916 "The programmer is obviously confused");
7917 //genPackBits (retype,right,rname,POINTER);
7921 /* we have can just get the values */
7922 int size = AOP_SIZE(right);
7925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7927 l = aopGet(AOP(right),offset,FALSE,TRUE);
7930 //pic14_emitcode("mov","@%s,a",rname);
7931 pic14_emitcode("movf","indf,w ;1");
7934 if (AOP_TYPE(right) == AOP_LIT) {
7935 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7937 pic14_emitcode("movlw","%s",l);
7938 pic14_emitcode("movwf","indf ;2");
7940 pic14_emitcode("clrf","indf");
7942 pic14_emitcode("movf","%s,w",l);
7943 pic14_emitcode("movwf","indf ;2");
7945 //pic14_emitcode("mov","@%s,%s",rname,l);
7948 pic14_emitcode("incf","fsr,f ;3");
7949 //pic14_emitcode("inc","%s",rname);
7954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7955 /* now some housekeeping stuff */
7957 /* we had to allocate for this iCode */
7958 freeAsmop(NULL,aop,ic,TRUE);
7960 /* we did not allocate which means left
7961 already in a pointer register, then
7962 if size > 0 && this could be used again
7963 we have to point it back to where it
7965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 if (AOP_SIZE(right) > 1 &&
7967 !OP_SYMBOL(result)->remat &&
7968 ( OP_SYMBOL(result)->liveTo > ic->seq ||
7970 int size = AOP_SIZE(right) - 1;
7972 pic14_emitcode("decf","fsr,f");
7973 //pic14_emitcode("dec","%s",rname);
7977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7979 freeAsmop(right,NULL,ic,TRUE);
7984 /*-----------------------------------------------------------------*/
7985 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
7986 /*-----------------------------------------------------------------*/
7987 static void genPagedPointerSet (operand *right,
7996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7998 retype= getSpec(operandType(right));
8000 aopOp(result,ic,FALSE);
8002 /* if the value is already in a pointer register
8003 then don't need anything more */
8004 if (!AOP_INPREG(AOP(result))) {
8005 /* otherwise get a free pointer register */
8007 preg = getFreePtr(ic,&aop,FALSE);
8008 pic14_emitcode("mov","%s,%s",
8010 aopGet(AOP(result),0,FALSE,TRUE));
8011 rname = preg->name ;
8013 rname = aopGet(AOP(result),0,FALSE,FALSE);
8015 freeAsmop(result,NULL,ic,TRUE);
8016 aopOp (right,ic,FALSE);
8018 /* if bitfield then unpack the bits */
8019 if (IS_BITVAR(retype))
8020 genPackBits (retype,right,rname,PPOINTER);
8022 /* we have can just get the values */
8023 int size = AOP_SIZE(right);
8027 l = aopGet(AOP(right),offset,FALSE,TRUE);
8030 pic14_emitcode("movx","@%s,a",rname);
8033 pic14_emitcode("inc","%s",rname);
8039 /* now some housekeeping stuff */
8041 /* we had to allocate for this iCode */
8042 freeAsmop(NULL,aop,ic,TRUE);
8044 /* we did not allocate which means left
8045 already in a pointer register, then
8046 if size > 0 && this could be used again
8047 we have to point it back to where it
8049 if (AOP_SIZE(right) > 1 &&
8050 !OP_SYMBOL(result)->remat &&
8051 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8053 int size = AOP_SIZE(right) - 1;
8055 pic14_emitcode("dec","%s",rname);
8060 freeAsmop(right,NULL,ic,TRUE);
8065 /*-----------------------------------------------------------------*/
8066 /* genFarPointerSet - set value from far space */
8067 /*-----------------------------------------------------------------*/
8068 static void genFarPointerSet (operand *right,
8069 operand *result, iCode *ic)
8072 sym_link *retype = getSpec(operandType(right));
8074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8075 aopOp(result,ic,FALSE);
8077 /* if the operand is already in dptr
8078 then we do nothing else we move the value to dptr */
8079 if (AOP_TYPE(result) != AOP_STR) {
8080 /* if this is remateriazable */
8081 if (AOP_TYPE(result) == AOP_IMMD)
8082 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8083 else { /* we need to get it byte by byte */
8084 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8085 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8086 if (options.model == MODEL_FLAT24)
8088 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8092 /* so dptr know contains the address */
8093 freeAsmop(result,NULL,ic,TRUE);
8094 aopOp(right,ic,FALSE);
8096 /* if bit then unpack */
8097 if (IS_BITVAR(retype))
8098 genPackBits(retype,right,"dptr",FPOINTER);
8100 size = AOP_SIZE(right);
8104 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8106 pic14_emitcode("movx","@dptr,a");
8108 pic14_emitcode("inc","dptr");
8112 freeAsmop(right,NULL,ic,TRUE);
8115 /*-----------------------------------------------------------------*/
8116 /* genGenPointerSet - set value from generic pointer space */
8117 /*-----------------------------------------------------------------*/
8118 static void genGenPointerSet (operand *right,
8119 operand *result, iCode *ic)
8122 sym_link *retype = getSpec(operandType(right));
8124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8126 aopOp(result,ic,FALSE);
8127 aopOp(right,ic,FALSE);
8128 size = AOP_SIZE(right);
8130 DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8131 AopType(AOP_TYPE(result)),
8132 aopGet(AOP(result),0,TRUE,FALSE),
8133 AopType(AOP_TYPE(right)),
8134 aopGet(AOP(right),0,FALSE,FALSE),
8137 /* if the operand is already in dptr
8138 then we do nothing else we move the value to dptr */
8139 if (AOP_TYPE(result) != AOP_STR) {
8140 /* if this is remateriazable */
8141 if (AOP_TYPE(result) == AOP_IMMD) {
8142 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8143 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8145 else { /* we need to get it byte by byte */
8146 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8147 size = AOP_SIZE(right);
8150 /* hack hack! see if this the FSR. If so don't load W */
8151 if(AOP_TYPE(right) != AOP_ACC) {
8154 emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8157 emitpcode(POC_MOVLW,popGetLit(0xfd));
8158 emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8162 emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8163 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8166 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8173 if(aopIdx(AOP(result),0) != 4) {
8175 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8179 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8184 /* so dptr know contains the address */
8187 /* if bit then unpack */
8188 if (IS_BITVAR(retype))
8189 genPackBits(retype,right,"dptr",GPOINTER);
8191 size = AOP_SIZE(right);
8195 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8197 pic14_emitcode("incf","fsr,f");
8198 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8199 pic14_emitcode("movwf","indf");
8201 //DEBUGpic14_emitcode(";lcall","__gptrput");
8203 // pic14_emitcode("inc","dptr");
8208 freeAsmop(right,NULL,ic,TRUE);
8209 freeAsmop(result,NULL,ic,TRUE);
8212 /*-----------------------------------------------------------------*/
8213 /* genPointerSet - stores the value into a pointer location */
8214 /*-----------------------------------------------------------------*/
8215 static void genPointerSet (iCode *ic)
8217 operand *right, *result ;
8218 sym_link *type, *etype;
8221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8223 right = IC_RIGHT(ic);
8224 result = IC_RESULT(ic) ;
8226 /* depending on the type of pointer we need to
8227 move it to the correct pointer register */
8228 type = operandType(result);
8229 etype = getSpec(type);
8230 /* if left is of type of pointer then it is simple */
8231 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8232 p_type = DCL_TYPE(type);
8235 /* we have to go by the storage class */
8236 p_type = PTR_TYPE(SPEC_OCLS(etype));
8238 /* if (SPEC_OCLS(etype)->codesp ) { */
8239 /* p_type = CPOINTER ; */
8242 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8243 /* p_type = FPOINTER ; */
8245 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8246 /* p_type = PPOINTER ; */
8248 /* if (SPEC_OCLS(etype) == idata ) */
8249 /* p_type = IPOINTER ; */
8251 /* p_type = POINTER ; */
8254 /* now that we have the pointer type we assign
8255 the pointer values */
8260 genNearPointerSet (right,result,ic);
8264 genPagedPointerSet (right,result,ic);
8268 genFarPointerSet (right,result,ic);
8272 genGenPointerSet (right,result,ic);
8278 /*-----------------------------------------------------------------*/
8279 /* genIfx - generate code for Ifx statement */
8280 /*-----------------------------------------------------------------*/
8281 static void genIfx (iCode *ic, iCode *popIc)
8283 operand *cond = IC_COND(ic);
8286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8288 aopOp(cond,ic,FALSE);
8290 /* get the value into acc */
8291 if (AOP_TYPE(cond) != AOP_CRY)
8292 pic14_toBoolean(cond);
8295 /* the result is now in the accumulator */
8296 freeAsmop(cond,NULL,ic,TRUE);
8298 /* if there was something to be popped then do it */
8302 /* if the condition is a bit variable */
8303 if (isbit && IS_ITEMP(cond) &&
8305 genIfxJump(ic,SPIL_LOC(cond)->rname);
8306 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8309 if (isbit && !IS_ITEMP(cond))
8310 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8318 /*-----------------------------------------------------------------*/
8319 /* genAddrOf - generates code for address of */
8320 /*-----------------------------------------------------------------*/
8321 static void genAddrOf (iCode *ic)
8323 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8324 operand *right, *result, *left;
8325 //int size, offset ;
8327 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8330 //aopOp(IC_RESULT(ic),ic,FALSE);
8332 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8333 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8334 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8337 DEBUGpic14_emitcode ("; ","result %s",
8338 AopType(AOP_TYPE(IC_RESULT(ic))));
8341 DEBUGpic14_emitcode ("; ","left %s",
8342 AopType(AOP_TYPE(IC_LEFT(ic))));
8344 DEBUGpic14_emitcode ("; ","right %s",
8345 AopType(AOP_TYPE(IC_RIGHT(ic))));
8347 emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8348 emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8351 /* object not on stack then we need the name */
8352 size = AOP_SIZE(IC_RESULT(ic));
8356 char s[SDCC_NAME_MAX];
8358 sprintf(s,"#(%s >> %d)",
8362 sprintf(s,"#%s",sym->rname);
8363 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8368 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8369 freeAsmop(left,NULL,ic,FALSE);
8370 freeAsmop(result,NULL,ic,TRUE);
8375 /*-----------------------------------------------------------------*/
8376 /* genFarFarAssign - assignment when both are in far space */
8377 /*-----------------------------------------------------------------*/
8378 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8380 int size = AOP_SIZE(right);
8383 /* first push the right side on to the stack */
8385 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8387 pic14_emitcode ("push","acc");
8390 freeAsmop(right,NULL,ic,FALSE);
8391 /* now assign DPTR to result */
8392 aopOp(result,ic,FALSE);
8393 size = AOP_SIZE(result);
8395 pic14_emitcode ("pop","acc");
8396 aopPut(AOP(result),"a",--offset);
8398 freeAsmop(result,NULL,ic,FALSE);
8403 /*-----------------------------------------------------------------*/
8404 /* genAssign - generate code for assignment */
8405 /*-----------------------------------------------------------------*/
8406 static void genAssign (iCode *ic)
8408 operand *result, *right;
8409 int size, offset,know_W;
8410 unsigned long lit = 0L;
8412 result = IC_RESULT(ic);
8413 right = IC_RIGHT(ic) ;
8415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8417 /* if they are the same */
8418 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8421 aopOp(right,ic,FALSE);
8422 aopOp(result,ic,TRUE);
8424 DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8425 AopType(AOP_TYPE(IC_RESULT(ic))),
8426 AopType(AOP_TYPE(IC_RIGHT(ic))),
8429 /* if they are the same registers */
8430 if (pic14_sameRegs(AOP(right),AOP(result)))
8433 /* if the result is a bit */
8434 if (AOP_TYPE(result) == AOP_CRY) {
8436 /* if the right size is a literal then
8437 we know what the value is */
8438 if (AOP_TYPE(right) == AOP_LIT) {
8440 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8441 popGet(AOP(result),0,FALSE,FALSE));
8443 if (((int) operandLitValue(right)))
8444 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8445 AOP(result)->aopu.aop_dir,
8446 AOP(result)->aopu.aop_dir);
8448 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8449 AOP(result)->aopu.aop_dir,
8450 AOP(result)->aopu.aop_dir);
8454 /* the right is also a bit variable */
8455 if (AOP_TYPE(right) == AOP_CRY) {
8456 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8457 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8458 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8460 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8461 AOP(result)->aopu.aop_dir,
8462 AOP(result)->aopu.aop_dir);
8463 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8464 AOP(right)->aopu.aop_dir,
8465 AOP(right)->aopu.aop_dir);
8466 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8467 AOP(result)->aopu.aop_dir,
8468 AOP(result)->aopu.aop_dir);
8473 emitpcode(POC_BCF, popGet(AOP(result),0,FALSE,FALSE));
8474 pic14_toBoolean(right);
8476 emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
8477 //aopPut(AOP(result),"a",0);
8481 /* bit variables done */
8483 size = AOP_SIZE(result);
8485 if(AOP_TYPE(right) == AOP_LIT)
8486 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8488 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8489 if(aopIdx(AOP(result),0) == 4) {
8490 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8491 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8494 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8499 if(AOP_TYPE(right) == AOP_LIT) {
8501 if(know_W != (lit&0xff))
8502 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8504 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8506 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8510 } else if (AOP_TYPE(right) == AOP_CRY) {
8511 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8513 emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8514 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8517 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8518 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8526 freeAsmop (right,NULL,ic,FALSE);
8527 freeAsmop (result,NULL,ic,TRUE);
8530 /*-----------------------------------------------------------------*/
8531 /* genJumpTab - genrates code for jump table */
8532 /*-----------------------------------------------------------------*/
8533 static void genJumpTab (iCode *ic)
8538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8540 aopOp(IC_JTCOND(ic),ic,FALSE);
8541 /* get the condition into accumulator */
8542 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8544 /* multiply by three */
8545 pic14_emitcode("add","a,acc");
8546 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8548 jtab = newiTempLabel(NULL);
8549 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8550 pic14_emitcode("jmp","@a+dptr");
8551 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8553 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8554 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8556 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8557 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8558 emitpLabel(jtab->key);
8560 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8562 /* now generate the jump labels */
8563 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8564 jtab = setNextItem(IC_JTLABELS(ic))) {
8565 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8566 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8572 /*-----------------------------------------------------------------*/
8573 /* genMixedOperation - gen code for operators between mixed types */
8574 /*-----------------------------------------------------------------*/
8576 TSD - Written for the PIC port - but this unfortunately is buggy.
8577 This routine is good in that it is able to efficiently promote
8578 types to different (larger) sizes. Unfortunately, the temporary
8579 variables that are optimized out by this routine are sometimes
8580 used in other places. So until I know how to really parse the
8581 iCode tree, I'm going to not be using this routine :(.
8583 static int genMixedOperation (iCode *ic)
8586 operand *result = IC_RESULT(ic);
8587 sym_link *ctype = operandType(IC_LEFT(ic));
8588 operand *right = IC_RIGHT(ic);
8594 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8596 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8602 nextright = IC_RIGHT(nextic);
8603 nextleft = IC_LEFT(nextic);
8604 nextresult = IC_RESULT(nextic);
8606 aopOp(right,ic,FALSE);
8607 aopOp(result,ic,FALSE);
8608 aopOp(nextright, nextic, FALSE);
8609 aopOp(nextleft, nextic, FALSE);
8610 aopOp(nextresult, nextic, FALSE);
8612 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8618 pic14_emitcode(";remove right +","");
8620 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8626 pic14_emitcode(";remove left +","");
8630 big = AOP_SIZE(nextleft);
8631 small = AOP_SIZE(nextright);
8633 switch(nextic->op) {
8636 pic14_emitcode(";optimize a +","");
8637 /* if unsigned or not an integral type */
8638 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8639 pic14_emitcode(";add a bit to something","");
8642 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8644 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8645 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8646 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8648 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8656 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8657 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8658 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8661 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8663 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8664 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8665 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8666 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8667 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8670 pic14_emitcode("rlf","known_zero,w");
8677 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8678 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8679 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8681 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8691 freeAsmop(right,NULL,ic,TRUE);
8692 freeAsmop(result,NULL,ic,TRUE);
8693 freeAsmop(nextright,NULL,ic,TRUE);
8694 freeAsmop(nextleft,NULL,ic,TRUE);
8696 nextic->generated = 1;
8703 /*-----------------------------------------------------------------*/
8704 /* genCast - gen code for casting */
8705 /*-----------------------------------------------------------------*/
8706 static void genCast (iCode *ic)
8708 operand *result = IC_RESULT(ic);
8709 sym_link *ctype = operandType(IC_LEFT(ic));
8710 operand *right = IC_RIGHT(ic);
8713 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8714 /* if they are equivalent then do nothing */
8715 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8718 aopOp(right,ic,FALSE) ;
8719 aopOp(result,ic,FALSE);
8721 /* if the result is a bit */
8722 if (AOP_TYPE(result) == AOP_CRY) {
8723 /* if the right size is a literal then
8724 we know what the value is */
8725 if (AOP_TYPE(right) == AOP_LIT) {
8727 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8728 popGet(AOP(result),0,FALSE,FALSE));
8730 if (((int) operandLitValue(right)))
8731 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8732 AOP(result)->aopu.aop_dir,
8733 AOP(result)->aopu.aop_dir);
8735 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8736 AOP(result)->aopu.aop_dir,
8737 AOP(result)->aopu.aop_dir);
8742 /* the right is also a bit variable */
8743 if (AOP_TYPE(right) == AOP_CRY) {
8746 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8748 pic14_emitcode("clrc","");
8749 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8750 AOP(right)->aopu.aop_dir,
8751 AOP(right)->aopu.aop_dir);
8752 aopPut(AOP(result),"c",0);
8757 pic14_toBoolean(right);
8758 aopPut(AOP(result),"a",0);
8762 /* if they are the same size : or less */
8763 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8765 /* if they are in the same place */
8766 if (pic14_sameRegs(AOP(right),AOP(result)))
8769 /* if they in different places then copy */
8770 size = AOP_SIZE(result);
8774 aopGet(AOP(right),offset,FALSE,FALSE),
8782 /* if the result is of type pointer */
8783 if (IS_PTR(ctype)) {
8786 sym_link *type = operandType(right);
8787 sym_link *etype = getSpec(type);
8789 /* pointer to generic pointer */
8790 if (IS_GENPTR(ctype)) {
8794 p_type = DCL_TYPE(type);
8796 /* we have to go by the storage class */
8797 p_type = PTR_TYPE(SPEC_OCLS(etype));
8799 /* if (SPEC_OCLS(etype)->codesp ) */
8800 /* p_type = CPOINTER ; */
8802 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8803 /* p_type = FPOINTER ; */
8805 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8806 /* p_type = PPOINTER; */
8808 /* if (SPEC_OCLS(etype) == idata ) */
8809 /* p_type = IPOINTER ; */
8811 /* p_type = POINTER ; */
8814 /* the first two bytes are known */
8815 size = GPTRSIZE - 1;
8819 aopGet(AOP(right),offset,FALSE,FALSE),
8823 /* the last byte depending on type */
8840 /* this should never happen */
8841 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8842 "got unknown pointer type");
8845 aopPut(AOP(result),l, GPTRSIZE - 1);
8849 /* just copy the pointers */
8850 size = AOP_SIZE(result);
8854 aopGet(AOP(right),offset,FALSE,FALSE),
8862 if (AOP_TYPE(right) == AOP_CRY) {
8864 size = AOP_SIZE(right);
8866 emitpcode(POC_CLRF, popGet(AOP(result),0,FALSE,FALSE));
8867 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
8868 emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8870 pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8871 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8872 AOP(right)->aopu.aop_dir,
8873 AOP(right)->aopu.aop_dir);
8874 pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8876 pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8877 emitpcode(POC_CLRF, popGet(AOP(result),offset++,FALSE,FALSE));
8882 /* so we now know that the size of destination is greater
8883 than the size of the source.
8884 Now, if the next iCode is an operator then we might be
8885 able to optimize the operation without performing a cast.
8887 if(genMixedOperation(ic))
8891 /* we move to result for the size of source */
8892 size = AOP_SIZE(right);
8895 pic14_emitcode(";","%d",__LINE__);
8896 /* aopPut(AOP(result),
8897 aopGet(AOP(right),offset,FALSE,FALSE),
8899 emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8900 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8904 /* now depending on the sign of the destination */
8905 size = AOP_SIZE(result) - AOP_SIZE(right);
8906 /* if unsigned or not an integral type */
8907 if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8909 emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8910 pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8914 /* we need to extend the sign :{ */
8916 emitpcodeNULLop(POC_CLRW);
8919 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8921 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8923 emitpcode(POC_MOVLW, popGetLit(0xff));
8925 pic14_emitcode("clrw","");
8926 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8927 AOP(right)->aopu.aop_dir,
8928 AOP(right)->aopu.aop_dir);
8929 pic14_emitcode("movlw","0xff");
8931 emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8932 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8934 // aopPut(AOP(result),"a",offset++);
8939 /* we are done hurray !!!! */
8942 freeAsmop(right,NULL,ic,TRUE);
8943 freeAsmop(result,NULL,ic,TRUE);
8947 /*-----------------------------------------------------------------*/
8948 /* genDjnz - generate decrement & jump if not zero instrucion */
8949 /*-----------------------------------------------------------------*/
8950 static int genDjnz (iCode *ic, iCode *ifx)
8953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8958 /* if the if condition has a false label
8959 then we cannot save */
8963 /* if the minus is not of the form
8965 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8966 !IS_OP_LITERAL(IC_RIGHT(ic)))
8969 if (operandLitValue(IC_RIGHT(ic)) != 1)
8972 /* if the size of this greater than one then no
8974 if (getSize(operandType(IC_RESULT(ic))) > 1)
8977 /* otherwise we can save BIG */
8978 lbl = newiTempLabel(NULL);
8979 lbl1= newiTempLabel(NULL);
8981 aopOp(IC_RESULT(ic),ic,FALSE);
8983 if (IS_AOP_PREG(IC_RESULT(ic))) {
8984 pic14_emitcode("dec","%s",
8985 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8986 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8987 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8991 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8992 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8994 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8995 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8998 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
8999 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9000 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9001 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9004 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9009 /*-----------------------------------------------------------------*/
9010 /* genReceive - generate code for a receive iCode */
9011 /*-----------------------------------------------------------------*/
9012 static void genReceive (iCode *ic)
9014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9016 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9017 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9018 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9020 int size = getSize(operandType(IC_RESULT(ic)));
9021 int offset = fReturnSizePic - size;
9023 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9024 fReturn[fReturnSizePic - offset - 1] : "acc"));
9027 aopOp(IC_RESULT(ic),ic,FALSE);
9028 size = AOP_SIZE(IC_RESULT(ic));
9031 pic14_emitcode ("pop","acc");
9032 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9037 aopOp(IC_RESULT(ic),ic,FALSE);
9039 assignResultValue(IC_RESULT(ic));
9042 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9045 /*-----------------------------------------------------------------*/
9046 /* genpic14Code - generate code for pic14 based controllers */
9047 /*-----------------------------------------------------------------*/
9049 * At this point, ralloc.c has gone through the iCode and attempted
9050 * to optimize in a way suitable for a PIC. Now we've got to generate
9051 * PIC instructions that correspond to the iCode.
9053 * Once the instructions are generated, we'll pass through both the
9054 * peep hole optimizer and the pCode optimizer.
9055 *-----------------------------------------------------------------*/
9057 void genpic14Code (iCode *lic)
9062 lineHead = lineCurr = NULL;
9064 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9067 /* if debug information required */
9068 /* if (options.debug && currFunc) { */
9070 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9072 if (IS_STATIC(currFunc->etype)) {
9073 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9074 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9076 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9077 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9083 for (ic = lic ; ic ; ic = ic->next ) {
9085 DEBUGpic14_emitcode(";ic","");
9086 if ( cln != ic->lineno ) {
9087 if ( options.debug ) {
9089 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9090 FileBaseName(ic->filename),ic->lineno,
9091 ic->level,ic->block);
9094 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9097 /* if the result is marked as
9098 spilt and rematerializable or code for
9099 this has already been generated then
9101 if (resultRemat(ic) || ic->generated )
9104 /* depending on the operation */
9123 /* IPOP happens only when trying to restore a
9124 spilt live range, if there is an ifx statement
9125 following this pop then the if statement might
9126 be using some of the registers being popped which
9127 would destory the contents of the register so
9128 we need to check for this condition and handle it */
9130 ic->next->op == IFX &&
9131 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9132 genIfx (ic->next,ic);
9150 genEndFunction (ic);
9170 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9187 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9191 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9198 /* note these two are xlated by algebraic equivalence
9199 during parsing SDCC.y */
9200 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9201 "got '>=' or '<=' shouldn't have come here");
9205 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9217 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9221 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9225 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9252 case GET_VALUE_AT_ADDRESS:
9257 if (POINTER_SET(ic))
9284 addSet(&_G.sendSet,ic);
9293 /* now we are ready to call the
9294 peep hole optimizer */
9295 if (!options.nopeep) {
9296 printf("peep hole optimizing\n");
9297 peepHole (&lineHead);
9299 /* now do the actual printing */
9300 printLine (lineHead,codeOutFile);
9302 printf("printing pBlock\n\n");
9303 printpBlock(stdout,pb);