1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 static int labelOffset=0;
64 static int debug_verbose=1;
65 static int optimized_for_speed = 0;
67 /* max_key keeps track of the largest label number used in
68 a function. This is then used to adjust the label offset
69 for the next function.
72 static int GpsuedoStkPtr=0;
74 unsigned int pic14aopLiteral (value *val, int offset);
75 const char *AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic14;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic14_ptrRegReq ;
119 extern int pic14_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
176 char lb[INITIAL_INLINEASM];
186 sprintf(lb,"%s\t",inst);
188 sprintf(lb,"%s",inst);
189 vsprintf(lb+(strlen(lb)),fmt,ap);
193 while (isspace(*lbp)) lbp++;
196 lineCurr = (lineCurr ?
197 connectLine(lineCurr,newLineNode(lb)) :
198 (lineHead = newLineNode(lb)));
199 lineCurr->isInline = _G.inLine;
200 lineCurr->isDebug = _G.debugLine;
202 addpCode2pBlock(pb,newpCodeCharP(lb));
208 static void emitpLabel(int key)
210 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
213 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
229 /*-----------------------------------------------------------------*/
230 /* pic14_emitcode - writes the code into a file : for now it is simple */
231 /*-----------------------------------------------------------------*/
232 void pic14_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
242 sprintf(lb,"%s\t",inst);
244 sprintf(lb,"%s",inst);
245 vsprintf(lb+(strlen(lb)),fmt,ap);
249 while (isspace(*lbp)) lbp++;
252 lineCurr = (lineCurr ?
253 connectLine(lineCurr,newLineNode(lb)) :
254 (lineHead = newLineNode(lb)));
255 lineCurr->isInline = _G.inLine;
256 lineCurr->isDebug = _G.debugLine;
259 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
267 /*-----------------------------------------------------------------*/
268 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
270 bool r0iu = FALSE , r1iu = FALSE;
271 bool r0ou = FALSE , r1ou = FALSE;
273 /* the logic: if r0 & r1 used in the instruction
274 then we are in trouble otherwise */
276 /* first check if r0 & r1 are used by this
277 instruction, in which case we are in trouble */
278 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
279 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
284 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
285 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
287 /* if no usage of r0 then return it */
288 if (!r0iu && !r0ou) {
289 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
290 (*aopp)->type = AOP_R0;
292 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
295 /* if no usage of r1 then return it */
296 if (!r1iu && !r1ou) {
297 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
298 (*aopp)->type = AOP_R1;
300 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
303 /* now we know they both have usage */
304 /* if r0 not used in this instruction */
306 /* push it if not already pushed */
308 //pic14_emitcode ("push","%s",
309 // pic14_regWithIdx(R0_IDX)->dname);
313 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
314 (*aopp)->type = AOP_R0;
316 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
319 /* if r1 not used then */
322 /* push it if not already pushed */
324 //pic14_emitcode ("push","%s",
325 // pic14_regWithIdx(R1_IDX)->dname);
329 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
330 (*aopp)->type = AOP_R1;
331 return pic14_regWithIdx(R1_IDX);
335 /* I said end of world but not quite end of world yet */
336 /* if this is a result then we can push it on the stack*/
338 (*aopp)->type = AOP_STK;
342 /* other wise this is true end of the world */
343 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
344 "getFreePtr should never reach here");
348 /*-----------------------------------------------------------------*/
349 /* newAsmop - creates a new asmOp */
350 /*-----------------------------------------------------------------*/
351 asmop *newAsmop (short type)
355 aop = Safe_calloc(1,sizeof(asmop));
360 static void genSetDPTR(int n)
364 pic14_emitcode(";", "Select standard DPTR");
365 pic14_emitcode("mov", "dps, #0x00");
369 pic14_emitcode(";", "Select alternate DPTR");
370 pic14_emitcode("mov", "dps, #0x01");
374 /*-----------------------------------------------------------------*/
375 /* resolveIfx - converts an iCode ifx into a form more useful for */
376 /* generating code */
377 /*-----------------------------------------------------------------*/
378 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
385 resIfx->condition = 1; /* assume that the ifx is true */
386 resIfx->generated = 0; /* indicate that the ifx has not been used */
389 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
390 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
391 __FUNCTION__,__LINE__,resIfx->lbl->key);
394 resIfx->lbl = IC_TRUE(ifx);
396 resIfx->lbl = IC_FALSE(ifx);
397 resIfx->condition = 0;
400 DEBUGpic14_emitcode("; ***","ifx true is non-null");
402 DEBUGpic14_emitcode("; ***","ifx false is non-null");
405 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
408 /*-----------------------------------------------------------------*/
409 /* pointerCode - returns the code for a pointer type */
410 /*-----------------------------------------------------------------*/
411 static int pointerCode (sym_link *etype)
414 return PTR_TYPE(SPEC_OCLS(etype));
418 /*-----------------------------------------------------------------*/
419 /* aopForSym - for a true symbol */
420 /*-----------------------------------------------------------------*/
421 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
424 memmap *space= SPEC_OCLS(sym->etype);
426 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
427 /* if already has one */
431 /* assign depending on the storage class */
432 /* if it is on the stack or indirectly addressable */
433 /* space we need to assign either r0 or r1 to it */
434 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
435 sym->aop = aop = newAsmop(0);
436 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
437 aop->size = getSize(sym->type);
439 /* now assign the address of the variable to
440 the pointer register */
441 if (aop->type != AOP_STK) {
445 pic14_emitcode("push","acc");
447 pic14_emitcode("mov","a,_bp");
448 pic14_emitcode("add","a,#0x%02x",
450 ((char)(sym->stack - _G.nRegsSaved )) :
451 ((char)sym->stack)) & 0xff);
452 pic14_emitcode("mov","%s,a",
453 aop->aopu.aop_ptr->name);
456 pic14_emitcode("pop","acc");
458 pic14_emitcode("mov","%s,#%s",
459 aop->aopu.aop_ptr->name,
461 aop->paged = space->paged;
463 aop->aopu.aop_stk = sym->stack;
467 if (sym->onStack && options.stack10bit)
469 /* It's on the 10 bit stack, which is located in
473 //DEBUGpic14_emitcode(";","%d",__LINE__);
476 pic14_emitcode("push","acc");
478 pic14_emitcode("mov","a,_bp");
479 pic14_emitcode("add","a,#0x%02x",
481 ((char)(sym->stack - _G.nRegsSaved )) :
482 ((char)sym->stack)) & 0xff);
485 pic14_emitcode ("mov","dpx1,#0x40");
486 pic14_emitcode ("mov","dph1,#0x00");
487 pic14_emitcode ("mov","dpl1, a");
491 pic14_emitcode("pop","acc");
493 sym->aop = aop = newAsmop(AOP_DPTR2);
494 aop->size = getSize(sym->type);
498 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 /* if in bit space */
500 if (IN_BITSPACE(space)) {
501 sym->aop = aop = newAsmop (AOP_CRY);
502 aop->aopu.aop_dir = sym->rname ;
503 aop->size = getSize(sym->type);
504 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
507 /* if it is in direct space */
508 if (IN_DIRSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_DIR);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
516 /* special case for a function */
517 if (IS_FUNC(sym->type)) {
518 sym->aop = aop = newAsmop(AOP_IMMD);
519 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
520 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
521 strcpy(aop->aopu.aop_immd,sym->rname);
522 aop->size = FPTRSIZE;
523 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
528 /* only remaining is far space */
529 /* in which case DPTR gets the address */
530 sym->aop = aop = newAsmop(AOP_DPTR);
531 pic14_emitcode ("mov","dptr,#%s", sym->rname);
532 aop->size = getSize(sym->type);
534 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
535 /* if it is in code space */
536 if (IN_CODESPACE(space))
542 /*-----------------------------------------------------------------*/
543 /* aopForRemat - rematerialzes an object */
544 /*-----------------------------------------------------------------*/
545 static asmop *aopForRemat (symbol *sym)
547 iCode *ic = sym->rematiCode;
548 asmop *aop = newAsmop(AOP_IMMD);
550 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
553 val += (int) operandLitValue(IC_RIGHT(ic));
554 else if (ic->op == '-')
555 val -= (int) operandLitValue(IC_RIGHT(ic));
559 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
563 sprintf(buffer,"(%s %c 0x%04x)",
564 OP_SYMBOL(IC_LEFT(ic))->rname,
565 val >= 0 ? '+' : '-',
568 strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
570 //DEBUGpic14_emitcode(";","%s",buffer);
571 aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
572 strcpy(aop->aopu.aop_immd,buffer);
573 //aop->aopu.aop_alloc_reg = allocDirReg (IC_LEFT(ic));
574 allocDirReg (IC_LEFT(ic));
578 int aopIdx (asmop *aop, int offset)
583 if(aop->type != AOP_REG)
586 return aop->aopu.aop_reg[offset]->rIdx;
589 /*-----------------------------------------------------------------*/
590 /* regsInCommon - two operands have some registers in common */
591 /*-----------------------------------------------------------------*/
592 static bool regsInCommon (operand *op1, operand *op2)
597 /* if they have registers in common */
598 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
601 sym1 = OP_SYMBOL(op1);
602 sym2 = OP_SYMBOL(op2);
604 if (sym1->nRegs == 0 || sym2->nRegs == 0)
607 for (i = 0 ; i < sym1->nRegs ; i++) {
612 for (j = 0 ; j < sym2->nRegs ;j++ ) {
616 if (sym2->regs[j] == sym1->regs[i])
624 /*-----------------------------------------------------------------*/
625 /* operandsEqu - equivalent */
626 /*-----------------------------------------------------------------*/
627 static bool operandsEqu ( operand *op1, operand *op2)
631 /* if they not symbols */
632 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
635 sym1 = OP_SYMBOL(op1);
636 sym2 = OP_SYMBOL(op2);
638 /* if both are itemps & one is spilt
639 and the other is not then false */
640 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
641 sym1->isspilt != sym2->isspilt )
644 /* if they are the same */
648 if (strcmp(sym1->rname,sym2->rname) == 0)
652 /* if left is a tmp & right is not */
656 (sym1->usl.spillLoc == sym2))
663 (sym2->usl.spillLoc == sym1))
669 /*-----------------------------------------------------------------*/
670 /* pic14_sameRegs - two asmops have the same registers */
671 /*-----------------------------------------------------------------*/
672 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
679 if (aop1->type != AOP_REG ||
680 aop2->type != AOP_REG )
683 if (aop1->size != aop2->size )
686 for (i = 0 ; i < aop1->size ; i++ )
687 if (aop1->aopu.aop_reg[i] !=
688 aop2->aopu.aop_reg[i] )
694 /*-----------------------------------------------------------------*/
695 /* aopOp - allocates an asmop for an operand : */
696 /*-----------------------------------------------------------------*/
697 void aopOp (operand *op, iCode *ic, bool result)
706 // DEBUGpic14_emitcode(";","%d",__LINE__);
707 /* if this a literal */
708 if (IS_OP_LITERAL(op)) {
709 op->aop = aop = newAsmop(AOP_LIT);
710 aop->aopu.aop_lit = op->operand.valOperand;
711 aop->size = getSize(operandType(op));
716 sym_link *type = operandType(op);
717 if(IS_PTR_CONST(type))
718 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
721 /* if already has a asmop then continue */
725 /* if the underlying symbol has a aop */
726 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
727 DEBUGpic14_emitcode(";","%d",__LINE__);
728 op->aop = OP_SYMBOL(op)->aop;
732 /* if this is a true symbol */
733 if (IS_TRUE_SYMOP(op)) {
734 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
735 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
739 /* this is a temporary : this has
745 e) can be a return use only */
750 /* if the type is a conditional */
751 if (sym->regType == REG_CND) {
752 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
757 /* if it is spilt then two situations
759 b) has a spill location */
760 if (sym->isspilt || sym->nRegs == 0) {
762 DEBUGpic14_emitcode(";","%d",__LINE__);
763 /* rematerialize it NOW */
765 sym->aop = op->aop = aop =
767 aop->size = getSize(sym->type);
773 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
774 aop->size = getSize(sym->type);
775 for ( i = 0 ; i < 2 ; i++ )
776 aop->aopu.aop_str[i] = accUse[i];
777 DEBUGpic14_emitcode(";","%d",__LINE__);
783 aop = op->aop = sym->aop = newAsmop(AOP_STR);
784 aop->size = getSize(sym->type);
785 for ( i = 0 ; i < fReturnSizePic ; i++ )
786 aop->aopu.aop_str[i] = fReturn[i];
787 DEBUGpic14_emitcode(";","%d",__LINE__);
791 /* else spill location */
792 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
793 /* force a new aop if sizes differ */
794 sym->usl.spillLoc->aop = NULL;
796 DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
797 sym->aop = op->aop = aop =
798 aopForSym(ic,sym->usl.spillLoc,result);
799 aop->size = getSize(sym->type);
804 sym_link *type = operandType(op);
805 if(IS_PTR_CONST(type))
806 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
809 /* must be in a register */
810 sym->aop = op->aop = aop = newAsmop(AOP_REG);
811 aop->size = sym->nRegs;
812 for ( i = 0 ; i < sym->nRegs ;i++)
813 aop->aopu.aop_reg[i] = sym->regs[i];
816 /*-----------------------------------------------------------------*/
817 /* freeAsmop - free up the asmop given to an operand */
818 /*----------------------------------------------------------------*/
819 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
836 /* depending on the asmop type only three cases need work AOP_RO
837 , AOP_R1 && AOP_STK */
843 pic14_emitcode ("pop","ar0");
847 bitVectUnSetBit(ic->rUsed,R0_IDX);
853 pic14_emitcode ("pop","ar1");
857 bitVectUnSetBit(ic->rUsed,R1_IDX);
863 int stk = aop->aopu.aop_stk + aop->size;
864 bitVectUnSetBit(ic->rUsed,R0_IDX);
865 bitVectUnSetBit(ic->rUsed,R1_IDX);
867 getFreePtr(ic,&aop,FALSE);
869 if (options.stack10bit)
871 /* I'm not sure what to do here yet... */
874 "*** Warning: probably generating bad code for "
875 "10 bit stack mode.\n");
879 pic14_emitcode ("mov","a,_bp");
880 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
881 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
883 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
887 pic14_emitcode("pop","acc");
888 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
890 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
893 freeAsmop(op,NULL,ic,TRUE);
895 pic14_emitcode("pop","ar0");
900 pic14_emitcode("pop","ar1");
908 /* all other cases just dealloc */
912 OP_SYMBOL(op)->aop = NULL;
913 /* if the symbol has a spill */
915 SPIL_LOC(op)->aop = NULL;
920 /*-----------------------------------------------------------------*/
921 /* aopGet - for fetching value of the aop */
922 /*-----------------------------------------------------------------*/
923 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
928 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
929 /* offset is greater than
931 if (offset > (aop->size - 1) &&
932 aop->type != AOP_LIT)
935 /* depending on type */
940 DEBUGpic14_emitcode(";","%d",__LINE__);
941 /* if we need to increment it */
942 while (offset > aop->coff) {
943 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
947 while (offset < aop->coff) {
948 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
954 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
955 return (dname ? "acc" : "a");
957 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
958 rs = Safe_calloc(1,strlen(s)+1);
964 DEBUGpic14_emitcode(";","%d",__LINE__);
965 if (aop->type == AOP_DPTR2)
970 while (offset > aop->coff) {
971 pic14_emitcode ("inc","dptr");
975 while (offset < aop->coff) {
976 pic14_emitcode("lcall","__decdptr");
982 pic14_emitcode("clr","a");
983 pic14_emitcode("movc","a,@a+dptr");
986 pic14_emitcode("movx","a,@dptr");
989 if (aop->type == AOP_DPTR2)
994 return (dname ? "acc" : "a");
999 sprintf (s,"%s",aop->aopu.aop_immd);
1002 sprintf(s,"(%s >> %d)",
1007 aop->aopu.aop_immd);
1008 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1009 rs = Safe_calloc(1,strlen(s)+1);
1015 sprintf(s,"(%s + %d)",
1019 sprintf(s,"%s",aop->aopu.aop_dir);
1020 rs = Safe_calloc(1,strlen(s)+1);
1026 // return aop->aopu.aop_reg[offset]->dname;
1028 return aop->aopu.aop_reg[offset]->name;
1031 //pic14_emitcode(";","%d",__LINE__);
1032 return aop->aopu.aop_dir;
1035 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1036 return "AOP_accumulator_bug";
1039 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1040 rs = Safe_calloc(1,strlen(s)+1);
1045 DEBUGpic14_emitcode(";","%d",__LINE__);
1046 aop->coff = offset ;
1047 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1051 return aop->aopu.aop_str[offset];
1055 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1056 "aopget got unsupported aop->type");
1060 /*-----------------------------------------------------------------*/
1061 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1062 /*-----------------------------------------------------------------*/
1063 pCodeOp *popGetLabel(unsigned int key)
1066 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1071 return newpCodeOpLabel(NULL,key+100+labelOffset);
1074 /*-----------------------------------------------------------------*/
1075 /* popCopyReg - copy a pcode operator */
1076 /*-----------------------------------------------------------------*/
1077 pCodeOp *popCopyReg(pCodeOpReg *pc)
1081 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1082 pcor->pcop.type = pc->pcop.type;
1083 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1084 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1086 pcor->rIdx = pc->rIdx;
1089 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1093 /*-----------------------------------------------------------------*/
1094 /* popGet - asm operator to pcode operator conversion */
1095 /*-----------------------------------------------------------------*/
1096 pCodeOp *popGetLit(unsigned int lit)
1099 return newpCodeOpLit(lit);
1103 /*-----------------------------------------------------------------*/
1104 /* popGetImmd - asm operator to pcode immediate conversion */
1105 /*-----------------------------------------------------------------*/
1106 pCodeOp *popGetImmd(char *name, unsigned int offset)
1109 return newpCodeOpImmd(name, offset);
1113 /*-----------------------------------------------------------------*/
1114 /* popGet - asm operator to pcode operator conversion */
1115 /*-----------------------------------------------------------------*/
1116 pCodeOp *popGetWithString(char *str)
1122 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1126 pcop = newpCodeOp(str,PO_STR);
1131 pCodeOp *popRegFromString(char *str)
1134 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1135 pcop->type = PO_DIR;
1137 DEBUGpic14_emitcode(";","%d",__LINE__);
1138 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1143 pCodeOp *popRegFromIdx(int rIdx)
1147 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1148 __FUNCTION__,__LINE__,rIdx);
1150 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1152 PCOR(pcop)->rIdx = rIdx;
1153 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1154 PCOR(pcop)->r->isFree = 0;
1155 PCOR(pcop)->r->wasUsed = 1;
1157 pcop->type = PCOR(pcop)->r->pc_type;
1162 /*-----------------------------------------------------------------*/
1163 /* popGet - asm operator to pcode operator conversion */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1172 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1173 /* offset is greater than
1176 if (offset > (aop->size - 1) &&
1177 aop->type != AOP_LIT)
1178 return NULL; //zero;
1180 /* depending on type */
1181 switch (aop->type) {
1188 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1192 DEBUGpic14_emitcode(";","%d",__LINE__);
1193 return popGetImmd(aop->aopu.aop_immd,offset);
1196 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1197 pcop->type = PO_DIR;
1200 sprintf(s,"(%s + %d)",
1204 sprintf(s,"%s",aop->aopu.aop_dir);
1205 pcop->name = Safe_calloc(1,strlen(s)+1);
1206 strcpy(pcop->name,s);
1207 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1208 if(PCOR(pcop)->r == NULL)
1209 fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1211 PCOR(pcop)->instance = offset;
1217 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1219 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1220 PCOR(pcop)->rIdx = rIdx;
1221 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1222 PCOR(pcop)->instance = offset;
1223 pcop->type = PCOR(pcop)->r->pc_type;
1224 //rs = aop->aopu.aop_reg[offset]->name;
1225 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1230 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1231 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1232 if(PCOR(pcop)->r == NULL)
1233 fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1237 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1240 DEBUGpic14_emitcode(";","%d",__LINE__);
1241 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1243 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1244 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1245 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1246 pcop->type = PCOR(pcop)->r->pc_type;
1247 pcop->name = PCOR(pcop)->r->name;
1253 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1254 "popGet got unsupported aop->type");
1257 /*-----------------------------------------------------------------*/
1258 /* aopPut - puts a string for a aop */
1259 /*-----------------------------------------------------------------*/
1260 void aopPut (asmop *aop, char *s, int offset)
1265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1267 if (aop->size && offset > ( aop->size - 1)) {
1268 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1269 "aopPut got offset > aop->size");
1273 /* will assign value to value */
1274 /* depending on where it is ofcourse */
1275 switch (aop->type) {
1278 sprintf(d,"(%s + %d)",
1279 aop->aopu.aop_dir,offset);
1281 sprintf(d,"%s",aop->aopu.aop_dir);
1284 DEBUGpic14_emitcode(";","%d",__LINE__);
1286 pic14_emitcode("movf","%s,w",s);
1287 pic14_emitcode("movwf","%s",d);
1290 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1291 if(offset >= aop->size) {
1292 emitpcode(POC_CLRF,popGet(aop,offset));
1295 emitpcode(POC_MOVLW,popGetImmd(s,offset));
1298 emitpcode(POC_MOVWF,popGet(aop,offset));
1305 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1306 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1309 strcmp(s,"r0") == 0 ||
1310 strcmp(s,"r1") == 0 ||
1311 strcmp(s,"r2") == 0 ||
1312 strcmp(s,"r3") == 0 ||
1313 strcmp(s,"r4") == 0 ||
1314 strcmp(s,"r5") == 0 ||
1315 strcmp(s,"r6") == 0 ||
1316 strcmp(s,"r7") == 0 )
1317 pic14_emitcode("mov","%s,%s ; %d",
1318 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1323 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1325 pic14_emitcode("movwf","%s",
1326 aop->aopu.aop_reg[offset]->name);
1329 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1330 pcop->type = PO_GPR_REGISTER;
1332 PCOR(pcop)->rIdx = -1;
1333 PCOR(pcop)->r = NULL;
1335 DEBUGpic14_emitcode(";","%d",__LINE__);
1336 pcop->name = Safe_strdup(s);
1337 emitpcode(POC_MOVFW,pcop);
1339 emitpcode(POC_MOVWF,popGet(aop,offset));
1347 if (aop->type == AOP_DPTR2)
1353 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1354 "aopPut writting to code space");
1358 while (offset > aop->coff) {
1360 pic14_emitcode ("inc","dptr");
1363 while (offset < aop->coff) {
1365 pic14_emitcode("lcall","__decdptr");
1370 /* if not in accumulater */
1373 pic14_emitcode ("movx","@dptr,a");
1375 if (aop->type == AOP_DPTR2)
1383 while (offset > aop->coff) {
1385 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1387 while (offset < aop->coff) {
1389 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1395 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1400 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1402 if (strcmp(s,"r0") == 0 ||
1403 strcmp(s,"r1") == 0 ||
1404 strcmp(s,"r2") == 0 ||
1405 strcmp(s,"r3") == 0 ||
1406 strcmp(s,"r4") == 0 ||
1407 strcmp(s,"r5") == 0 ||
1408 strcmp(s,"r6") == 0 ||
1409 strcmp(s,"r7") == 0 ) {
1411 sprintf(buffer,"a%s",s);
1412 pic14_emitcode("mov","@%s,%s",
1413 aop->aopu.aop_ptr->name,buffer);
1415 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1420 if (strcmp(s,"a") == 0)
1421 pic14_emitcode("push","acc");
1423 pic14_emitcode("push","%s",s);
1428 /* if bit variable */
1429 if (!aop->aopu.aop_dir) {
1430 pic14_emitcode("clr","a");
1431 pic14_emitcode("rlc","a");
1434 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1437 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1440 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1442 lbl = newiTempLabel(NULL);
1444 if (strcmp(s,"a")) {
1447 pic14_emitcode("clr","c");
1448 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1449 pic14_emitcode("cpl","c");
1450 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1451 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1458 if (strcmp(aop->aopu.aop_str[offset],s))
1459 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1464 if (!offset && (strcmp(s,"acc") == 0))
1467 if (strcmp(aop->aopu.aop_str[offset],s))
1468 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1472 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1473 "aopPut got unsupported aop->type");
1479 /*-----------------------------------------------------------------*/
1480 /* reAdjustPreg - points a register back to where it should */
1481 /*-----------------------------------------------------------------*/
1482 static void reAdjustPreg (asmop *aop)
1486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1488 if ((size = aop->size) <= 1)
1491 switch (aop->type) {
1495 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1499 if (aop->type == AOP_DPTR2)
1505 pic14_emitcode("lcall","__decdptr");
1508 if (aop->type == AOP_DPTR2)
1518 /*-----------------------------------------------------------------*/
1519 /* genNotFloat - generates not for float operations */
1520 /*-----------------------------------------------------------------*/
1521 static void genNotFloat (operand *op, operand *res)
1527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1528 /* we will put 127 in the first byte of
1530 aopPut(AOP(res),"#127",0);
1531 size = AOP_SIZE(op) - 1;
1534 l = aopGet(op->aop,offset++,FALSE,FALSE);
1538 pic14_emitcode("orl","a,%s",
1540 offset++,FALSE,FALSE));
1542 tlbl = newiTempLabel(NULL);
1544 tlbl = newiTempLabel(NULL);
1545 aopPut(res->aop,one,1);
1546 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1547 aopPut(res->aop,zero,1);
1548 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1550 size = res->aop->size - 2;
1552 /* put zeros in the rest */
1554 aopPut(res->aop,zero,offset++);
1558 /*-----------------------------------------------------------------*/
1559 /* opIsGptr: returns non-zero if the passed operand is */
1560 /* a generic pointer type. */
1561 /*-----------------------------------------------------------------*/
1562 static int opIsGptr(operand *op)
1564 sym_link *type = operandType(op);
1566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1567 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1575 /*-----------------------------------------------------------------*/
1576 /* pic14_getDataSize - get the operand data size */
1577 /*-----------------------------------------------------------------*/
1578 int pic14_getDataSize(operand *op)
1580 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1583 return AOP_SIZE(op);
1585 // tsd- in the pic port, the genptr size is 1, so this code here
1586 // fails. ( in the 8051 port, the size was 4).
1589 size = AOP_SIZE(op);
1590 if (size == GPTRSIZE)
1592 sym_link *type = operandType(op);
1593 if (IS_GENPTR(type))
1595 /* generic pointer; arithmetic operations
1596 * should ignore the high byte (pointer type).
1599 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1606 /*-----------------------------------------------------------------*/
1607 /* pic14_outAcc - output Acc */
1608 /*-----------------------------------------------------------------*/
1609 void pic14_outAcc(operand *result)
1612 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1613 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1616 size = pic14_getDataSize(result);
1618 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1621 /* unsigned or positive */
1623 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1628 /*-----------------------------------------------------------------*/
1629 /* pic14_outBitC - output a bit C */
1630 /*-----------------------------------------------------------------*/
1631 void pic14_outBitC(operand *result)
1634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1635 /* if the result is bit */
1636 if (AOP_TYPE(result) == AOP_CRY)
1637 aopPut(AOP(result),"c",0);
1639 pic14_emitcode("clr","a ; %d", __LINE__);
1640 pic14_emitcode("rlc","a");
1641 pic14_outAcc(result);
1645 /*-----------------------------------------------------------------*/
1646 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1647 /*-----------------------------------------------------------------*/
1648 void pic14_toBoolean(operand *oper)
1650 int size = AOP_SIZE(oper) - 1;
1653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1655 if ( AOP_TYPE(oper) != AOP_ACC) {
1656 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1659 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1664 /*-----------------------------------------------------------------*/
1665 /* genNot - generate code for ! operation */
1666 /*-----------------------------------------------------------------*/
1667 static void genNot (iCode *ic)
1670 sym_link *optype = operandType(IC_LEFT(ic));
1673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1674 /* assign asmOps to operand & result */
1675 aopOp (IC_LEFT(ic),ic,FALSE);
1676 aopOp (IC_RESULT(ic),ic,TRUE);
1678 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1679 /* if in bit space then a special case */
1680 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1681 pic14_emitcode("movlw","1<<garbage");
1682 //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1683 //pic14_emitcode("cpl","c");
1684 //pic14_outBitC(IC_RESULT(ic));
1688 /* if type float then do float */
1689 if (IS_FLOAT(optype)) {
1690 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1694 size = AOP_SIZE(IC_RESULT(ic));
1696 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1697 emitpcode(POC_ANDLW,popGetLit(1));
1698 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1701 pic14_toBoolean(IC_LEFT(ic));
1703 tlbl = newiTempLabel(NULL);
1704 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1706 pic14_outBitC(IC_RESULT(ic));
1709 /* release the aops */
1710 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1711 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1715 /*-----------------------------------------------------------------*/
1716 /* genCpl - generate code for complement */
1717 /*-----------------------------------------------------------------*/
1718 static void genCpl (iCode *ic)
1724 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1725 /* assign asmOps to operand & result */
1726 aopOp (IC_LEFT(ic),ic,FALSE);
1727 aopOp (IC_RESULT(ic),ic,TRUE);
1729 /* if both are in bit space then
1731 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1732 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1734 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1735 pic14_emitcode("cpl","c");
1736 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1740 size = AOP_SIZE(IC_RESULT(ic));
1742 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1744 pic14_emitcode("cpl","a");
1745 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1750 /* release the aops */
1751 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1752 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1755 /*-----------------------------------------------------------------*/
1756 /* genUminusFloat - unary minus for floating points */
1757 /*-----------------------------------------------------------------*/
1758 static void genUminusFloat(operand *op,operand *result)
1760 int size ,offset =0 ;
1763 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1764 /* for this we just need to flip the
1765 first it then copy the rest in place */
1766 size = AOP_SIZE(op) - 1;
1767 l = aopGet(AOP(op),3,FALSE,FALSE);
1771 pic14_emitcode("cpl","acc.7");
1772 aopPut(AOP(result),"a",3);
1776 aopGet(AOP(op),offset,FALSE,FALSE),
1782 /*-----------------------------------------------------------------*/
1783 /* genUminus - unary minus code generation */
1784 /*-----------------------------------------------------------------*/
1785 static void genUminus (iCode *ic)
1788 sym_link *optype, *rtype;
1791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1793 aopOp(IC_LEFT(ic),ic,FALSE);
1794 aopOp(IC_RESULT(ic),ic,TRUE);
1796 /* if both in bit space then special
1798 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1799 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1801 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1802 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1803 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1808 optype = operandType(IC_LEFT(ic));
1809 rtype = operandType(IC_RESULT(ic));
1811 /* if float then do float stuff */
1812 if (IS_FLOAT(optype)) {
1813 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1817 /* otherwise subtract from zero by taking the 2's complement */
1818 size = AOP_SIZE(IC_LEFT(ic));
1820 for(i=0; i<size; i++) {
1821 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1822 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1824 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1825 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1829 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1830 for(i=1; i<size; i++) {
1832 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1836 /* release the aops */
1837 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1838 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1841 /*-----------------------------------------------------------------*/
1842 /* saveRegisters - will look for a call and save the registers */
1843 /*-----------------------------------------------------------------*/
1844 static void saveRegisters(iCode *lic)
1851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1853 for (ic = lic ; ic ; ic = ic->next)
1854 if (ic->op == CALL || ic->op == PCALL)
1858 fprintf(stderr,"found parameter push with no function call\n");
1862 /* if the registers have been saved already then
1864 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1867 /* find the registers in use at this time
1868 and push them away to safety */
1869 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1873 if (options.useXstack) {
1874 if (bitVectBitValue(rsave,R0_IDX))
1875 pic14_emitcode("mov","b,r0");
1876 pic14_emitcode("mov","r0,%s",spname);
1877 for (i = 0 ; i < pic14_nRegs ; i++) {
1878 if (bitVectBitValue(rsave,i)) {
1880 pic14_emitcode("mov","a,b");
1882 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1883 pic14_emitcode("movx","@r0,a");
1884 pic14_emitcode("inc","r0");
1887 pic14_emitcode("mov","%s,r0",spname);
1888 if (bitVectBitValue(rsave,R0_IDX))
1889 pic14_emitcode("mov","r0,b");
1891 //for (i = 0 ; i < pic14_nRegs ; i++) {
1892 // if (bitVectBitValue(rsave,i))
1893 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1896 dtype = operandType(IC_LEFT(ic));
1897 if (currFunc && dtype &&
1898 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1899 IFFUNC_ISISR(currFunc->type) &&
1902 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1905 /*-----------------------------------------------------------------*/
1906 /* unsaveRegisters - pop the pushed registers */
1907 /*-----------------------------------------------------------------*/
1908 static void unsaveRegisters (iCode *ic)
1913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1914 /* find the registers in use at this time
1915 and push them away to safety */
1916 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1919 if (options.useXstack) {
1920 pic14_emitcode("mov","r0,%s",spname);
1921 for (i = pic14_nRegs ; i >= 0 ; i--) {
1922 if (bitVectBitValue(rsave,i)) {
1923 pic14_emitcode("dec","r0");
1924 pic14_emitcode("movx","a,@r0");
1926 pic14_emitcode("mov","b,a");
1928 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1932 pic14_emitcode("mov","%s,r0",spname);
1933 if (bitVectBitValue(rsave,R0_IDX))
1934 pic14_emitcode("mov","r0,b");
1936 //for (i = pic14_nRegs ; i >= 0 ; i--) {
1937 // if (bitVectBitValue(rsave,i))
1938 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1944 /*-----------------------------------------------------------------*/
1946 /*-----------------------------------------------------------------*/
1947 static void pushSide(operand * oper, int size)
1951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1953 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1954 if (AOP_TYPE(oper) != AOP_REG &&
1955 AOP_TYPE(oper) != AOP_DIR &&
1957 pic14_emitcode("mov","a,%s",l);
1958 pic14_emitcode("push","acc");
1960 pic14_emitcode("push","%s",l);
1965 /*-----------------------------------------------------------------*/
1966 /* assignResultValue - */
1967 /*-----------------------------------------------------------------*/
1968 static void assignResultValue(operand * oper)
1970 int size = AOP_SIZE(oper);
1972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1974 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
1976 if(!GpsuedoStkPtr) {
1977 /* The last byte in the assignment is in W */
1979 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1984 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1986 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1991 /*-----------------------------------------------------------------*/
1992 /* genIpush - genrate code for pushing this gets a little complex */
1993 /*-----------------------------------------------------------------*/
1994 static void genIpush (iCode *ic)
1997 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
1999 int size, offset = 0 ;
2003 /* if this is not a parm push : ie. it is spill push
2004 and spill push is always done on the local stack */
2005 if (!ic->parmPush) {
2007 /* and the item is spilt then do nothing */
2008 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2011 aopOp(IC_LEFT(ic),ic,FALSE);
2012 size = AOP_SIZE(IC_LEFT(ic));
2013 /* push it on the stack */
2015 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2020 pic14_emitcode("push","%s",l);
2025 /* this is a paramter push: in this case we call
2026 the routine to find the call and save those
2027 registers that need to be saved */
2030 /* then do the push */
2031 aopOp(IC_LEFT(ic),ic,FALSE);
2034 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2035 size = AOP_SIZE(IC_LEFT(ic));
2038 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2039 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2040 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2042 pic14_emitcode("mov","a,%s",l);
2043 pic14_emitcode("push","acc");
2045 pic14_emitcode("push","%s",l);
2048 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2052 /*-----------------------------------------------------------------*/
2053 /* genIpop - recover the registers: can happen only for spilling */
2054 /*-----------------------------------------------------------------*/
2055 static void genIpop (iCode *ic)
2057 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2062 /* if the temp was not pushed then */
2063 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2066 aopOp(IC_LEFT(ic),ic,FALSE);
2067 size = AOP_SIZE(IC_LEFT(ic));
2070 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2073 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2077 /*-----------------------------------------------------------------*/
2078 /* unsaverbank - restores the resgister bank from stack */
2079 /*-----------------------------------------------------------------*/
2080 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2082 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2090 if (options.useXstack) {
2092 r = getFreePtr(ic,&aop,FALSE);
2095 pic14_emitcode("mov","%s,_spx",r->name);
2096 pic14_emitcode("movx","a,@%s",r->name);
2097 pic14_emitcode("mov","psw,a");
2098 pic14_emitcode("dec","%s",r->name);
2101 pic14_emitcode ("pop","psw");
2104 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2105 if (options.useXstack) {
2106 pic14_emitcode("movx","a,@%s",r->name);
2107 //pic14_emitcode("mov","(%s+%d),a",
2108 // regspic14[i].base,8*bank+regspic14[i].offset);
2109 pic14_emitcode("dec","%s",r->name);
2112 pic14_emitcode("pop",""); //"(%s+%d)",
2113 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2116 if (options.useXstack) {
2118 pic14_emitcode("mov","_spx,%s",r->name);
2119 freeAsmop(NULL,aop,ic,TRUE);
2125 /*-----------------------------------------------------------------*/
2126 /* saverbank - saves an entire register bank on the stack */
2127 /*-----------------------------------------------------------------*/
2128 static void saverbank (int bank, iCode *ic, bool pushPsw)
2130 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2137 if (options.useXstack) {
2140 r = getFreePtr(ic,&aop,FALSE);
2141 pic14_emitcode("mov","%s,_spx",r->name);
2145 for (i = 0 ; i < pic14_nRegs ;i++) {
2146 if (options.useXstack) {
2147 pic14_emitcode("inc","%s",r->name);
2148 //pic14_emitcode("mov","a,(%s+%d)",
2149 // regspic14[i].base,8*bank+regspic14[i].offset);
2150 pic14_emitcode("movx","@%s,a",r->name);
2152 pic14_emitcode("push","");// "(%s+%d)",
2153 //regspic14[i].base,8*bank+regspic14[i].offset);
2157 if (options.useXstack) {
2158 pic14_emitcode("mov","a,psw");
2159 pic14_emitcode("movx","@%s,a",r->name);
2160 pic14_emitcode("inc","%s",r->name);
2161 pic14_emitcode("mov","_spx,%s",r->name);
2162 freeAsmop (NULL,aop,ic,TRUE);
2165 pic14_emitcode("push","psw");
2167 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2173 /*-----------------------------------------------------------------*/
2174 /* genCall - generates a call statement */
2175 /*-----------------------------------------------------------------*/
2176 static void genCall (iCode *ic)
2180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2182 /* if caller saves & we have not saved then */
2186 /* if we are calling a function that is not using
2187 the same register bank then we need to save the
2188 destination registers on the stack */
2189 dtype = operandType(IC_LEFT(ic));
2190 if (currFunc && dtype &&
2191 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2192 IFFUNC_ISISR(currFunc->type) &&
2195 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2197 /* if send set is not empty the assign */
2200 /* For the Pic port, there is no data stack.
2201 * So parameters passed to functions are stored
2202 * in registers. (The pCode optimizer will get
2203 * rid of most of these :).
2205 int psuedoStkPtr=-1;
2206 int firstTimeThruLoop = 1;
2208 _G.sendSet = reverseSet(_G.sendSet);
2210 /* First figure how many parameters are getting passed */
2211 for (sic = setFirstItem(_G.sendSet) ; sic ;
2212 sic = setNextItem(_G.sendSet)) {
2214 aopOp(IC_LEFT(sic),sic,FALSE);
2215 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2216 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2219 for (sic = setFirstItem(_G.sendSet) ; sic ;
2220 sic = setNextItem(_G.sendSet)) {
2221 int size, offset = 0;
2223 aopOp(IC_LEFT(sic),sic,FALSE);
2224 size = AOP_SIZE(IC_LEFT(sic));
2228 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2229 AopType(AOP_TYPE(IC_LEFT(sic))));
2231 if(!firstTimeThruLoop) {
2232 /* If this is not the first time we've been through the loop
2233 * then we need to save the parameter in a temporary
2234 * register. The last byte of the last parameter is
2236 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2239 firstTimeThruLoop=0;
2241 //if (strcmp(l,fReturn[offset])) {
2243 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2244 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2245 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2247 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2252 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2257 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2258 OP_SYMBOL(IC_LEFT(ic))->rname :
2259 OP_SYMBOL(IC_LEFT(ic))->name));
2262 /* if we need assign a result value */
2263 if ((IS_ITEMP(IC_RESULT(ic)) &&
2264 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2265 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2266 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2269 aopOp(IC_RESULT(ic),ic,FALSE);
2272 assignResultValue(IC_RESULT(ic));
2274 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2275 AopType(AOP_TYPE(IC_RESULT(ic))));
2277 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2280 /* adjust the stack for parameters if
2282 if (ic->parmBytes) {
2284 if (ic->parmBytes > 3) {
2285 pic14_emitcode("mov","a,%s",spname);
2286 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2287 pic14_emitcode("mov","%s,a",spname);
2289 for ( i = 0 ; i < ic->parmBytes ;i++)
2290 pic14_emitcode("dec","%s",spname);
2294 /* if register bank was saved then pop them */
2296 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2298 /* if we hade saved some registers then unsave them */
2299 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2300 unsaveRegisters (ic);
2305 /*-----------------------------------------------------------------*/
2306 /* genPcall - generates a call by pointer statement */
2307 /*-----------------------------------------------------------------*/
2308 static void genPcall (iCode *ic)
2311 symbol *rlbl = newiTempLabel(NULL);
2314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2315 /* if caller saves & we have not saved then */
2319 /* if we are calling a function that is not using
2320 the same register bank then we need to save the
2321 destination registers on the stack */
2322 dtype = operandType(IC_LEFT(ic));
2323 if (currFunc && dtype &&
2324 IFFUNC_ISISR(currFunc->type) &&
2325 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2326 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2329 /* push the return address on to the stack */
2330 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2331 pic14_emitcode("push","acc");
2332 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2333 pic14_emitcode("push","acc");
2335 if (options.model == MODEL_FLAT24)
2337 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2338 pic14_emitcode("push","acc");
2341 /* now push the calling address */
2342 aopOp(IC_LEFT(ic),ic,FALSE);
2344 pushSide(IC_LEFT(ic), FPTRSIZE);
2346 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2348 /* if send set is not empty the assign */
2352 for (sic = setFirstItem(_G.sendSet) ; sic ;
2353 sic = setNextItem(_G.sendSet)) {
2354 int size, offset = 0;
2355 aopOp(IC_LEFT(sic),sic,FALSE);
2356 size = AOP_SIZE(IC_LEFT(sic));
2358 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2360 if (strcmp(l,fReturn[offset]))
2361 pic14_emitcode("mov","%s,%s",
2366 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2371 pic14_emitcode("ret","");
2372 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2375 /* if we need assign a result value */
2376 if ((IS_ITEMP(IC_RESULT(ic)) &&
2377 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2378 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2379 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2382 aopOp(IC_RESULT(ic),ic,FALSE);
2385 assignResultValue(IC_RESULT(ic));
2387 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2390 /* adjust the stack for parameters if
2392 if (ic->parmBytes) {
2394 if (ic->parmBytes > 3) {
2395 pic14_emitcode("mov","a,%s",spname);
2396 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2397 pic14_emitcode("mov","%s,a",spname);
2399 for ( i = 0 ; i < ic->parmBytes ;i++)
2400 pic14_emitcode("dec","%s",spname);
2404 /* if register bank was saved then unsave them */
2405 if (currFunc && dtype &&
2406 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2407 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2409 /* if we hade saved some registers then
2412 unsaveRegisters (ic);
2416 /*-----------------------------------------------------------------*/
2417 /* resultRemat - result is rematerializable */
2418 /*-----------------------------------------------------------------*/
2419 static int resultRemat (iCode *ic)
2421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2422 if (SKIP_IC(ic) || ic->op == IFX)
2425 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2426 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2427 if (sym->remat && !POINTER_SET(ic))
2434 #if defined(__BORLANDC__) || defined(_MSC_VER)
2435 #define STRCASECMP stricmp
2437 #define STRCASECMP strcasecmp
2440 /*-----------------------------------------------------------------*/
2441 /* inExcludeList - return 1 if the string is in exclude Reg list */
2442 /*-----------------------------------------------------------------*/
2443 static bool inExcludeList(char *s)
2445 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2450 if (options.excludeRegs[i] &&
2451 STRCASECMP(options.excludeRegs[i],"none") == 0)
2454 for ( i = 0 ; options.excludeRegs[i]; i++) {
2455 if (options.excludeRegs[i] &&
2456 STRCASECMP(s,options.excludeRegs[i]) == 0)
2463 /*-----------------------------------------------------------------*/
2464 /* genFunction - generated code for function entry */
2465 /*-----------------------------------------------------------------*/
2466 static void genFunction (iCode *ic)
2471 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2473 labelOffset += (max_key+4);
2477 /* create the function header */
2478 pic14_emitcode(";","-----------------------------------------");
2479 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2480 pic14_emitcode(";","-----------------------------------------");
2482 pic14_emitcode("","%s:",sym->rname);
2483 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2485 ftype = operandType(IC_LEFT(ic));
2487 /* if critical function then turn interrupts off */
2488 if (IFFUNC_ISCRITICAL(ftype))
2489 pic14_emitcode("clr","ea");
2491 /* here we need to generate the equates for the
2492 register bank if required */
2494 if (FUNC_REGBANK(ftype) != rbank) {
2497 rbank = FUNC_REGBANK(ftype);
2498 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2499 if (strcmp(regspic14[i].base,"0") == 0)
2500 pic14_emitcode("","%s = 0x%02x",
2502 8*rbank+regspic14[i].offset);
2504 pic14_emitcode ("","%s = %s + 0x%02x",
2507 8*rbank+regspic14[i].offset);
2512 /* if this is an interrupt service routine then
2513 save acc, b, dpl, dph */
2514 if (IFFUNC_ISISR(sym->type)) {
2515 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2516 emitpcodeNULLop(POC_NOP);
2517 emitpcodeNULLop(POC_NOP);
2518 emitpcodeNULLop(POC_NOP);
2519 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2520 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2521 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2522 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2524 pBlockConvert2ISR(pb);
2526 if (!inExcludeList("acc"))
2527 pic14_emitcode ("push","acc");
2528 if (!inExcludeList("b"))
2529 pic14_emitcode ("push","b");
2530 if (!inExcludeList("dpl"))
2531 pic14_emitcode ("push","dpl");
2532 if (!inExcludeList("dph"))
2533 pic14_emitcode ("push","dph");
2534 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2536 pic14_emitcode ("push", "dpx");
2537 /* Make sure we're using standard DPTR */
2538 pic14_emitcode ("push", "dps");
2539 pic14_emitcode ("mov", "dps, #0x00");
2540 if (options.stack10bit)
2542 /* This ISR could conceivably use DPTR2. Better save it. */
2543 pic14_emitcode ("push", "dpl1");
2544 pic14_emitcode ("push", "dph1");
2545 pic14_emitcode ("push", "dpx1");
2548 /* if this isr has no bank i.e. is going to
2549 run with bank 0 , then we need to save more
2551 if (!FUNC_REGBANK(sym->type)) {
2553 /* if this function does not call any other
2554 function then we can be economical and
2555 save only those registers that are used */
2556 if (! IFFUNC_HASFCALL(sym->type)) {
2559 /* if any registers used */
2560 if (sym->regsUsed) {
2561 /* save the registers used */
2562 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2563 if (bitVectBitValue(sym->regsUsed,i) ||
2564 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2565 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2570 /* this function has a function call cannot
2571 determines register usage so we will have the
2573 saverbank(0,ic,FALSE);
2578 /* if callee-save to be used for this function
2579 then save the registers being used in this function */
2580 if (IFFUNC_CALLEESAVES(sym->type)) {
2583 /* if any registers used */
2584 if (sym->regsUsed) {
2585 /* save the registers used */
2586 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2587 if (bitVectBitValue(sym->regsUsed,i) ||
2588 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2589 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2597 /* set the register bank to the desired value */
2598 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2599 pic14_emitcode("push","psw");
2600 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2603 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2605 if (options.useXstack) {
2606 pic14_emitcode("mov","r0,%s",spname);
2607 pic14_emitcode("mov","a,_bp");
2608 pic14_emitcode("movx","@r0,a");
2609 pic14_emitcode("inc","%s",spname);
2613 /* set up the stack */
2614 pic14_emitcode ("push","_bp"); /* save the callers stack */
2616 pic14_emitcode ("mov","_bp,%s",spname);
2619 /* adjust the stack for the function */
2624 werror(W_STACK_OVERFLOW,sym->name);
2626 if (i > 3 && sym->recvSize < 4) {
2628 pic14_emitcode ("mov","a,sp");
2629 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2630 pic14_emitcode ("mov","sp,a");
2635 pic14_emitcode("inc","sp");
2640 pic14_emitcode ("mov","a,_spx");
2641 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2642 pic14_emitcode ("mov","_spx,a");
2647 /*-----------------------------------------------------------------*/
2648 /* genEndFunction - generates epilogue for functions */
2649 /*-----------------------------------------------------------------*/
2650 static void genEndFunction (iCode *ic)
2652 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2654 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2656 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2658 pic14_emitcode ("mov","%s,_bp",spname);
2661 /* if use external stack but some variables were
2662 added to the local stack then decrement the
2664 if (options.useXstack && sym->stack) {
2665 pic14_emitcode("mov","a,sp");
2666 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2667 pic14_emitcode("mov","sp,a");
2671 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2672 if (options.useXstack) {
2673 pic14_emitcode("mov","r0,%s",spname);
2674 pic14_emitcode("movx","a,@r0");
2675 pic14_emitcode("mov","_bp,a");
2676 pic14_emitcode("dec","%s",spname);
2680 pic14_emitcode ("pop","_bp");
2684 /* restore the register bank */
2685 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2686 pic14_emitcode ("pop","psw");
2688 if (IFFUNC_ISISR(sym->type)) {
2690 /* now we need to restore the registers */
2691 /* if this isr has no bank i.e. is going to
2692 run with bank 0 , then we need to save more
2694 if (!FUNC_REGBANK(sym->type)) {
2696 /* if this function does not call any other
2697 function then we can be economical and
2698 save only those registers that are used */
2699 if (! IFFUNC_HASFCALL(sym->type)) {
2702 /* if any registers used */
2703 if (sym->regsUsed) {
2704 /* save the registers used */
2705 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2706 if (bitVectBitValue(sym->regsUsed,i) ||
2707 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2708 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2713 /* this function has a function call cannot
2714 determines register usage so we will have the
2716 unsaverbank(0,ic,FALSE);
2720 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2722 if (options.stack10bit)
2724 pic14_emitcode ("pop", "dpx1");
2725 pic14_emitcode ("pop", "dph1");
2726 pic14_emitcode ("pop", "dpl1");
2728 pic14_emitcode ("pop", "dps");
2729 pic14_emitcode ("pop", "dpx");
2731 if (!inExcludeList("dph"))
2732 pic14_emitcode ("pop","dph");
2733 if (!inExcludeList("dpl"))
2734 pic14_emitcode ("pop","dpl");
2735 if (!inExcludeList("b"))
2736 pic14_emitcode ("pop","b");
2737 if (!inExcludeList("acc"))
2738 pic14_emitcode ("pop","acc");
2740 if (IFFUNC_ISCRITICAL(sym->type))
2741 pic14_emitcode("setb","ea");
2744 /* if debug then send end of function */
2745 /* if (options.debug && currFunc) { */
2748 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2749 FileBaseName(ic->filename),currFunc->lastLine,
2750 ic->level,ic->block);
2751 if (IS_STATIC(currFunc->etype))
2752 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2754 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2758 pic14_emitcode ("reti","");
2760 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2761 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2762 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2763 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2764 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2765 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2767 emitpcodeNULLop(POC_RETFIE);
2771 if (IFFUNC_ISCRITICAL(sym->type))
2772 pic14_emitcode("setb","ea");
2774 if (IFFUNC_CALLEESAVES(sym->type)) {
2777 /* if any registers used */
2778 if (sym->regsUsed) {
2779 /* save the registers used */
2780 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2781 if (bitVectBitValue(sym->regsUsed,i) ||
2782 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2783 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2789 /* if debug then send end of function */
2792 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2793 FileBaseName(ic->filename),currFunc->lastLine,
2794 ic->level,ic->block);
2795 if (IS_STATIC(currFunc->etype))
2796 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2798 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2802 pic14_emitcode ("return","");
2803 emitpcodeNULLop(POC_RETURN);
2805 /* Mark the end of a function */
2806 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2811 /*-----------------------------------------------------------------*/
2812 /* genRet - generate code for return statement */
2813 /*-----------------------------------------------------------------*/
2814 static void genRet (iCode *ic)
2816 int size,offset = 0 , pushed = 0;
2818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2819 /* if we have no return value then
2820 just generate the "ret" */
2824 /* we have something to return then
2825 move the return value into place */
2826 aopOp(IC_LEFT(ic),ic,FALSE);
2827 size = AOP_SIZE(IC_LEFT(ic));
2831 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2833 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2835 pic14_emitcode("push","%s",l);
2838 l = aopGet(AOP(IC_LEFT(ic)),offset,
2840 if (strcmp(fReturn[offset],l)) {
2841 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2842 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2843 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2845 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2848 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2849 pic14_emitcode("movwf","%s",fReturn[offset]);
2859 if (strcmp(fReturn[pushed],"a"))
2860 pic14_emitcode("pop",fReturn[pushed]);
2862 pic14_emitcode("pop","acc");
2865 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2868 /* generate a jump to the return label
2869 if the next is not the return statement */
2870 if (!(ic->next && ic->next->op == LABEL &&
2871 IC_LABEL(ic->next) == returnLabel)) {
2873 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2874 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2879 /*-----------------------------------------------------------------*/
2880 /* genLabel - generates a label */
2881 /*-----------------------------------------------------------------*/
2882 static void genLabel (iCode *ic)
2884 /* special case never generate */
2885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2886 if (IC_LABEL(ic) == entryLabel)
2889 emitpLabel(IC_LABEL(ic)->key);
2890 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2893 /*-----------------------------------------------------------------*/
2894 /* genGoto - generates a goto */
2895 /*-----------------------------------------------------------------*/
2897 static void genGoto (iCode *ic)
2899 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2900 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2904 /*-----------------------------------------------------------------*/
2905 /* genMultbits :- multiplication of bits */
2906 /*-----------------------------------------------------------------*/
2907 static void genMultbits (operand *left,
2911 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2913 if(!pic14_sameRegs(AOP(result),AOP(right)))
2914 emitpcode(POC_BSF, popGet(AOP(result),0));
2916 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2917 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2918 emitpcode(POC_BCF, popGet(AOP(result),0));
2923 /*-----------------------------------------------------------------*/
2924 /* genMultOneByte : 8 bit multiplication & division */
2925 /*-----------------------------------------------------------------*/
2926 static void genMultOneByte (operand *left,
2930 sym_link *opetype = operandType(result);
2935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2936 DEBUGpic14_AopType(__LINE__,left,right,result);
2938 /* (if two literals, the value is computed before) */
2939 /* if one literal, literal on the right */
2940 if (AOP_TYPE(left) == AOP_LIT){
2946 size = AOP_SIZE(result);
2947 /* signed or unsigned */
2948 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2949 l = aopGet(AOP(left),0,FALSE,FALSE);
2951 pic14_emitcode("mul","ab");
2952 /* if result size = 1, mul signed = mul unsigned */
2953 aopPut(AOP(result),"a",0);
2955 if (SPEC_USIGN(opetype)){
2956 aopPut(AOP(result),"b",1);
2958 /* for filling the MSBs */
2959 pic14_emitcode("clr","a");
2962 pic14_emitcode("mov","a,b");
2964 /* adjust the MSB if left or right neg */
2966 /* if one literal */
2967 if (AOP_TYPE(right) == AOP_LIT){
2968 /* AND literal negative */
2969 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2970 /* adjust MSB (c==0 after mul) */
2971 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2975 lbl = newiTempLabel(NULL);
2976 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2977 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2978 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2979 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2980 lbl = newiTempLabel(NULL);
2981 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2982 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2983 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2986 lbl = newiTempLabel(NULL);
2987 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2988 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2989 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2990 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2991 lbl = newiTempLabel(NULL);
2992 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2993 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2994 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2996 aopPut(AOP(result),"a",1);
2999 pic14_emitcode("rlc","a");
3000 pic14_emitcode("subb","a,acc");
3007 aopPut(AOP(result),"a",offset++);
3011 /*-----------------------------------------------------------------*/
3012 /* genMult - generates code for multiplication */
3013 /*-----------------------------------------------------------------*/
3014 static void genMult (iCode *ic)
3016 operand *left = IC_LEFT(ic);
3017 operand *right = IC_RIGHT(ic);
3018 operand *result= IC_RESULT(ic);
3020 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3021 /* assign the amsops */
3022 aopOp (left,ic,FALSE);
3023 aopOp (right,ic,FALSE);
3024 aopOp (result,ic,TRUE);
3026 DEBUGpic14_AopType(__LINE__,left,right,result);
3028 /* special cases first */
3030 if (AOP_TYPE(left) == AOP_CRY &&
3031 AOP_TYPE(right)== AOP_CRY) {
3032 genMultbits(left,right,result);
3036 /* if both are of size == 1 */
3037 if (AOP_SIZE(left) == 1 &&
3038 AOP_SIZE(right) == 1 ) {
3039 genMultOneByte(left,right,result);
3043 /* should have been converted to function call */
3047 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3048 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3049 freeAsmop(result,NULL,ic,TRUE);
3052 /*-----------------------------------------------------------------*/
3053 /* genDivbits :- division of bits */
3054 /*-----------------------------------------------------------------*/
3055 static void genDivbits (operand *left,
3062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3063 /* the result must be bit */
3064 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3065 l = aopGet(AOP(left),0,FALSE,FALSE);
3069 pic14_emitcode("div","ab");
3070 pic14_emitcode("rrc","a");
3071 aopPut(AOP(result),"c",0);
3074 /*-----------------------------------------------------------------*/
3075 /* genDivOneByte : 8 bit division */
3076 /*-----------------------------------------------------------------*/
3077 static void genDivOneByte (operand *left,
3081 sym_link *opetype = operandType(result);
3086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3087 size = AOP_SIZE(result) - 1;
3089 /* signed or unsigned */
3090 if (SPEC_USIGN(opetype)) {
3091 /* unsigned is easy */
3092 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3093 l = aopGet(AOP(left),0,FALSE,FALSE);
3095 pic14_emitcode("div","ab");
3096 aopPut(AOP(result),"a",0);
3098 aopPut(AOP(result),zero,offset++);
3102 /* signed is a little bit more difficult */
3104 /* save the signs of the operands */
3105 l = aopGet(AOP(left),0,FALSE,FALSE);
3107 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3108 pic14_emitcode("push","acc"); /* save it on the stack */
3110 /* now sign adjust for both left & right */
3111 l = aopGet(AOP(right),0,FALSE,FALSE);
3113 lbl = newiTempLabel(NULL);
3114 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3115 pic14_emitcode("cpl","a");
3116 pic14_emitcode("inc","a");
3117 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3118 pic14_emitcode("mov","b,a");
3120 /* sign adjust left side */
3121 l = aopGet(AOP(left),0,FALSE,FALSE);
3124 lbl = newiTempLabel(NULL);
3125 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3126 pic14_emitcode("cpl","a");
3127 pic14_emitcode("inc","a");
3128 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3130 /* now the division */
3131 pic14_emitcode("div","ab");
3132 /* we are interested in the lower order
3134 pic14_emitcode("mov","b,a");
3135 lbl = newiTempLabel(NULL);
3136 pic14_emitcode("pop","acc");
3137 /* if there was an over flow we don't
3138 adjust the sign of the result */
3139 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3140 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3142 pic14_emitcode("clr","a");
3143 pic14_emitcode("subb","a,b");
3144 pic14_emitcode("mov","b,a");
3145 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3147 /* now we are done */
3148 aopPut(AOP(result),"b",0);
3150 pic14_emitcode("mov","c,b.7");
3151 pic14_emitcode("subb","a,acc");
3154 aopPut(AOP(result),"a",offset++);
3158 /*-----------------------------------------------------------------*/
3159 /* genDiv - generates code for division */
3160 /*-----------------------------------------------------------------*/
3161 static void genDiv (iCode *ic)
3163 operand *left = IC_LEFT(ic);
3164 operand *right = IC_RIGHT(ic);
3165 operand *result= IC_RESULT(ic);
3167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3168 /* assign the amsops */
3169 aopOp (left,ic,FALSE);
3170 aopOp (right,ic,FALSE);
3171 aopOp (result,ic,TRUE);
3173 /* special cases first */
3175 if (AOP_TYPE(left) == AOP_CRY &&
3176 AOP_TYPE(right)== AOP_CRY) {
3177 genDivbits(left,right,result);
3181 /* if both are of size == 1 */
3182 if (AOP_SIZE(left) == 1 &&
3183 AOP_SIZE(right) == 1 ) {
3184 genDivOneByte(left,right,result);
3188 /* should have been converted to function call */
3191 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3192 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3193 freeAsmop(result,NULL,ic,TRUE);
3196 /*-----------------------------------------------------------------*/
3197 /* genModbits :- modulus of bits */
3198 /*-----------------------------------------------------------------*/
3199 static void genModbits (operand *left,
3206 /* the result must be bit */
3207 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3208 l = aopGet(AOP(left),0,FALSE,FALSE);
3212 pic14_emitcode("div","ab");
3213 pic14_emitcode("mov","a,b");
3214 pic14_emitcode("rrc","a");
3215 aopPut(AOP(result),"c",0);
3218 /*-----------------------------------------------------------------*/
3219 /* genModOneByte : 8 bit modulus */
3220 /*-----------------------------------------------------------------*/
3221 static void genModOneByte (operand *left,
3225 sym_link *opetype = operandType(result);
3229 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3230 /* signed or unsigned */
3231 if (SPEC_USIGN(opetype)) {
3232 /* unsigned is easy */
3233 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3234 l = aopGet(AOP(left),0,FALSE,FALSE);
3236 pic14_emitcode("div","ab");
3237 aopPut(AOP(result),"b",0);
3241 /* signed is a little bit more difficult */
3243 /* save the signs of the operands */
3244 l = aopGet(AOP(left),0,FALSE,FALSE);
3247 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3248 pic14_emitcode("push","acc"); /* save it on the stack */
3250 /* now sign adjust for both left & right */
3251 l = aopGet(AOP(right),0,FALSE,FALSE);
3254 lbl = newiTempLabel(NULL);
3255 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3256 pic14_emitcode("cpl","a");
3257 pic14_emitcode("inc","a");
3258 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3259 pic14_emitcode("mov","b,a");
3261 /* sign adjust left side */
3262 l = aopGet(AOP(left),0,FALSE,FALSE);
3265 lbl = newiTempLabel(NULL);
3266 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3267 pic14_emitcode("cpl","a");
3268 pic14_emitcode("inc","a");
3269 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3271 /* now the multiplication */
3272 pic14_emitcode("div","ab");
3273 /* we are interested in the lower order
3275 lbl = newiTempLabel(NULL);
3276 pic14_emitcode("pop","acc");
3277 /* if there was an over flow we don't
3278 adjust the sign of the result */
3279 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3280 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3282 pic14_emitcode("clr","a");
3283 pic14_emitcode("subb","a,b");
3284 pic14_emitcode("mov","b,a");
3285 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3287 /* now we are done */
3288 aopPut(AOP(result),"b",0);
3292 /*-----------------------------------------------------------------*/
3293 /* genMod - generates code for division */
3294 /*-----------------------------------------------------------------*/
3295 static void genMod (iCode *ic)
3297 operand *left = IC_LEFT(ic);
3298 operand *right = IC_RIGHT(ic);
3299 operand *result= IC_RESULT(ic);
3301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3302 /* assign the amsops */
3303 aopOp (left,ic,FALSE);
3304 aopOp (right,ic,FALSE);
3305 aopOp (result,ic,TRUE);
3307 /* special cases first */
3309 if (AOP_TYPE(left) == AOP_CRY &&
3310 AOP_TYPE(right)== AOP_CRY) {
3311 genModbits(left,right,result);
3315 /* if both are of size == 1 */
3316 if (AOP_SIZE(left) == 1 &&
3317 AOP_SIZE(right) == 1 ) {
3318 genModOneByte(left,right,result);
3322 /* should have been converted to function call */
3326 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3327 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3328 freeAsmop(result,NULL,ic,TRUE);
3331 /*-----------------------------------------------------------------*/
3332 /* genIfxJump :- will create a jump depending on the ifx */
3333 /*-----------------------------------------------------------------*/
3335 note: May need to add parameter to indicate when a variable is in bit space.
3337 static void genIfxJump (iCode *ic, char *jval)
3340 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3341 /* if true label then we jump if condition
3343 if ( IC_TRUE(ic) ) {
3345 if(strcmp(jval,"a") == 0)
3347 else if (strcmp(jval,"c") == 0)
3350 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3351 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3354 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3355 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3359 /* false label is present */
3360 if(strcmp(jval,"a") == 0)
3362 else if (strcmp(jval,"c") == 0)
3365 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3366 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3369 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3370 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3375 /* mark the icode as generated */
3379 /*-----------------------------------------------------------------*/
3381 /*-----------------------------------------------------------------*/
3382 static void genSkip(iCode *ifx,int status_bit)
3387 if ( IC_TRUE(ifx) ) {
3388 switch(status_bit) {
3403 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3404 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3408 switch(status_bit) {
3422 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3423 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3429 /*-----------------------------------------------------------------*/
3431 /*-----------------------------------------------------------------*/
3432 static void genSkipc(resolvedIfx *rifx)
3442 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3443 rifx->generated = 1;
3446 /*-----------------------------------------------------------------*/
3448 /*-----------------------------------------------------------------*/
3449 static void genSkipz2(resolvedIfx *rifx)
3459 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3460 rifx->generated = 1;
3463 /*-----------------------------------------------------------------*/
3465 /*-----------------------------------------------------------------*/
3466 static void genSkipz(iCode *ifx, int condition)
3477 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3479 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3482 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3484 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3487 /*-----------------------------------------------------------------*/
3489 /*-----------------------------------------------------------------*/
3490 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3496 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3498 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3501 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3502 rifx->generated = 1;
3506 /*-----------------------------------------------------------------*/
3507 /* genChkZeroes :- greater or less than comparison */
3508 /* For each byte in a literal that is zero, inclusive or the */
3509 /* the corresponding byte in the operand with W */
3510 /* returns true if any of the bytes are zero */
3511 /*-----------------------------------------------------------------*/
3512 static int genChkZeroes(operand *op, int lit, int size)
3519 i = (lit >> (size*8)) & 0xff;
3523 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3525 emitpcode(POC_IORFW, popGet(AOP(op),size));
3534 /*-----------------------------------------------------------------*/
3535 /* genCmp :- greater or less than comparison */
3536 /*-----------------------------------------------------------------*/
3537 static void genCmp (operand *left,operand *right,
3538 operand *result, iCode *ifx, int sign)
3540 int size, offset = 0 ;
3541 unsigned long lit = 0L,i = 0;
3542 resolvedIfx rFalseIfx;
3543 // resolvedIfx rTrueIfx;
3545 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3547 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3548 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3552 resolveIfx(&rFalseIfx,ifx);
3553 truelbl = newiTempLabel(NULL);
3555 //if(IC_TRUE(ifx) == NULL)
3556 /* if left & right are bit variables */
3557 if (AOP_TYPE(left) == AOP_CRY &&
3558 AOP_TYPE(right) == AOP_CRY ) {
3559 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3560 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3562 /* subtract right from left if at the
3563 end the carry flag is set then we know that
3564 left is greater than right */
3565 size = max(AOP_SIZE(left),AOP_SIZE(right));
3567 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3568 if((size == 1) && !sign &&
3569 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3570 symbol *lbl = newiTempLabel(NULL);
3571 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3572 aopGet(AOP(left),offset,FALSE,FALSE),
3573 aopGet(AOP(right),offset,FALSE,FALSE),
3575 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3578 symbol *lbl = newiTempLabel(NULL);
3580 if(AOP_TYPE(right) == AOP_LIT) {
3582 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3584 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3591 genSkipCond(&rFalseIfx,left,size-1,7);
3593 /* no need to compare to 0...*/
3594 /* NOTE: this is a de-generate compare that most certainly
3595 * creates some dead code. */
3596 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3598 if(ifx) ifx->generated = 1;
3605 //i = (lit >> (size*8)) & 0xff;
3606 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3608 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3610 i = ((0-lit) & 0xff);
3613 /* lit is 0x7f, all signed chars are less than
3614 * this except for 0x7f itself */
3615 emitpcode(POC_XORLW, popGetLit(0x7f));
3616 genSkipz2(&rFalseIfx);
3618 emitpcode(POC_ADDLW, popGetLit(0x80));
3619 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3620 genSkipc(&rFalseIfx);
3624 emitpcode(POC_ADDLW, popGetLit(i));
3625 genSkipc(&rFalseIfx);
3629 if(ifx) ifx->generated = 1;
3633 /* chars are out of the way. now do ints and longs */
3636 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3643 genSkipCond(&rFalseIfx,left,size,7);
3644 if(ifx) ifx->generated = 1;
3649 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3651 //rFalseIfx.condition ^= 1;
3652 //genSkipCond(&rFalseIfx,left,size,7);
3653 //rFalseIfx.condition ^= 1;
3655 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3656 if(rFalseIfx.condition)
3657 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3659 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3661 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3662 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3663 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3666 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3668 if(rFalseIfx.condition) {
3670 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3676 genSkipc(&rFalseIfx);
3677 emitpLabel(truelbl->key);
3678 if(ifx) ifx->generated = 1;
3685 if( (lit & 0xff) == 0) {
3686 /* lower byte is zero */
3687 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3688 i = ((lit >> 8) & 0xff) ^0x80;
3689 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3690 emitpcode(POC_ADDLW, popGetLit( 0x80));
3691 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3692 genSkipc(&rFalseIfx);
3695 if(ifx) ifx->generated = 1;
3700 /* Special cases for signed longs */
3701 if( (lit & 0xffffff) == 0) {
3702 /* lower byte is zero */
3703 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3704 i = ((lit >> 8*3) & 0xff) ^0x80;
3705 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3706 emitpcode(POC_ADDLW, popGetLit( 0x80));
3707 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3708 genSkipc(&rFalseIfx);
3711 if(ifx) ifx->generated = 1;
3719 if(lit & (0x80 << (size*8))) {
3720 /* lit is negative */
3721 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3723 //genSkipCond(&rFalseIfx,left,size,7);
3725 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3727 if(rFalseIfx.condition)
3728 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3730 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3734 /* lit is positive */
3735 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3736 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3737 if(rFalseIfx.condition)
3738 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3740 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3742 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3743 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3744 //rFalseIfx.condition ^= 1;
3745 //genSkipCond(&rFalseIfx,left,size,7);
3746 //rFalseIfx.condition ^= 1;
3750 This works, but is only good for ints.
3751 It also requires a "known zero" register.
3752 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3753 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3754 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3755 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3756 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3757 genSkipc(&rFalseIfx);
3759 emitpLabel(truelbl->key);
3760 if(ifx) ifx->generated = 1;
3764 /* There are no more special cases, so perform a general compare */
3766 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3767 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3771 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3773 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3775 //rFalseIfx.condition ^= 1;
3776 genSkipc(&rFalseIfx);
3778 emitpLabel(truelbl->key);
3780 if(ifx) ifx->generated = 1;
3787 /* sign is out of the way. So now do an unsigned compare */
3788 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3791 //genChkZeroes(left)
3793 /* General case - compare to an unsigned literal on the right.*/
3795 i = (lit >> (size*8)) & 0xff;
3796 emitpcode(POC_MOVLW, popGetLit(i));
3797 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3799 i = (lit >> (size*8)) & 0xff;
3802 emitpcode(POC_MOVLW, popGetLit(i));
3804 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3806 /* this byte of the lit is zero,
3807 *if it's not the last then OR in the variable */
3809 emitpcode(POC_IORFW, popGet(AOP(left),size));
3814 emitpLabel(lbl->key);
3815 //if(emitFinalCheck)
3816 genSkipc(&rFalseIfx);
3818 emitpLabel(truelbl->key);
3820 if(ifx) ifx->generated = 1;
3826 if(AOP_TYPE(left) == AOP_LIT) {
3827 //symbol *lbl = newiTempLabel(NULL);
3829 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3832 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3835 if((lit == 0) && (sign == 0)){
3838 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3840 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3842 //rFalseIfx.condition ^= 1;
3843 genSkipz2(&rFalseIfx);
3844 if(ifx) ifx->generated = 1;
3851 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3852 /* degenerate compare can never be true */
3853 if(rFalseIfx.condition == 0)
3854 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3856 if(ifx) ifx->generated = 1;
3862 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3863 emitpcode(POC_ADDLW, popGetLit(0x80));
3864 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3865 rFalseIfx.condition ^= 1;
3866 genSkipc(&rFalseIfx);
3868 rFalseIfx.condition ^= 1;
3869 genSkipCond(&rFalseIfx,right,0,7);
3874 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3875 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3877 rFalseIfx.condition ^= 1;
3878 genSkipc(&rFalseIfx);
3880 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3881 genSkipz2(&rFalseIfx);
3885 if(ifx) ifx->generated = 1;
3890 /* Size is greater than 1 */
3900 /* this means lit = 0xffffffff, or -1 */
3903 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
3904 rFalseIfx.condition ^= 1;
3905 genSkipCond(&rFalseIfx,right,size,7);
3906 if(ifx) ifx->generated = 1;
3913 if(rFalseIfx.condition) {
3914 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3915 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3918 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3920 emitpcode(POC_IORFW, popGet(AOP(right),size));
3924 if(rFalseIfx.condition) {
3925 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3926 emitpLabel(truelbl->key);
3928 rFalseIfx.condition ^= 1;
3929 genSkipCond(&rFalseIfx,right,s,7);
3932 if(ifx) ifx->generated = 1;
3937 if(lit & (0x80 << (size*8))) {
3938 /* Lit is less than zero */
3939 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
3940 //rFalseIfx.condition ^= 1;
3941 //genSkipCond(&rFalseIfx,left,size,7);
3942 //rFalseIfx.condition ^= 1;
3943 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3944 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3946 if(rFalseIfx.condition)
3947 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3949 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3953 /* Lit is greater than or equal to zero */
3954 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
3955 //rFalseIfx.condition ^= 1;
3956 //genSkipCond(&rFalseIfx,right,size,7);
3957 //rFalseIfx.condition ^= 1;
3959 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3960 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3962 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3963 if(rFalseIfx.condition)
3964 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3966 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3969 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3970 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3974 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3976 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3978 rFalseIfx.condition ^= 1;
3979 //rFalseIfx.condition = 1;
3980 genSkipc(&rFalseIfx);
3982 emitpLabel(truelbl->key);
3984 if(ifx) ifx->generated = 1;
3988 /* Unsigned compare for sizes greater than 1 */
3991 i = (lit >> (size*8)) & 0xff;
3995 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3996 emitpcode(POC_MOVLW, popGetLit(i&0xff));
3997 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3999 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4002 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4003 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4010 emitpLabel(lbl->key);
4012 rFalseIfx.condition ^= 1;
4013 genSkipc(&rFalseIfx);
4017 emitpLabel(truelbl->key);
4018 if(ifx) ifx->generated = 1;
4022 /* Compare two variables */
4024 DEBUGpic14_emitcode(";sign","%d",sign);
4028 /* Sigh. thus sucks... */
4030 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4031 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4032 emitpcode(POC_MOVLW, popGetLit(0x80));
4033 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4034 emitpcode(POC_XORFW, popGet(AOP(right),size));
4035 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4037 /* Signed char comparison */
4038 /* Special thanks to Nikolai Golovchenko for this snippet */
4039 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4040 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4041 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4042 emitpcode(POC_XORFW, popGet(AOP(left),0));
4043 emitpcode(POC_XORFW, popGet(AOP(right),0));
4044 emitpcode(POC_ADDLW, popGetLit(0x80));
4046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4047 genSkipc(&rFalseIfx);
4049 if(ifx) ifx->generated = 1;
4055 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4056 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4060 /* The rest of the bytes of a multi-byte compare */
4064 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4067 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4068 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4073 emitpLabel(lbl->key);
4075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4076 genSkipc(&rFalseIfx);
4077 if(ifx) ifx->generated = 1;
4084 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4085 pic14_outBitC(result);
4087 /* if the result is used in the next
4088 ifx conditional branch then generate
4089 code a little differently */
4091 genIfxJump (ifx,"c");
4093 pic14_outBitC(result);
4094 /* leave the result in acc */
4099 /*-----------------------------------------------------------------*/
4100 /* genCmpGt :- greater than comparison */
4101 /*-----------------------------------------------------------------*/
4102 static void genCmpGt (iCode *ic, iCode *ifx)
4104 operand *left, *right, *result;
4105 sym_link *letype , *retype;
4108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4110 right= IC_RIGHT(ic);
4111 result = IC_RESULT(ic);
4113 letype = getSpec(operandType(left));
4114 retype =getSpec(operandType(right));
4115 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4116 /* assign the amsops */
4117 aopOp (left,ic,FALSE);
4118 aopOp (right,ic,FALSE);
4119 aopOp (result,ic,TRUE);
4121 genCmp(right, left, result, ifx, sign);
4123 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4124 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4125 freeAsmop(result,NULL,ic,TRUE);
4128 /*-----------------------------------------------------------------*/
4129 /* genCmpLt - less than comparisons */
4130 /*-----------------------------------------------------------------*/
4131 static void genCmpLt (iCode *ic, iCode *ifx)
4133 operand *left, *right, *result;
4134 sym_link *letype , *retype;
4137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4139 right= IC_RIGHT(ic);
4140 result = IC_RESULT(ic);
4142 letype = getSpec(operandType(left));
4143 retype =getSpec(operandType(right));
4144 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4146 /* assign the amsops */
4147 aopOp (left,ic,FALSE);
4148 aopOp (right,ic,FALSE);
4149 aopOp (result,ic,TRUE);
4151 genCmp(left, right, result, ifx, sign);
4153 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4154 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4155 freeAsmop(result,NULL,ic,TRUE);
4158 /*-----------------------------------------------------------------*/
4159 /* genc16bit2lit - compare a 16 bit value to a literal */
4160 /*-----------------------------------------------------------------*/
4161 static void genc16bit2lit(operand *op, int lit, int offset)
4165 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4166 if( (lit&0xff) == 0)
4171 switch( BYTEofLONG(lit,i)) {
4173 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4176 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4179 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4182 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4183 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4188 switch( BYTEofLONG(lit,i)) {
4190 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4194 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4198 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4201 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4203 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4209 /*-----------------------------------------------------------------*/
4210 /* gencjneshort - compare and jump if not equal */
4211 /*-----------------------------------------------------------------*/
4212 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4214 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4219 unsigned long lit = 0L;
4220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4221 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4223 resolveIfx(&rIfx,ifx);
4224 lbl = newiTempLabel(NULL);
4227 /* if the left side is a literal or
4228 if the right is in a pointer register and left
4230 if ((AOP_TYPE(left) == AOP_LIT) ||
4231 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4236 if(AOP_TYPE(right) == AOP_LIT)
4237 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4239 /* if the right side is a literal then anything goes */
4240 if (AOP_TYPE(right) == AOP_LIT &&
4241 AOP_TYPE(left) != AOP_DIR ) {
4244 genc16bit2lit(left, lit, 0);
4246 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4251 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4252 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4254 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4258 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4266 /* if the right side is in a register or in direct space or
4267 if the left is a pointer register & right is not */
4268 else if (AOP_TYPE(right) == AOP_REG ||
4269 AOP_TYPE(right) == AOP_DIR ||
4270 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4271 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4274 genc16bit2lit(left, lit, 0);
4276 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4281 if((AOP_TYPE(left) == AOP_DIR) &&
4282 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4284 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4285 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4287 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4289 switch (lit & 0xff) {
4291 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4294 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4295 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4299 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4300 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4304 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4305 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4310 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4313 if(AOP_TYPE(result) == AOP_CRY) {
4314 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4319 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4321 /* fix me. probably need to check result size too */
4322 emitpcode(POC_CLRF,popGet(AOP(result),0));
4327 emitpcode(POC_INCF,popGet(AOP(result),0));
4337 } else if(AOP_TYPE(right) == AOP_REG &&
4338 AOP_TYPE(left) != AOP_DIR){
4341 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4342 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4343 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4348 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4353 /* right is a pointer reg need both a & b */
4355 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4357 pic14_emitcode("mov","b,%s",l);
4358 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4359 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4363 emitpLabel(lbl->key);
4370 /*-----------------------------------------------------------------*/
4371 /* gencjne - compare and jump if not equal */
4372 /*-----------------------------------------------------------------*/
4373 static void gencjne(operand *left, operand *right, iCode *ifx)
4375 symbol *tlbl = newiTempLabel(NULL);
4377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4378 gencjneshort(left, right, lbl);
4380 pic14_emitcode("mov","a,%s",one);
4381 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4382 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4383 pic14_emitcode("clr","a");
4384 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4386 emitpLabel(lbl->key);
4387 emitpLabel(tlbl->key);
4392 /*-----------------------------------------------------------------*/
4393 /* genCmpEq - generates code for equal to */
4394 /*-----------------------------------------------------------------*/
4395 static void genCmpEq (iCode *ic, iCode *ifx)
4397 operand *left, *right, *result;
4398 unsigned long lit = 0L;
4401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4404 DEBUGpic14_emitcode ("; ifx is non-null","");
4406 DEBUGpic14_emitcode ("; ifx is null","");
4408 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4409 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4410 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4412 size = max(AOP_SIZE(left),AOP_SIZE(right));
4414 DEBUGpic14_AopType(__LINE__,left,right,result);
4416 /* if literal, literal on the right or
4417 if the right is in a pointer register and left
4419 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4420 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4421 operand *tmp = right ;
4427 if(ifx && !AOP_SIZE(result)){
4429 /* if they are both bit variables */
4430 if (AOP_TYPE(left) == AOP_CRY &&
4431 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4432 if(AOP_TYPE(right) == AOP_LIT){
4433 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4435 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4436 pic14_emitcode("cpl","c");
4437 } else if(lit == 1L) {
4438 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4440 pic14_emitcode("clr","c");
4442 /* AOP_TYPE(right) == AOP_CRY */
4444 symbol *lbl = newiTempLabel(NULL);
4445 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4446 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4447 pic14_emitcode("cpl","c");
4448 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4450 /* if true label then we jump if condition
4452 tlbl = newiTempLabel(NULL);
4453 if ( IC_TRUE(ifx) ) {
4454 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4455 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4457 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4458 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4460 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4463 /* They're not both bit variables. Is the right a literal? */
4464 if(AOP_TYPE(right) == AOP_LIT) {
4465 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4470 switch(lit & 0xff) {
4472 if ( IC_TRUE(ifx) ) {
4473 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4475 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4477 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4478 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4482 if ( IC_TRUE(ifx) ) {
4483 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4485 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4487 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4488 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4492 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4494 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4499 /* end of size == 1 */
4503 genc16bit2lit(left,lit,offset);
4506 /* end of size == 2 */
4511 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4512 emitpcode(POC_IORFW,popGet(AOP(left),1));
4513 emitpcode(POC_IORFW,popGet(AOP(left),2));
4514 emitpcode(POC_IORFW,popGet(AOP(left),3));
4518 /* search for patterns that can be optimized */
4520 genc16bit2lit(left,lit,0);
4523 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4525 genc16bit2lit(left,lit,2);
4527 emitpcode(POC_IORFW,popGet(AOP(left),2));
4528 emitpcode(POC_IORFW,popGet(AOP(left),3));
4541 } else if(AOP_TYPE(right) == AOP_CRY ) {
4542 /* we know the left is not a bit, but that the right is */
4543 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4544 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4545 popGet(AOP(right),offset));
4546 emitpcode(POC_XORLW,popGetLit(1));
4548 /* if the two are equal, then W will be 0 and the Z bit is set
4549 * we could test Z now, or go ahead and check the high order bytes if
4550 * the variable we're comparing is larger than a byte. */
4553 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4555 if ( IC_TRUE(ifx) ) {
4557 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4558 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4561 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4562 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4566 /* They're both variables that are larger than bits */
4569 tlbl = newiTempLabel(NULL);
4572 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4573 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4575 if ( IC_TRUE(ifx) ) {
4578 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4579 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4582 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4583 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4587 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4588 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4592 if(s>1 && IC_TRUE(ifx)) {
4593 emitpLabel(tlbl->key);
4594 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4598 /* mark the icode as generated */
4603 /* if they are both bit variables */
4604 if (AOP_TYPE(left) == AOP_CRY &&
4605 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4606 if(AOP_TYPE(right) == AOP_LIT){
4607 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4609 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4610 pic14_emitcode("cpl","c");
4611 } else if(lit == 1L) {
4612 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4614 pic14_emitcode("clr","c");
4616 /* AOP_TYPE(right) == AOP_CRY */
4618 symbol *lbl = newiTempLabel(NULL);
4619 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4620 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4621 pic14_emitcode("cpl","c");
4622 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4625 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4626 pic14_outBitC(result);
4630 genIfxJump (ifx,"c");
4633 /* if the result is used in an arithmetic operation
4634 then put the result in place */
4635 pic14_outBitC(result);
4638 gencjne(left,right,result,ifx);
4641 gencjne(left,right,newiTempLabel(NULL));
4643 if(IC_TRUE(ifx)->key)
4644 gencjne(left,right,IC_TRUE(ifx)->key);
4646 gencjne(left,right,IC_FALSE(ifx)->key);
4650 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4651 aopPut(AOP(result),"a",0);
4656 genIfxJump (ifx,"a");
4660 /* if the result is used in an arithmetic operation
4661 then put the result in place */
4663 if (AOP_TYPE(result) != AOP_CRY)
4664 pic14_outAcc(result);
4666 /* leave the result in acc */
4670 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4671 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4672 freeAsmop(result,NULL,ic,TRUE);
4675 /*-----------------------------------------------------------------*/
4676 /* ifxForOp - returns the icode containing the ifx for operand */
4677 /*-----------------------------------------------------------------*/
4678 static iCode *ifxForOp ( operand *op, iCode *ic )
4680 /* if true symbol then needs to be assigned */
4681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4682 if (IS_TRUE_SYMOP(op))
4685 /* if this has register type condition and
4686 the next instruction is ifx with the same operand
4687 and live to of the operand is upto the ifx only then */
4689 ic->next->op == IFX &&
4690 IC_COND(ic->next)->key == op->key &&
4691 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4695 ic->next->op == IFX &&
4696 IC_COND(ic->next)->key == op->key) {
4697 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4701 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4703 ic->next->op == IFX)
4704 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4707 ic->next->op == IFX &&
4708 IC_COND(ic->next)->key == op->key) {
4709 DEBUGpic14_emitcode ("; "," key is okay");
4710 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4711 OP_SYMBOL(op)->liveTo,
4718 /*-----------------------------------------------------------------*/
4719 /* genAndOp - for && operation */
4720 /*-----------------------------------------------------------------*/
4721 static void genAndOp (iCode *ic)
4723 operand *left,*right, *result;
4726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4727 /* note here that && operations that are in an
4728 if statement are taken away by backPatchLabels
4729 only those used in arthmetic operations remain */
4730 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4731 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4732 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4734 /* if both are bit variables */
4735 if (AOP_TYPE(left) == AOP_CRY &&
4736 AOP_TYPE(right) == AOP_CRY ) {
4737 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4738 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4739 pic14_outBitC(result);
4741 tlbl = newiTempLabel(NULL);
4742 pic14_toBoolean(left);
4743 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4744 pic14_toBoolean(right);
4745 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4746 pic14_outBitAcc(result);
4749 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4750 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4751 freeAsmop(result,NULL,ic,TRUE);
4755 /*-----------------------------------------------------------------*/
4756 /* genOrOp - for || operation */
4757 /*-----------------------------------------------------------------*/
4760 modified this code, but it doesn't appear to ever get called
4763 static void genOrOp (iCode *ic)
4765 operand *left,*right, *result;
4768 /* note here that || operations that are in an
4769 if statement are taken away by backPatchLabels
4770 only those used in arthmetic operations remain */
4771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4772 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4773 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4774 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4776 DEBUGpic14_AopType(__LINE__,left,right,result);
4778 /* if both are bit variables */
4779 if (AOP_TYPE(left) == AOP_CRY &&
4780 AOP_TYPE(right) == AOP_CRY ) {
4781 pic14_emitcode("clrc","");
4782 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4783 AOP(left)->aopu.aop_dir,
4784 AOP(left)->aopu.aop_dir);
4785 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4786 AOP(right)->aopu.aop_dir,
4787 AOP(right)->aopu.aop_dir);
4788 pic14_emitcode("setc","");
4791 tlbl = newiTempLabel(NULL);
4792 pic14_toBoolean(left);
4794 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4795 pic14_toBoolean(right);
4796 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4798 pic14_outBitAcc(result);
4801 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4802 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4803 freeAsmop(result,NULL,ic,TRUE);
4806 /*-----------------------------------------------------------------*/
4807 /* isLiteralBit - test if lit == 2^n */
4808 /*-----------------------------------------------------------------*/
4809 static int isLiteralBit(unsigned long lit)
4811 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4812 0x100L,0x200L,0x400L,0x800L,
4813 0x1000L,0x2000L,0x4000L,0x8000L,
4814 0x10000L,0x20000L,0x40000L,0x80000L,
4815 0x100000L,0x200000L,0x400000L,0x800000L,
4816 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4817 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4821 for(idx = 0; idx < 32; idx++)
4827 /*-----------------------------------------------------------------*/
4828 /* continueIfTrue - */
4829 /*-----------------------------------------------------------------*/
4830 static void continueIfTrue (iCode *ic)
4832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4834 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4838 /*-----------------------------------------------------------------*/
4840 /*-----------------------------------------------------------------*/
4841 static void jumpIfTrue (iCode *ic)
4843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4845 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4849 /*-----------------------------------------------------------------*/
4850 /* jmpTrueOrFalse - */
4851 /*-----------------------------------------------------------------*/
4852 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4854 // ugly but optimized by peephole
4855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4857 symbol *nlbl = newiTempLabel(NULL);
4858 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4859 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4860 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4861 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4864 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4865 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4870 /*-----------------------------------------------------------------*/
4871 /* genAnd - code for and */
4872 /*-----------------------------------------------------------------*/
4873 static void genAnd (iCode *ic, iCode *ifx)
4875 operand *left, *right, *result;
4877 unsigned long lit = 0L;
4882 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4883 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4884 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4885 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4887 resolveIfx(&rIfx,ifx);
4889 /* if left is a literal & right is not then exchange them */
4890 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4891 AOP_NEEDSACC(left)) {
4892 operand *tmp = right ;
4897 /* if result = right then exchange them */
4898 if(pic14_sameRegs(AOP(result),AOP(right))){
4899 operand *tmp = right ;
4904 /* if right is bit then exchange them */
4905 if (AOP_TYPE(right) == AOP_CRY &&
4906 AOP_TYPE(left) != AOP_CRY){
4907 operand *tmp = right ;
4911 if(AOP_TYPE(right) == AOP_LIT)
4912 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4914 size = AOP_SIZE(result);
4916 DEBUGpic14_AopType(__LINE__,left,right,result);
4919 // result = bit & yy;
4920 if (AOP_TYPE(left) == AOP_CRY){
4921 // c = bit & literal;
4922 if(AOP_TYPE(right) == AOP_LIT){
4924 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4927 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4930 if(size && (AOP_TYPE(result) == AOP_CRY)){
4931 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4934 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4938 pic14_emitcode("clr","c");
4941 if (AOP_TYPE(right) == AOP_CRY){
4943 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4944 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4947 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4949 pic14_emitcode("rrc","a");
4950 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4956 pic14_outBitC(result);
4958 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4959 genIfxJump(ifx, "c");
4963 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4964 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4965 if((AOP_TYPE(right) == AOP_LIT) &&
4966 (AOP_TYPE(result) == AOP_CRY) &&
4967 (AOP_TYPE(left) != AOP_CRY)){
4968 int posbit = isLiteralBit(lit);
4972 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4975 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4981 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4982 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4984 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4985 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4988 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4989 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4990 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4997 symbol *tlbl = newiTempLabel(NULL);
4998 int sizel = AOP_SIZE(left);
5000 pic14_emitcode("setb","c");
5002 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5003 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5005 if((posbit = isLiteralBit(bytelit)) != 0)
5006 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5008 if(bytelit != 0x0FFL)
5009 pic14_emitcode("anl","a,%s",
5010 aopGet(AOP(right),offset,FALSE,TRUE));
5011 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5016 // bit = left & literal
5018 pic14_emitcode("clr","c");
5019 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5021 // if(left & literal)
5024 jmpTrueOrFalse(ifx, tlbl);
5028 pic14_outBitC(result);
5032 /* if left is same as result */
5033 if(pic14_sameRegs(AOP(result),AOP(left))){
5035 for(;size--; offset++,lit>>=8) {
5036 if(AOP_TYPE(right) == AOP_LIT){
5037 switch(lit & 0xff) {
5039 /* and'ing with 0 has clears the result */
5040 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5041 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5044 /* and'ing with 0xff is a nop when the result and left are the same */
5049 int p = my_powof2( (~lit) & 0xff );
5051 /* only one bit is set in the literal, so use a bcf instruction */
5052 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5053 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5056 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5057 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5058 if(know_W != (lit&0xff))
5059 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5061 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5066 if (AOP_TYPE(left) == AOP_ACC) {
5067 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5069 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5070 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5077 // left & result in different registers
5078 if(AOP_TYPE(result) == AOP_CRY){
5080 // if(size), result in bit
5081 // if(!size && ifx), conditional oper: if(left & right)
5082 symbol *tlbl = newiTempLabel(NULL);
5083 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5085 pic14_emitcode("setb","c");
5087 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5088 pic14_emitcode("anl","a,%s",
5089 aopGet(AOP(left),offset,FALSE,FALSE));
5090 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5095 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5096 pic14_outBitC(result);
5098 jmpTrueOrFalse(ifx, tlbl);
5100 for(;(size--);offset++) {
5102 // result = left & right
5103 if(AOP_TYPE(right) == AOP_LIT){
5104 int t = (lit >> (offset*8)) & 0x0FFL;
5107 pic14_emitcode("clrf","%s",
5108 aopGet(AOP(result),offset,FALSE,FALSE));
5109 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5112 pic14_emitcode("movf","%s,w",
5113 aopGet(AOP(left),offset,FALSE,FALSE));
5114 pic14_emitcode("movwf","%s",
5115 aopGet(AOP(result),offset,FALSE,FALSE));
5116 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5117 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5120 pic14_emitcode("movlw","0x%x",t);
5121 pic14_emitcode("andwf","%s,w",
5122 aopGet(AOP(left),offset,FALSE,FALSE));
5123 pic14_emitcode("movwf","%s",
5124 aopGet(AOP(result),offset,FALSE,FALSE));
5126 emitpcode(POC_MOVLW, popGetLit(t));
5127 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5128 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5133 if (AOP_TYPE(left) == AOP_ACC) {
5134 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5135 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5137 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5138 pic14_emitcode("andwf","%s,w",
5139 aopGet(AOP(left),offset,FALSE,FALSE));
5140 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5141 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5143 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5144 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5150 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5151 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5152 freeAsmop(result,NULL,ic,TRUE);
5155 /*-----------------------------------------------------------------*/
5156 /* genOr - code for or */
5157 /*-----------------------------------------------------------------*/
5158 static void genOr (iCode *ic, iCode *ifx)
5160 operand *left, *right, *result;
5162 unsigned long lit = 0L;
5164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5166 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5167 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5168 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5170 DEBUGpic14_AopType(__LINE__,left,right,result);
5172 /* if left is a literal & right is not then exchange them */
5173 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5174 AOP_NEEDSACC(left)) {
5175 operand *tmp = right ;
5180 /* if result = right then exchange them */
5181 if(pic14_sameRegs(AOP(result),AOP(right))){
5182 operand *tmp = right ;
5187 /* if right is bit then exchange them */
5188 if (AOP_TYPE(right) == AOP_CRY &&
5189 AOP_TYPE(left) != AOP_CRY){
5190 operand *tmp = right ;
5195 DEBUGpic14_AopType(__LINE__,left,right,result);
5197 if(AOP_TYPE(right) == AOP_LIT)
5198 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5200 size = AOP_SIZE(result);
5204 if (AOP_TYPE(left) == AOP_CRY){
5205 if(AOP_TYPE(right) == AOP_LIT){
5206 // c = bit & literal;
5208 // lit != 0 => result = 1
5209 if(AOP_TYPE(result) == AOP_CRY){
5211 emitpcode(POC_BSF, popGet(AOP(result),0));
5212 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5213 // AOP(result)->aopu.aop_dir,
5214 // AOP(result)->aopu.aop_dir);
5216 continueIfTrue(ifx);
5220 // lit == 0 => result = left
5221 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5223 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5226 if (AOP_TYPE(right) == AOP_CRY){
5227 if(pic14_sameRegs(AOP(result),AOP(left))){
5229 emitpcode(POC_BCF, popGet(AOP(result),0));
5230 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5231 emitpcode(POC_BSF, popGet(AOP(result),0));
5233 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5234 AOP(result)->aopu.aop_dir,
5235 AOP(result)->aopu.aop_dir);
5236 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5237 AOP(right)->aopu.aop_dir,
5238 AOP(right)->aopu.aop_dir);
5239 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5240 AOP(result)->aopu.aop_dir,
5241 AOP(result)->aopu.aop_dir);
5243 if( AOP_TYPE(result) == AOP_ACC) {
5244 emitpcode(POC_MOVLW, popGetLit(0));
5245 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5246 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5247 emitpcode(POC_MOVLW, popGetLit(1));
5251 emitpcode(POC_BCF, popGet(AOP(result),0));
5252 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5253 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5254 emitpcode(POC_BSF, popGet(AOP(result),0));
5256 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5257 AOP(result)->aopu.aop_dir,
5258 AOP(result)->aopu.aop_dir);
5259 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5260 AOP(right)->aopu.aop_dir,
5261 AOP(right)->aopu.aop_dir);
5262 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5263 AOP(left)->aopu.aop_dir,
5264 AOP(left)->aopu.aop_dir);
5265 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5266 AOP(result)->aopu.aop_dir,
5267 AOP(result)->aopu.aop_dir);
5272 symbol *tlbl = newiTempLabel(NULL);
5273 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5276 emitpcode(POC_BCF, popGet(AOP(result),0));
5277 if( AOP_TYPE(right) == AOP_ACC) {
5278 emitpcode(POC_IORLW, popGetLit(0));
5280 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5281 emitpcode(POC_BSF, popGet(AOP(result),0));
5286 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5287 pic14_emitcode(";XXX setb","c");
5288 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5289 AOP(left)->aopu.aop_dir,tlbl->key+100);
5290 pic14_toBoolean(right);
5291 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5292 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5293 jmpTrueOrFalse(ifx, tlbl);
5297 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5304 pic14_outBitC(result);
5306 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5307 genIfxJump(ifx, "c");
5311 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5312 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5313 if((AOP_TYPE(right) == AOP_LIT) &&
5314 (AOP_TYPE(result) == AOP_CRY) &&
5315 (AOP_TYPE(left) != AOP_CRY)){
5317 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5320 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5322 continueIfTrue(ifx);
5325 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5326 // lit = 0, result = boolean(left)
5328 pic14_emitcode(";XXX setb","c");
5329 pic14_toBoolean(right);
5331 symbol *tlbl = newiTempLabel(NULL);
5332 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5334 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5336 genIfxJump (ifx,"a");
5340 pic14_outBitC(result);
5344 /* if left is same as result */
5345 if(pic14_sameRegs(AOP(result),AOP(left))){
5347 for(;size--; offset++,lit>>=8) {
5348 if(AOP_TYPE(right) == AOP_LIT){
5349 if((lit & 0xff) == 0)
5350 /* or'ing with 0 has no effect */
5353 int p = my_powof2(lit & 0xff);
5355 /* only one bit is set in the literal, so use a bsf instruction */
5357 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5359 if(know_W != (lit & 0xff))
5360 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5361 know_W = lit & 0xff;
5362 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5367 if (AOP_TYPE(left) == AOP_ACC) {
5368 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5369 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5371 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5372 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5374 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5375 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5381 // left & result in different registers
5382 if(AOP_TYPE(result) == AOP_CRY){
5384 // if(size), result in bit
5385 // if(!size && ifx), conditional oper: if(left | right)
5386 symbol *tlbl = newiTempLabel(NULL);
5387 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5388 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5392 pic14_emitcode(";XXX setb","c");
5394 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5395 pic14_emitcode(";XXX orl","a,%s",
5396 aopGet(AOP(left),offset,FALSE,FALSE));
5397 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5402 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5403 pic14_outBitC(result);
5405 jmpTrueOrFalse(ifx, tlbl);
5406 } else for(;(size--);offset++){
5408 // result = left & right
5409 if(AOP_TYPE(right) == AOP_LIT){
5410 int t = (lit >> (offset*8)) & 0x0FFL;
5413 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5414 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5416 pic14_emitcode("movf","%s,w",
5417 aopGet(AOP(left),offset,FALSE,FALSE));
5418 pic14_emitcode("movwf","%s",
5419 aopGet(AOP(result),offset,FALSE,FALSE));
5422 emitpcode(POC_MOVLW, popGetLit(t));
5423 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5424 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5426 pic14_emitcode("movlw","0x%x",t);
5427 pic14_emitcode("iorwf","%s,w",
5428 aopGet(AOP(left),offset,FALSE,FALSE));
5429 pic14_emitcode("movwf","%s",
5430 aopGet(AOP(result),offset,FALSE,FALSE));
5436 // faster than result <- left, anl result,right
5437 // and better if result is SFR
5438 if (AOP_TYPE(left) == AOP_ACC) {
5439 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5440 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5442 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5443 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5445 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5446 pic14_emitcode("iorwf","%s,w",
5447 aopGet(AOP(left),offset,FALSE,FALSE));
5449 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5450 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5455 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5456 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5457 freeAsmop(result,NULL,ic,TRUE);
5460 /*-----------------------------------------------------------------*/
5461 /* genXor - code for xclusive or */
5462 /*-----------------------------------------------------------------*/
5463 static void genXor (iCode *ic, iCode *ifx)
5465 operand *left, *right, *result;
5467 unsigned long lit = 0L;
5469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5471 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5472 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5473 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5475 /* if left is a literal & right is not ||
5476 if left needs acc & right does not */
5477 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5478 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5479 operand *tmp = right ;
5484 /* if result = right then exchange them */
5485 if(pic14_sameRegs(AOP(result),AOP(right))){
5486 operand *tmp = right ;
5491 /* if right is bit then exchange them */
5492 if (AOP_TYPE(right) == AOP_CRY &&
5493 AOP_TYPE(left) != AOP_CRY){
5494 operand *tmp = right ;
5498 if(AOP_TYPE(right) == AOP_LIT)
5499 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5501 size = AOP_SIZE(result);
5505 if (AOP_TYPE(left) == AOP_CRY){
5506 if(AOP_TYPE(right) == AOP_LIT){
5507 // c = bit & literal;
5509 // lit>>1 != 0 => result = 1
5510 if(AOP_TYPE(result) == AOP_CRY){
5512 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5513 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5515 continueIfTrue(ifx);
5518 pic14_emitcode("setb","c");
5522 // lit == 0, result = left
5523 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5525 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5527 // lit == 1, result = not(left)
5528 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5529 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5530 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5531 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5534 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5535 pic14_emitcode("cpl","c");
5542 symbol *tlbl = newiTempLabel(NULL);
5543 if (AOP_TYPE(right) == AOP_CRY){
5545 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5548 int sizer = AOP_SIZE(right);
5550 // if val>>1 != 0, result = 1
5551 pic14_emitcode("setb","c");
5553 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5555 // test the msb of the lsb
5556 pic14_emitcode("anl","a,#0xfe");
5557 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5561 pic14_emitcode("rrc","a");
5563 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5564 pic14_emitcode("cpl","c");
5565 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5570 pic14_outBitC(result);
5572 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5573 genIfxJump(ifx, "c");
5577 if(pic14_sameRegs(AOP(result),AOP(left))){
5578 /* if left is same as result */
5579 for(;size--; offset++) {
5580 if(AOP_TYPE(right) == AOP_LIT){
5581 int t = (lit >> (offset*8)) & 0x0FFL;
5585 if (IS_AOP_PREG(left)) {
5586 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5587 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5588 aopPut(AOP(result),"a",offset);
5590 emitpcode(POC_MOVLW, popGetLit(t));
5591 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5592 pic14_emitcode("xrl","%s,%s",
5593 aopGet(AOP(left),offset,FALSE,TRUE),
5594 aopGet(AOP(right),offset,FALSE,FALSE));
5597 if (AOP_TYPE(left) == AOP_ACC)
5598 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5600 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5601 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5603 if (IS_AOP_PREG(left)) {
5604 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5605 aopPut(AOP(result),"a",offset);
5607 pic14_emitcode("xrl","%s,a",
5608 aopGet(AOP(left),offset,FALSE,TRUE));
5614 // left & result in different registers
5615 if(AOP_TYPE(result) == AOP_CRY){
5617 // if(size), result in bit
5618 // if(!size && ifx), conditional oper: if(left ^ right)
5619 symbol *tlbl = newiTempLabel(NULL);
5620 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5622 pic14_emitcode("setb","c");
5624 if((AOP_TYPE(right) == AOP_LIT) &&
5625 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5626 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5628 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5629 pic14_emitcode("xrl","a,%s",
5630 aopGet(AOP(left),offset,FALSE,FALSE));
5632 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5637 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5638 pic14_outBitC(result);
5640 jmpTrueOrFalse(ifx, tlbl);
5641 } else for(;(size--);offset++){
5643 // result = left & right
5644 if(AOP_TYPE(right) == AOP_LIT){
5645 int t = (lit >> (offset*8)) & 0x0FFL;
5648 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5649 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5650 pic14_emitcode("movf","%s,w",
5651 aopGet(AOP(left),offset,FALSE,FALSE));
5652 pic14_emitcode("movwf","%s",
5653 aopGet(AOP(result),offset,FALSE,FALSE));
5656 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5657 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5658 pic14_emitcode("comf","%s,w",
5659 aopGet(AOP(left),offset,FALSE,FALSE));
5660 pic14_emitcode("movwf","%s",
5661 aopGet(AOP(result),offset,FALSE,FALSE));
5664 emitpcode(POC_MOVLW, popGetLit(t));
5665 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5666 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5667 pic14_emitcode("movlw","0x%x",t);
5668 pic14_emitcode("xorwf","%s,w",
5669 aopGet(AOP(left),offset,FALSE,FALSE));
5670 pic14_emitcode("movwf","%s",
5671 aopGet(AOP(result),offset,FALSE,FALSE));
5677 // faster than result <- left, anl result,right
5678 // and better if result is SFR
5679 if (AOP_TYPE(left) == AOP_ACC) {
5680 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5681 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5683 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5684 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5685 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5686 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5688 if ( AOP_TYPE(result) != AOP_ACC){
5689 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5690 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5696 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5697 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5698 freeAsmop(result,NULL,ic,TRUE);
5701 /*-----------------------------------------------------------------*/
5702 /* genInline - write the inline code out */
5703 /*-----------------------------------------------------------------*/
5704 static void genInline (iCode *ic)
5706 char *buffer, *bp, *bp1;
5708 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5710 _G.inLine += (!options.asmpeep);
5712 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5713 strcpy(buffer,IC_INLINE(ic));
5715 /* emit each line as a code */
5719 pic14_emitcode(bp1,"");
5726 pic14_emitcode(bp1,"");
5733 pic14_emitcode(bp1,"");
5734 /* pic14_emitcode("",buffer); */
5735 _G.inLine -= (!options.asmpeep);
5738 /*-----------------------------------------------------------------*/
5739 /* genRRC - rotate right with carry */
5740 /*-----------------------------------------------------------------*/
5741 static void genRRC (iCode *ic)
5743 operand *left , *result ;
5744 int size, offset = 0, same;
5746 /* rotate right with carry */
5748 result=IC_RESULT(ic);
5749 aopOp (left,ic,FALSE);
5750 aopOp (result,ic,FALSE);
5752 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5754 same = pic14_sameRegs(AOP(result),AOP(left));
5756 size = AOP_SIZE(result);
5758 /* get the lsb and put it into the carry */
5759 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5766 emitpcode(POC_RRF, popGet(AOP(left),offset));
5768 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5769 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5775 freeAsmop(left,NULL,ic,TRUE);
5776 freeAsmop(result,NULL,ic,TRUE);
5779 /*-----------------------------------------------------------------*/
5780 /* genRLC - generate code for rotate left with carry */
5781 /*-----------------------------------------------------------------*/
5782 static void genRLC (iCode *ic)
5784 operand *left , *result ;
5785 int size, offset = 0;
5788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5789 /* rotate right with carry */
5791 result=IC_RESULT(ic);
5792 aopOp (left,ic,FALSE);
5793 aopOp (result,ic,FALSE);
5795 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5797 same = pic14_sameRegs(AOP(result),AOP(left));
5799 /* move it to the result */
5800 size = AOP_SIZE(result);
5802 /* get the msb and put it into the carry */
5803 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5810 emitpcode(POC_RLF, popGet(AOP(left),offset));
5812 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5813 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5820 freeAsmop(left,NULL,ic,TRUE);
5821 freeAsmop(result,NULL,ic,TRUE);
5824 /*-----------------------------------------------------------------*/
5825 /* genGetHbit - generates code get highest order bit */
5826 /*-----------------------------------------------------------------*/
5827 static void genGetHbit (iCode *ic)
5829 operand *left, *result;
5831 result=IC_RESULT(ic);
5832 aopOp (left,ic,FALSE);
5833 aopOp (result,ic,FALSE);
5835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5836 /* get the highest order byte into a */
5837 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5838 if(AOP_TYPE(result) == AOP_CRY){
5839 pic14_emitcode("rlc","a");
5840 pic14_outBitC(result);
5843 pic14_emitcode("rl","a");
5844 pic14_emitcode("anl","a,#0x01");
5845 pic14_outAcc(result);
5849 freeAsmop(left,NULL,ic,TRUE);
5850 freeAsmop(result,NULL,ic,TRUE);
5853 /*-----------------------------------------------------------------*/
5854 /* AccRol - rotate left accumulator by known count */
5855 /*-----------------------------------------------------------------*/
5856 static void AccRol (int shCount)
5858 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5859 shCount &= 0x0007; // shCount : 0..7
5864 pic14_emitcode("rl","a");
5867 pic14_emitcode("rl","a");
5868 pic14_emitcode("rl","a");
5871 pic14_emitcode("swap","a");
5872 pic14_emitcode("rr","a");
5875 pic14_emitcode("swap","a");
5878 pic14_emitcode("swap","a");
5879 pic14_emitcode("rl","a");
5882 pic14_emitcode("rr","a");
5883 pic14_emitcode("rr","a");
5886 pic14_emitcode("rr","a");
5891 /*-----------------------------------------------------------------*/
5892 /* AccLsh - left shift accumulator by known count */
5893 /*-----------------------------------------------------------------*/
5894 static void AccLsh (int shCount)
5896 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5899 pic14_emitcode("add","a,acc");
5902 pic14_emitcode("add","a,acc");
5903 pic14_emitcode("add","a,acc");
5905 /* rotate left accumulator */
5907 /* and kill the lower order bits */
5908 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5913 /*-----------------------------------------------------------------*/
5914 /* AccRsh - right shift accumulator by known count */
5915 /*-----------------------------------------------------------------*/
5916 static void AccRsh (int shCount)
5918 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5922 pic14_emitcode("rrc","a");
5924 /* rotate right accumulator */
5925 AccRol(8 - shCount);
5926 /* and kill the higher order bits */
5927 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5933 /*-----------------------------------------------------------------*/
5934 /* AccSRsh - signed right shift accumulator by known count */
5935 /*-----------------------------------------------------------------*/
5936 static void AccSRsh (int shCount)
5939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5942 pic14_emitcode("mov","c,acc.7");
5943 pic14_emitcode("rrc","a");
5944 } else if(shCount == 2){
5945 pic14_emitcode("mov","c,acc.7");
5946 pic14_emitcode("rrc","a");
5947 pic14_emitcode("mov","c,acc.7");
5948 pic14_emitcode("rrc","a");
5950 tlbl = newiTempLabel(NULL);
5951 /* rotate right accumulator */
5952 AccRol(8 - shCount);
5953 /* and kill the higher order bits */
5954 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5955 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5956 pic14_emitcode("orl","a,#0x%02x",
5957 (unsigned char)~SRMask[shCount]);
5958 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5963 /*-----------------------------------------------------------------*/
5964 /* shiftR1Left2Result - shift right one byte from left to result */
5965 /*-----------------------------------------------------------------*/
5966 static void shiftR1Left2ResultSigned (operand *left, int offl,
5967 operand *result, int offr,
5972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5974 same = (left == result) || (AOP(left) == AOP(result));
5978 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5980 emitpcode(POC_RRF, popGet(AOP(result),offr));
5982 emitpcode(POC_RRFW, popGet(AOP(left),offl));
5983 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
5993 /*-----------------------------------------------------------------*/
5994 /* shiftR1Left2Result - shift right one byte from left to result */
5995 /*-----------------------------------------------------------------*/
5996 static void shiftR1Left2Result (operand *left, int offl,
5997 operand *result, int offr,
5998 int shCount, int sign)
6002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6004 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6006 /* Copy the msb into the carry if signed. */
6008 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6018 emitpcode(POC_RRF, popGet(AOP(result),offr));
6020 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6021 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6027 emitpcode(POC_RRF, popGet(AOP(result),offr));
6029 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6030 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6033 emitpcode(POC_RRF, popGet(AOP(result),offr));
6038 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6040 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6041 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6044 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6045 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6046 emitpcode(POC_ANDLW, popGetLit(0x1f));
6047 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6051 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6052 emitpcode(POC_ANDLW, popGetLit(0x0f));
6053 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6057 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6058 emitpcode(POC_ANDLW, popGetLit(0x0f));
6059 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6061 emitpcode(POC_RRF, popGet(AOP(result),offr));
6066 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6067 emitpcode(POC_ANDLW, popGetLit(0x80));
6068 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6069 emitpcode(POC_RLF, popGet(AOP(result),offr));
6070 emitpcode(POC_RLF, popGet(AOP(result),offr));
6075 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6076 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6077 emitpcode(POC_RLF, popGet(AOP(result),offr));
6088 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6090 /* shift right accumulator */
6095 aopPut(AOP(result),"a",offr);
6099 /*-----------------------------------------------------------------*/
6100 /* shiftL1Left2Result - shift left one byte from left to result */
6101 /*-----------------------------------------------------------------*/
6102 static void shiftL1Left2Result (operand *left, int offl,
6103 operand *result, int offr, int shCount)
6108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6110 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6111 DEBUGpic14_emitcode ("; ***","same = %d",same);
6112 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6114 /* shift left accumulator */
6115 //AccLsh(shCount); // don't comment out just yet...
6116 // aopPut(AOP(result),"a",offr);
6120 /* Shift left 1 bit position */
6121 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6123 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6125 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6126 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6130 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6131 emitpcode(POC_ANDLW,popGetLit(0x7e));
6132 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6133 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6136 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6137 emitpcode(POC_ANDLW,popGetLit(0x3e));
6138 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6139 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6140 emitpcode(POC_RLF, popGet(AOP(result),offr));
6143 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6144 emitpcode(POC_ANDLW, popGetLit(0xf0));
6145 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6148 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6149 emitpcode(POC_ANDLW, popGetLit(0xf0));
6150 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6151 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6154 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6155 emitpcode(POC_ANDLW, popGetLit(0x30));
6156 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6157 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6158 emitpcode(POC_RLF, popGet(AOP(result),offr));
6161 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6162 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6163 emitpcode(POC_RRF, popGet(AOP(result),offr));
6167 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6172 /*-----------------------------------------------------------------*/
6173 /* movLeft2Result - move byte from left to result */
6174 /*-----------------------------------------------------------------*/
6175 static void movLeft2Result (operand *left, int offl,
6176 operand *result, int offr, int sign)
6179 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6180 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6181 l = aopGet(AOP(left),offl,FALSE,FALSE);
6183 if (*l == '@' && (IS_AOP_PREG(result))) {
6184 pic14_emitcode("mov","a,%s",l);
6185 aopPut(AOP(result),"a",offr);
6188 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6189 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6191 //aopPut(AOP(result),l,offr);
6193 /* MSB sign in acc.7 ! */
6194 if(pic14_getDataSize(left) == offl+1){
6195 pic14_emitcode("mov","a,%s",l);
6196 aopPut(AOP(result),"a",offr);
6203 /*-----------------------------------------------------------------*/
6204 /* shiftL2Left2Result - shift left two bytes from left to result */
6205 /*-----------------------------------------------------------------*/
6206 static void shiftL2Left2Result (operand *left, int offl,
6207 operand *result, int offr, int shCount)
6211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6213 if(pic14_sameRegs(AOP(result), AOP(left))) {
6221 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6222 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6223 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6227 emitpcode(POC_RLF, popGet(AOP(result),offr));
6228 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6234 emitpcode(POC_MOVLW, popGetLit(0x0f));
6235 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6236 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6237 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6238 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6239 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6240 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6242 emitpcode(POC_RLF, popGet(AOP(result),offr));
6243 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6247 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6248 emitpcode(POC_RRF, popGet(AOP(result),offr));
6249 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6250 emitpcode(POC_RRF, popGet(AOP(result),offr));
6251 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6252 emitpcode(POC_ANDLW,popGetLit(0xc0));
6253 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6254 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6255 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6256 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6259 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6260 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6261 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6262 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6263 emitpcode(POC_RRF, popGet(AOP(result),offr));
6273 /* note, use a mov/add for the shift since the mov has a
6274 chance of getting optimized out */
6275 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6276 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6278 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6279 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6283 emitpcode(POC_RLF, popGet(AOP(result),offr));
6284 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6290 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6291 emitpcode(POC_ANDLW, popGetLit(0xF0));
6292 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6293 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6294 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6295 emitpcode(POC_ANDLW, popGetLit(0xF0));
6296 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6297 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6301 emitpcode(POC_RLF, popGet(AOP(result),offr));
6302 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6306 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6307 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6308 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6309 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6311 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6312 emitpcode(POC_RRF, popGet(AOP(result),offr));
6313 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6314 emitpcode(POC_ANDLW,popGetLit(0xc0));
6315 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6316 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6317 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6318 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6321 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6322 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6323 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6324 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6325 emitpcode(POC_RRF, popGet(AOP(result),offr));
6330 /*-----------------------------------------------------------------*/
6331 /* shiftR2Left2Result - shift right two bytes from left to result */
6332 /*-----------------------------------------------------------------*/
6333 static void shiftR2Left2Result (operand *left, int offl,
6334 operand *result, int offr,
6335 int shCount, int sign)
6339 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6340 same = pic14_sameRegs(AOP(result), AOP(left));
6342 if(same && ((offl + MSB16) == offr)){
6344 /* don't crash result[offr] */
6345 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6346 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6348 movLeft2Result(left,offl, result, offr, 0);
6349 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6351 /* a:x >> shCount (x = lsb(result))*/
6354 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6356 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6366 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6367 emitpcode(POC_RRF,popGet(AOP(result),offr));
6370 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6371 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6372 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6373 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6378 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6379 emitpcode(POC_RRF,popGet(AOP(result),offr));
6386 emitpcode(POC_MOVLW, popGetLit(0xf0));
6387 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6388 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6390 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6391 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6392 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6393 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6395 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6396 emitpcode(POC_ANDLW, popGetLit(0x0f));
6397 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6399 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6400 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6401 emitpcode(POC_ANDLW, popGetLit(0xf0));
6402 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6403 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6407 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6408 emitpcode(POC_RRF, popGet(AOP(result),offr));
6416 emitpcode(POC_RLF, popGet(AOP(result),offr));
6417 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6419 emitpcode(POC_RLF, popGet(AOP(result),offr));
6420 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6421 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6422 emitpcode(POC_ANDLW,popGetLit(0x03));
6423 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6424 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6425 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6426 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6428 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6429 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6430 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6431 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6432 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6433 emitpcode(POC_RLF, popGet(AOP(result),offr));
6434 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6435 emitpcode(POC_ANDLW,popGetLit(0x03));
6436 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6441 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6442 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6443 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6444 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6445 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6450 /*-----------------------------------------------------------------*/
6451 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6452 /*-----------------------------------------------------------------*/
6453 static void shiftLLeftOrResult (operand *left, int offl,
6454 operand *result, int offr, int shCount)
6456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6457 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6458 /* shift left accumulator */
6460 /* or with result */
6461 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6462 /* back to result */
6463 aopPut(AOP(result),"a",offr);
6466 /*-----------------------------------------------------------------*/
6467 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6468 /*-----------------------------------------------------------------*/
6469 static void shiftRLeftOrResult (operand *left, int offl,
6470 operand *result, int offr, int shCount)
6472 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6473 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6474 /* shift right accumulator */
6476 /* or with result */
6477 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6478 /* back to result */
6479 aopPut(AOP(result),"a",offr);
6482 /*-----------------------------------------------------------------*/
6483 /* genlshOne - left shift a one byte quantity by known count */
6484 /*-----------------------------------------------------------------*/
6485 static void genlshOne (operand *result, operand *left, int shCount)
6487 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6488 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6491 /*-----------------------------------------------------------------*/
6492 /* genlshTwo - left shift two bytes by known amount != 0 */
6493 /*-----------------------------------------------------------------*/
6494 static void genlshTwo (operand *result,operand *left, int shCount)
6498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6499 size = pic14_getDataSize(result);
6501 /* if shCount >= 8 */
6507 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6509 movLeft2Result(left, LSB, result, MSB16, 0);
6511 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6514 /* 1 <= shCount <= 7 */
6517 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6519 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6523 /*-----------------------------------------------------------------*/
6524 /* shiftLLong - shift left one long from left to result */
6525 /* offl = LSB or MSB16 */
6526 /*-----------------------------------------------------------------*/
6527 static void shiftLLong (operand *left, operand *result, int offr )
6530 int size = AOP_SIZE(result);
6532 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6533 if(size >= LSB+offr){
6534 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6536 pic14_emitcode("add","a,acc");
6537 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6538 size >= MSB16+offr && offr != LSB )
6539 pic14_emitcode("xch","a,%s",
6540 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6542 aopPut(AOP(result),"a",LSB+offr);
6545 if(size >= MSB16+offr){
6546 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6547 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6550 pic14_emitcode("rlc","a");
6551 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6552 size >= MSB24+offr && offr != LSB)
6553 pic14_emitcode("xch","a,%s",
6554 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6556 aopPut(AOP(result),"a",MSB16+offr);
6559 if(size >= MSB24+offr){
6560 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6561 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6564 pic14_emitcode("rlc","a");
6565 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6566 size >= MSB32+offr && offr != LSB )
6567 pic14_emitcode("xch","a,%s",
6568 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6570 aopPut(AOP(result),"a",MSB24+offr);
6573 if(size > MSB32+offr){
6574 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6575 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6578 pic14_emitcode("rlc","a");
6579 aopPut(AOP(result),"a",MSB32+offr);
6582 aopPut(AOP(result),zero,LSB);
6585 /*-----------------------------------------------------------------*/
6586 /* genlshFour - shift four byte by a known amount != 0 */
6587 /*-----------------------------------------------------------------*/
6588 static void genlshFour (operand *result, operand *left, int shCount)
6592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6593 size = AOP_SIZE(result);
6595 /* if shifting more that 3 bytes */
6596 if (shCount >= 24 ) {
6599 /* lowest order of left goes to the highest
6600 order of the destination */
6601 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6603 movLeft2Result(left, LSB, result, MSB32, 0);
6604 aopPut(AOP(result),zero,LSB);
6605 aopPut(AOP(result),zero,MSB16);
6606 aopPut(AOP(result),zero,MSB32);
6610 /* more than two bytes */
6611 else if ( shCount >= 16 ) {
6612 /* lower order two bytes goes to higher order two bytes */
6614 /* if some more remaining */
6616 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6618 movLeft2Result(left, MSB16, result, MSB32, 0);
6619 movLeft2Result(left, LSB, result, MSB24, 0);
6621 aopPut(AOP(result),zero,MSB16);
6622 aopPut(AOP(result),zero,LSB);
6626 /* if more than 1 byte */
6627 else if ( shCount >= 8 ) {
6628 /* lower order three bytes goes to higher order three bytes */
6632 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6634 movLeft2Result(left, LSB, result, MSB16, 0);
6636 else{ /* size = 4 */
6638 movLeft2Result(left, MSB24, result, MSB32, 0);
6639 movLeft2Result(left, MSB16, result, MSB24, 0);
6640 movLeft2Result(left, LSB, result, MSB16, 0);
6641 aopPut(AOP(result),zero,LSB);
6643 else if(shCount == 1)
6644 shiftLLong(left, result, MSB16);
6646 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6647 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6648 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6649 aopPut(AOP(result),zero,LSB);
6654 /* 1 <= shCount <= 7 */
6655 else if(shCount <= 2){
6656 shiftLLong(left, result, LSB);
6658 shiftLLong(result, result, LSB);
6660 /* 3 <= shCount <= 7, optimize */
6662 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6663 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6664 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6668 /*-----------------------------------------------------------------*/
6669 /* genLeftShiftLiteral - left shifting by known count */
6670 /*-----------------------------------------------------------------*/
6671 static void genLeftShiftLiteral (operand *left,
6676 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6680 freeAsmop(right,NULL,ic,TRUE);
6682 aopOp(left,ic,FALSE);
6683 aopOp(result,ic,FALSE);
6685 size = getSize(operandType(result));
6688 pic14_emitcode("; shift left ","result %d, left %d",size,
6692 /* I suppose that the left size >= result size */
6695 movLeft2Result(left, size, result, size, 0);
6699 else if(shCount >= (size * 8))
6701 aopPut(AOP(result),zero,size);
6705 genlshOne (result,left,shCount);
6710 genlshTwo (result,left,shCount);
6714 genlshFour (result,left,shCount);
6718 freeAsmop(left,NULL,ic,TRUE);
6719 freeAsmop(result,NULL,ic,TRUE);
6722 /*-----------------------------------------------------------------*
6723 * genMultiAsm - repeat assembly instruction for size of register.
6724 * if endian == 1, then the high byte (i.e base address + size of
6725 * register) is used first else the low byte is used first;
6726 *-----------------------------------------------------------------*/
6727 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6745 emitpcode(poc, popGet(AOP(reg),offset));
6750 /*-----------------------------------------------------------------*/
6751 /* genLeftShift - generates code for left shifting */
6752 /*-----------------------------------------------------------------*/
6753 static void genLeftShift (iCode *ic)
6755 operand *left,*right, *result;
6758 symbol *tlbl , *tlbl1;
6760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6762 right = IC_RIGHT(ic);
6764 result = IC_RESULT(ic);
6766 aopOp(right,ic,FALSE);
6768 /* if the shift count is known then do it
6769 as efficiently as possible */
6770 if (AOP_TYPE(right) == AOP_LIT) {
6771 genLeftShiftLiteral (left,right,result,ic);
6775 /* shift count is unknown then we have to form
6776 a loop get the loop count in B : Note: we take
6777 only the lower order byte since shifting
6778 more that 32 bits make no sense anyway, ( the
6779 largest size of an object can be only 32 bits ) */
6782 aopOp(left,ic,FALSE);
6783 aopOp(result,ic,FALSE);
6785 /* now move the left to the result if they are not the
6787 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6788 AOP_SIZE(result) > 1) {
6790 size = AOP_SIZE(result);
6793 l = aopGet(AOP(left),offset,FALSE,TRUE);
6794 if (*l == '@' && (IS_AOP_PREG(result))) {
6796 pic14_emitcode("mov","a,%s",l);
6797 aopPut(AOP(result),"a",offset);
6799 aopPut(AOP(result),l,offset);
6804 size = AOP_SIZE(result);
6806 /* if it is only one byte then */
6808 if(optimized_for_speed) {
6809 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6810 emitpcode(POC_ANDLW, popGetLit(0xf0));
6811 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6812 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6813 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6814 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6815 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6816 emitpcode(POC_RLFW, popGet(AOP(result),0));
6817 emitpcode(POC_ANDLW, popGetLit(0xfe));
6818 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6819 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6820 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6823 tlbl = newiTempLabel(NULL);
6824 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6825 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6826 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6829 emitpcode(POC_COMFW, popGet(AOP(right),0));
6830 emitpcode(POC_RRF, popGet(AOP(result),0));
6831 emitpLabel(tlbl->key);
6832 emitpcode(POC_RLF, popGet(AOP(result),0));
6833 emitpcode(POC_ADDLW, popGetLit(1));
6835 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6840 if (pic14_sameRegs(AOP(left),AOP(result))) {
6842 tlbl = newiTempLabel(NULL);
6843 emitpcode(POC_COMFW, popGet(AOP(right),0));
6844 genMultiAsm(POC_RRF, result, size,1);
6845 emitpLabel(tlbl->key);
6846 genMultiAsm(POC_RLF, result, size,0);
6847 emitpcode(POC_ADDLW, popGetLit(1));
6849 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6853 tlbl = newiTempLabel(NULL);
6855 tlbl1 = newiTempLabel(NULL);
6857 reAdjustPreg(AOP(result));
6859 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6860 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6861 l = aopGet(AOP(result),offset,FALSE,FALSE);
6863 pic14_emitcode("add","a,acc");
6864 aopPut(AOP(result),"a",offset++);
6866 l = aopGet(AOP(result),offset,FALSE,FALSE);
6868 pic14_emitcode("rlc","a");
6869 aopPut(AOP(result),"a",offset++);
6871 reAdjustPreg(AOP(result));
6873 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6874 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6876 freeAsmop (right,NULL,ic,TRUE);
6877 freeAsmop(left,NULL,ic,TRUE);
6878 freeAsmop(result,NULL,ic,TRUE);
6881 /*-----------------------------------------------------------------*/
6882 /* genrshOne - right shift a one byte quantity by known count */
6883 /*-----------------------------------------------------------------*/
6884 static void genrshOne (operand *result, operand *left,
6885 int shCount, int sign)
6887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6888 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6891 /*-----------------------------------------------------------------*/
6892 /* genrshTwo - right shift two bytes by known amount != 0 */
6893 /*-----------------------------------------------------------------*/
6894 static void genrshTwo (operand *result,operand *left,
6895 int shCount, int sign)
6897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6898 /* if shCount >= 8 */
6902 shiftR1Left2Result(left, MSB16, result, LSB,
6905 movLeft2Result(left, MSB16, result, LSB, sign);
6907 addSign(result, MSB16, sign);
6909 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6913 /* 1 <= shCount <= 7 */
6915 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6918 /*-----------------------------------------------------------------*/
6919 /* shiftRLong - shift right one long from left to result */
6920 /* offl = LSB or MSB16 */
6921 /*-----------------------------------------------------------------*/
6922 static void shiftRLong (operand *left, int offl,
6923 operand *result, int sign)
6925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 pic14_emitcode("clr","c");
6928 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6930 pic14_emitcode("mov","c,acc.7");
6931 pic14_emitcode("rrc","a");
6932 aopPut(AOP(result),"a",MSB32-offl);
6934 /* add sign of "a" */
6935 addSign(result, MSB32, sign);
6937 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6938 pic14_emitcode("rrc","a");
6939 aopPut(AOP(result),"a",MSB24-offl);
6941 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6942 pic14_emitcode("rrc","a");
6943 aopPut(AOP(result),"a",MSB16-offl);
6946 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6947 pic14_emitcode("rrc","a");
6948 aopPut(AOP(result),"a",LSB);
6952 /*-----------------------------------------------------------------*/
6953 /* genrshFour - shift four byte by a known amount != 0 */
6954 /*-----------------------------------------------------------------*/
6955 static void genrshFour (operand *result, operand *left,
6956 int shCount, int sign)
6958 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6959 /* if shifting more that 3 bytes */
6960 if(shCount >= 24 ) {
6963 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6965 movLeft2Result(left, MSB32, result, LSB, sign);
6966 addSign(result, MSB16, sign);
6968 else if(shCount >= 16){
6971 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6973 movLeft2Result(left, MSB24, result, LSB, 0);
6974 movLeft2Result(left, MSB32, result, MSB16, sign);
6976 addSign(result, MSB24, sign);
6978 else if(shCount >= 8){
6981 shiftRLong(left, MSB16, result, sign);
6982 else if(shCount == 0){
6983 movLeft2Result(left, MSB16, result, LSB, 0);
6984 movLeft2Result(left, MSB24, result, MSB16, 0);
6985 movLeft2Result(left, MSB32, result, MSB24, sign);
6986 addSign(result, MSB32, sign);
6989 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6990 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6991 /* the last shift is signed */
6992 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6993 addSign(result, MSB32, sign);
6996 else{ /* 1 <= shCount <= 7 */
6998 shiftRLong(left, LSB, result, sign);
7000 shiftRLong(result, LSB, result, sign);
7003 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7004 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7005 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7010 /*-----------------------------------------------------------------*/
7011 /* genRightShiftLiteral - right shifting by known count */
7012 /*-----------------------------------------------------------------*/
7013 static void genRightShiftLiteral (operand *left,
7019 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7022 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7023 freeAsmop(right,NULL,ic,TRUE);
7025 aopOp(left,ic,FALSE);
7026 aopOp(result,ic,FALSE);
7029 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7033 size = pic14_getDataSize(left);
7034 /* test the LEFT size !!! */
7036 /* I suppose that the left size >= result size */
7038 size = pic14_getDataSize(result);
7040 movLeft2Result(left, size, result, size, 0);
7043 else if(shCount >= (size * 8)){
7045 /* get sign in acc.7 */
7046 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7047 addSign(result, LSB, sign);
7051 genrshOne (result,left,shCount,sign);
7055 genrshTwo (result,left,shCount,sign);
7059 genrshFour (result,left,shCount,sign);
7065 freeAsmop(left,NULL,ic,TRUE);
7066 freeAsmop(result,NULL,ic,TRUE);
7070 /*-----------------------------------------------------------------*/
7071 /* genSignedRightShift - right shift of signed number */
7072 /*-----------------------------------------------------------------*/
7073 static void genSignedRightShift (iCode *ic)
7075 operand *right, *left, *result;
7078 symbol *tlbl, *tlbl1 ;
7080 /* we do it the hard way put the shift count in b
7081 and loop thru preserving the sign */
7082 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7084 right = IC_RIGHT(ic);
7086 result = IC_RESULT(ic);
7088 aopOp(right,ic,FALSE);
7091 if ( AOP_TYPE(right) == AOP_LIT) {
7092 genRightShiftLiteral (left,right,result,ic,1);
7095 /* shift count is unknown then we have to form
7096 a loop get the loop count in B : Note: we take
7097 only the lower order byte since shifting
7098 more that 32 bits make no sense anyway, ( the
7099 largest size of an object can be only 32 bits ) */
7101 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7102 pic14_emitcode("inc","b");
7103 freeAsmop (right,NULL,ic,TRUE);
7104 aopOp(left,ic,FALSE);
7105 aopOp(result,ic,FALSE);
7107 /* now move the left to the result if they are not the
7109 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7110 AOP_SIZE(result) > 1) {
7112 size = AOP_SIZE(result);
7115 l = aopGet(AOP(left),offset,FALSE,TRUE);
7116 if (*l == '@' && IS_AOP_PREG(result)) {
7118 pic14_emitcode("mov","a,%s",l);
7119 aopPut(AOP(result),"a",offset);
7121 aopPut(AOP(result),l,offset);
7126 /* mov the highest order bit to OVR */
7127 tlbl = newiTempLabel(NULL);
7128 tlbl1= newiTempLabel(NULL);
7130 size = AOP_SIZE(result);
7132 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7133 pic14_emitcode("rlc","a");
7134 pic14_emitcode("mov","ov,c");
7135 /* if it is only one byte then */
7137 l = aopGet(AOP(left),0,FALSE,FALSE);
7139 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7140 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7141 pic14_emitcode("mov","c,ov");
7142 pic14_emitcode("rrc","a");
7143 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7144 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7145 aopPut(AOP(result),"a",0);
7149 reAdjustPreg(AOP(result));
7150 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7151 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7152 pic14_emitcode("mov","c,ov");
7154 l = aopGet(AOP(result),offset,FALSE,FALSE);
7156 pic14_emitcode("rrc","a");
7157 aopPut(AOP(result),"a",offset--);
7159 reAdjustPreg(AOP(result));
7160 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7161 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7164 freeAsmop(left,NULL,ic,TRUE);
7165 freeAsmop(result,NULL,ic,TRUE);
7168 /*-----------------------------------------------------------------*/
7169 /* genRightShift - generate code for right shifting */
7170 /*-----------------------------------------------------------------*/
7171 static void genRightShift (iCode *ic)
7173 operand *right, *left, *result;
7177 symbol *tlbl, *tlbl1 ;
7179 /* if signed then we do it the hard way preserve the
7180 sign bit moving it inwards */
7181 retype = getSpec(operandType(IC_RESULT(ic)));
7182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7184 if (!SPEC_USIGN(retype)) {
7185 genSignedRightShift (ic);
7189 /* signed & unsigned types are treated the same : i.e. the
7190 signed is NOT propagated inwards : quoting from the
7191 ANSI - standard : "for E1 >> E2, is equivalent to division
7192 by 2**E2 if unsigned or if it has a non-negative value,
7193 otherwise the result is implementation defined ", MY definition
7194 is that the sign does not get propagated */
7196 right = IC_RIGHT(ic);
7198 result = IC_RESULT(ic);
7200 aopOp(right,ic,FALSE);
7202 /* if the shift count is known then do it
7203 as efficiently as possible */
7204 if (AOP_TYPE(right) == AOP_LIT) {
7205 genRightShiftLiteral (left,right,result,ic, 0);
7209 /* shift count is unknown then we have to form
7210 a loop get the loop count in B : Note: we take
7211 only the lower order byte since shifting
7212 more that 32 bits make no sense anyway, ( the
7213 largest size of an object can be only 32 bits ) */
7215 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7216 pic14_emitcode("inc","b");
7217 aopOp(left,ic,FALSE);
7218 aopOp(result,ic,FALSE);
7220 /* now move the left to the result if they are not the
7222 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7223 AOP_SIZE(result) > 1) {
7225 size = AOP_SIZE(result);
7228 l = aopGet(AOP(left),offset,FALSE,TRUE);
7229 if (*l == '@' && IS_AOP_PREG(result)) {
7231 pic14_emitcode("mov","a,%s",l);
7232 aopPut(AOP(result),"a",offset);
7234 aopPut(AOP(result),l,offset);
7239 tlbl = newiTempLabel(NULL);
7240 tlbl1= newiTempLabel(NULL);
7241 size = AOP_SIZE(result);
7244 /* if it is only one byte then */
7247 l = aopGet(AOP(left),0,FALSE,FALSE);
7249 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7250 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7252 pic14_emitcode("rrc","a");
7253 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7254 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7255 aopPut(AOP(result),"a",0);
7257 tlbl = newiTempLabel(NULL);
7258 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7259 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7260 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7263 emitpcode(POC_COMFW, popGet(AOP(right),0));
7264 emitpcode(POC_RLF, popGet(AOP(result),0));
7265 emitpLabel(tlbl->key);
7266 emitpcode(POC_RRF, popGet(AOP(result),0));
7267 emitpcode(POC_ADDLW, popGetLit(1));
7269 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7274 reAdjustPreg(AOP(result));
7275 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7276 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7279 l = aopGet(AOP(result),offset,FALSE,FALSE);
7281 pic14_emitcode("rrc","a");
7282 aopPut(AOP(result),"a",offset--);
7284 reAdjustPreg(AOP(result));
7286 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7287 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7290 freeAsmop(left,NULL,ic,TRUE);
7291 freeAsmop (right,NULL,ic,TRUE);
7292 freeAsmop(result,NULL,ic,TRUE);
7295 /*-----------------------------------------------------------------*/
7296 /* genUnpackBits - generates code for unpacking bits */
7297 /*-----------------------------------------------------------------*/
7298 static void genUnpackBits (operand *result, char *rname, int ptype)
7305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7306 etype = getSpec(operandType(result));
7308 /* read the first byte */
7313 pic14_emitcode("mov","a,@%s",rname);
7317 pic14_emitcode("movx","a,@%s",rname);
7321 pic14_emitcode("movx","a,@dptr");
7325 pic14_emitcode("clr","a");
7326 pic14_emitcode("movc","a","@a+dptr");
7330 pic14_emitcode("lcall","__gptrget");
7334 /* if we have bitdisplacement then it fits */
7335 /* into this byte completely or if length is */
7336 /* less than a byte */
7337 if ((shCnt = SPEC_BSTR(etype)) ||
7338 (SPEC_BLEN(etype) <= 8)) {
7340 /* shift right acc */
7343 pic14_emitcode("anl","a,#0x%02x",
7344 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7345 aopPut(AOP(result),"a",offset);
7349 /* bit field did not fit in a byte */
7350 rlen = SPEC_BLEN(etype) - 8;
7351 aopPut(AOP(result),"a",offset++);
7358 pic14_emitcode("inc","%s",rname);
7359 pic14_emitcode("mov","a,@%s",rname);
7363 pic14_emitcode("inc","%s",rname);
7364 pic14_emitcode("movx","a,@%s",rname);
7368 pic14_emitcode("inc","dptr");
7369 pic14_emitcode("movx","a,@dptr");
7373 pic14_emitcode("clr","a");
7374 pic14_emitcode("inc","dptr");
7375 pic14_emitcode("movc","a","@a+dptr");
7379 pic14_emitcode("inc","dptr");
7380 pic14_emitcode("lcall","__gptrget");
7385 /* if we are done */
7389 aopPut(AOP(result),"a",offset++);
7394 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7395 aopPut(AOP(result),"a",offset);
7402 /*-----------------------------------------------------------------*/
7403 /* genDataPointerGet - generates code when ptr offset is known */
7404 /*-----------------------------------------------------------------*/
7405 static void genDataPointerGet (operand *left,
7409 int size , offset = 0;
7412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7415 /* optimization - most of the time, left and result are the same
7416 * address, but different types. for the pic code, we could omit
7420 aopOp(result,ic,TRUE);
7422 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7424 size = AOP_SIZE(result);
7427 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7431 freeAsmop(left,NULL,ic,TRUE);
7432 freeAsmop(result,NULL,ic,TRUE);
7435 /*-----------------------------------------------------------------*/
7436 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7437 /*-----------------------------------------------------------------*/
7438 static void genNearPointerGet (operand *left,
7445 sym_link *rtype, *retype;
7446 sym_link *ltype = operandType(left);
7449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7451 rtype = operandType(result);
7452 retype= getSpec(rtype);
7454 aopOp(left,ic,FALSE);
7456 /* if left is rematerialisable and
7457 result is not bit variable type and
7458 the left is pointer to data space i.e
7459 lower 128 bytes of space */
7460 if (AOP_TYPE(left) == AOP_IMMD &&
7461 !IS_BITVAR(retype) &&
7462 DCL_TYPE(ltype) == POINTER) {
7463 genDataPointerGet (left,result,ic);
7467 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7469 /* if the value is already in a pointer register
7470 then don't need anything more */
7471 if (!AOP_INPREG(AOP(left))) {
7472 /* otherwise get a free pointer register */
7473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7475 preg = getFreePtr(ic,&aop,FALSE);
7476 pic14_emitcode("mov","%s,%s",
7478 aopGet(AOP(left),0,FALSE,TRUE));
7479 rname = preg->name ;
7481 rname = aopGet(AOP(left),0,FALSE,FALSE);
7483 freeAsmop(left,NULL,ic,TRUE);
7484 aopOp (result,ic,FALSE);
7486 /* if bitfield then unpack the bits */
7487 if (IS_BITVAR(retype))
7488 genUnpackBits (result,rname,POINTER);
7490 /* we have can just get the values */
7491 int size = AOP_SIZE(result);
7494 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7496 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7498 pic14_emitcode("mov","a,@%s",rname);
7499 aopPut(AOP(result),"a",offset);
7501 sprintf(buffer,"@%s",rname);
7502 aopPut(AOP(result),buffer,offset);
7506 pic14_emitcode("inc","%s",rname);
7510 /* now some housekeeping stuff */
7512 /* we had to allocate for this iCode */
7513 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7514 freeAsmop(NULL,aop,ic,TRUE);
7516 /* we did not allocate which means left
7517 already in a pointer register, then
7518 if size > 0 && this could be used again
7519 we have to point it back to where it
7521 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7522 if (AOP_SIZE(result) > 1 &&
7523 !OP_SYMBOL(left)->remat &&
7524 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7526 int size = AOP_SIZE(result) - 1;
7528 pic14_emitcode("dec","%s",rname);
7533 freeAsmop(result,NULL,ic,TRUE);
7537 /*-----------------------------------------------------------------*/
7538 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7539 /*-----------------------------------------------------------------*/
7540 static void genPagedPointerGet (operand *left,
7547 sym_link *rtype, *retype;
7549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7551 rtype = operandType(result);
7552 retype= getSpec(rtype);
7554 aopOp(left,ic,FALSE);
7556 /* if the value is already in a pointer register
7557 then don't need anything more */
7558 if (!AOP_INPREG(AOP(left))) {
7559 /* otherwise get a free pointer register */
7561 preg = getFreePtr(ic,&aop,FALSE);
7562 pic14_emitcode("mov","%s,%s",
7564 aopGet(AOP(left),0,FALSE,TRUE));
7565 rname = preg->name ;
7567 rname = aopGet(AOP(left),0,FALSE,FALSE);
7569 freeAsmop(left,NULL,ic,TRUE);
7570 aopOp (result,ic,FALSE);
7572 /* if bitfield then unpack the bits */
7573 if (IS_BITVAR(retype))
7574 genUnpackBits (result,rname,PPOINTER);
7576 /* we have can just get the values */
7577 int size = AOP_SIZE(result);
7582 pic14_emitcode("movx","a,@%s",rname);
7583 aopPut(AOP(result),"a",offset);
7588 pic14_emitcode("inc","%s",rname);
7592 /* now some housekeeping stuff */
7594 /* we had to allocate for this iCode */
7595 freeAsmop(NULL,aop,ic,TRUE);
7597 /* we did not allocate which means left
7598 already in a pointer register, then
7599 if size > 0 && this could be used again
7600 we have to point it back to where it
7602 if (AOP_SIZE(result) > 1 &&
7603 !OP_SYMBOL(left)->remat &&
7604 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7606 int size = AOP_SIZE(result) - 1;
7608 pic14_emitcode("dec","%s",rname);
7613 freeAsmop(result,NULL,ic,TRUE);
7618 /*-----------------------------------------------------------------*/
7619 /* genFarPointerGet - gget value from far space */
7620 /*-----------------------------------------------------------------*/
7621 static void genFarPointerGet (operand *left,
7622 operand *result, iCode *ic)
7625 sym_link *retype = getSpec(operandType(result));
7627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7629 aopOp(left,ic,FALSE);
7631 /* if the operand is already in dptr
7632 then we do nothing else we move the value to dptr */
7633 if (AOP_TYPE(left) != AOP_STR) {
7634 /* if this is remateriazable */
7635 if (AOP_TYPE(left) == AOP_IMMD)
7636 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7637 else { /* we need to get it byte by byte */
7638 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7639 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7640 if (options.model == MODEL_FLAT24)
7642 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7646 /* so dptr know contains the address */
7647 freeAsmop(left,NULL,ic,TRUE);
7648 aopOp(result,ic,FALSE);
7650 /* if bit then unpack */
7651 if (IS_BITVAR(retype))
7652 genUnpackBits(result,"dptr",FPOINTER);
7654 size = AOP_SIZE(result);
7658 pic14_emitcode("movx","a,@dptr");
7659 aopPut(AOP(result),"a",offset++);
7661 pic14_emitcode("inc","dptr");
7665 freeAsmop(result,NULL,ic,TRUE);
7668 /*-----------------------------------------------------------------*/
7669 /* genCodePointerGet - get value from code space */
7670 /*-----------------------------------------------------------------*/
7671 static void genCodePointerGet (operand *left,
7672 operand *result, iCode *ic)
7675 sym_link *retype = getSpec(operandType(result));
7677 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7679 aopOp(left,ic,FALSE);
7681 /* if the operand is already in dptr
7682 then we do nothing else we move the value to dptr */
7683 if (AOP_TYPE(left) != AOP_STR) {
7684 /* if this is remateriazable */
7685 if (AOP_TYPE(left) == AOP_IMMD)
7686 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7687 else { /* we need to get it byte by byte */
7688 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7689 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7690 if (options.model == MODEL_FLAT24)
7692 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7696 /* so dptr know contains the address */
7697 freeAsmop(left,NULL,ic,TRUE);
7698 aopOp(result,ic,FALSE);
7700 /* if bit then unpack */
7701 if (IS_BITVAR(retype))
7702 genUnpackBits(result,"dptr",CPOINTER);
7704 size = AOP_SIZE(result);
7708 pic14_emitcode("clr","a");
7709 pic14_emitcode("movc","a,@a+dptr");
7710 aopPut(AOP(result),"a",offset++);
7712 pic14_emitcode("inc","dptr");
7716 freeAsmop(result,NULL,ic,TRUE);
7719 /*-----------------------------------------------------------------*/
7720 /* genGenPointerGet - gget value from generic pointer space */
7721 /*-----------------------------------------------------------------*/
7722 static void genGenPointerGet (operand *left,
7723 operand *result, iCode *ic)
7726 sym_link *retype = getSpec(operandType(result));
7728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7729 aopOp(left,ic,FALSE);
7730 aopOp(result,ic,FALSE);
7733 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7735 /* if the operand is already in dptr
7736 then we do nothing else we move the value to dptr */
7737 // if (AOP_TYPE(left) != AOP_STR) {
7738 /* if this is remateriazable */
7739 if (AOP_TYPE(left) == AOP_IMMD) {
7740 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7741 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7743 else { /* we need to get it byte by byte */
7745 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7746 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7748 size = AOP_SIZE(result);
7752 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7753 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7755 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7760 /* so dptr know contains the address */
7762 /* if bit then unpack */
7763 //if (IS_BITVAR(retype))
7764 // genUnpackBits(result,"dptr",GPOINTER);
7767 freeAsmop(left,NULL,ic,TRUE);
7768 freeAsmop(result,NULL,ic,TRUE);
7772 /*-----------------------------------------------------------------*/
7773 /* genConstPointerGet - get value from const generic pointer space */
7774 /*-----------------------------------------------------------------*/
7775 static void genConstPointerGet (operand *left,
7776 operand *result, iCode *ic)
7778 sym_link *retype = getSpec(operandType(result));
7779 symbol *albl = newiTempLabel(NULL);
7780 symbol *blbl = newiTempLabel(NULL);
7783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7784 aopOp(left,ic,FALSE);
7785 aopOp(result,ic,FALSE);
7788 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7790 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
7792 emitpcode(POC_CALL,popGetLabel(albl->key));
7793 emitpcode(POC_GOTO,popGetLabel(blbl->key));
7794 emitpLabel(albl->key);
7796 poc = ( (AOP_TYPE(left) == AOP_IMMD) ? POC_MOVLW : POC_MOVFW);
7798 emitpcode(poc,popGet(AOP(left),1));
7799 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
7800 emitpcode(poc,popGet(AOP(left),0));
7801 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
7803 emitpLabel(blbl->key);
7805 emitpcode(POC_MOVWF,popGet(AOP(result),0));
7808 freeAsmop(left,NULL,ic,TRUE);
7809 freeAsmop(result,NULL,ic,TRUE);
7812 /*-----------------------------------------------------------------*/
7813 /* genPointerGet - generate code for pointer get */
7814 /*-----------------------------------------------------------------*/
7815 static void genPointerGet (iCode *ic)
7817 operand *left, *result ;
7818 sym_link *type, *etype;
7821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7824 result = IC_RESULT(ic) ;
7826 /* depending on the type of pointer we need to
7827 move it to the correct pointer register */
7828 type = operandType(left);
7829 etype = getSpec(type);
7831 if (IS_PTR_CONST(type))
7832 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
7834 /* if left is of type of pointer then it is simple */
7835 if (IS_PTR(type) && !IS_FUNC(type->next))
7836 p_type = DCL_TYPE(type);
7838 /* we have to go by the storage class */
7839 p_type = PTR_TYPE(SPEC_OCLS(etype));
7841 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
7843 if (SPEC_OCLS(etype)->codesp ) {
7844 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
7845 //p_type = CPOINTER ;
7848 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
7849 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
7850 /*p_type = FPOINTER ;*/
7852 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
7853 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
7854 /* p_type = PPOINTER; */
7856 if (SPEC_OCLS(etype) == idata )
7857 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
7858 /* p_type = IPOINTER; */
7860 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
7861 /* p_type = POINTER ; */
7864 /* now that we have the pointer type we assign
7865 the pointer values */
7870 genNearPointerGet (left,result,ic);
7874 genPagedPointerGet(left,result,ic);
7878 genFarPointerGet (left,result,ic);
7882 genConstPointerGet (left,result,ic);
7883 //pic14_emitcodePointerGet (left,result,ic);
7887 if (IS_PTR_CONST(type))
7888 genConstPointerGet (left,result,ic);
7890 genGenPointerGet (left,result,ic);
7896 /*-----------------------------------------------------------------*/
7897 /* genPackBits - generates code for packed bit storage */
7898 /*-----------------------------------------------------------------*/
7899 static void genPackBits (sym_link *etype ,
7901 char *rname, int p_type)
7909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7910 blen = SPEC_BLEN(etype);
7911 bstr = SPEC_BSTR(etype);
7913 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7916 /* if the bit lenth is less than or */
7917 /* it exactly fits a byte then */
7918 if (SPEC_BLEN(etype) <= 8 ) {
7919 shCount = SPEC_BSTR(etype) ;
7921 /* shift left acc */
7924 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7929 pic14_emitcode ("mov","b,a");
7930 pic14_emitcode("mov","a,@%s",rname);
7934 pic14_emitcode ("mov","b,a");
7935 pic14_emitcode("movx","a,@dptr");
7939 pic14_emitcode ("push","b");
7940 pic14_emitcode ("push","acc");
7941 pic14_emitcode ("lcall","__gptrget");
7942 pic14_emitcode ("pop","b");
7946 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7947 ((unsigned char)(0xFF << (blen+bstr)) |
7948 (unsigned char)(0xFF >> (8-bstr)) ) );
7949 pic14_emitcode ("orl","a,b");
7950 if (p_type == GPOINTER)
7951 pic14_emitcode("pop","b");
7957 pic14_emitcode("mov","@%s,a",rname);
7961 pic14_emitcode("movx","@dptr,a");
7965 DEBUGpic14_emitcode(";lcall","__gptrput");
7970 if ( SPEC_BLEN(etype) <= 8 )
7973 pic14_emitcode("inc","%s",rname);
7974 rLen = SPEC_BLEN(etype) ;
7976 /* now generate for lengths greater than one byte */
7979 l = aopGet(AOP(right),offset++,FALSE,TRUE);
7989 pic14_emitcode("mov","@%s,a",rname);
7991 pic14_emitcode("mov","@%s,%s",rname,l);
7996 pic14_emitcode("movx","@dptr,a");
8001 DEBUGpic14_emitcode(";lcall","__gptrput");
8004 pic14_emitcode ("inc","%s",rname);
8009 /* last last was not complete */
8011 /* save the byte & read byte */
8014 pic14_emitcode ("mov","b,a");
8015 pic14_emitcode("mov","a,@%s",rname);
8019 pic14_emitcode ("mov","b,a");
8020 pic14_emitcode("movx","a,@dptr");
8024 pic14_emitcode ("push","b");
8025 pic14_emitcode ("push","acc");
8026 pic14_emitcode ("lcall","__gptrget");
8027 pic14_emitcode ("pop","b");
8031 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8032 pic14_emitcode ("orl","a,b");
8035 if (p_type == GPOINTER)
8036 pic14_emitcode("pop","b");
8041 pic14_emitcode("mov","@%s,a",rname);
8045 pic14_emitcode("movx","@dptr,a");
8049 DEBUGpic14_emitcode(";lcall","__gptrput");
8053 /*-----------------------------------------------------------------*/
8054 /* genDataPointerSet - remat pointer to data space */
8055 /*-----------------------------------------------------------------*/
8056 static void genDataPointerSet(operand *right,
8060 int size, offset = 0 ;
8061 char *l, buffer[256];
8063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8064 aopOp(right,ic,FALSE);
8066 l = aopGet(AOP(result),0,FALSE,TRUE);
8067 size = AOP_SIZE(right);
8068 // tsd, was l+1 - the underline `_' prefix was being stripped
8071 sprintf(buffer,"(%s + %d)",l,offset);
8073 sprintf(buffer,"%s",l);
8075 if (AOP_TYPE(right) == AOP_LIT) {
8076 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8077 lit = lit >> (8*offset);
8079 pic14_emitcode("movlw","%d",lit);
8080 pic14_emitcode("movwf","%s",buffer);
8082 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8083 emitpcode(POC_MOVWF, popRegFromString(buffer));
8086 pic14_emitcode("clrf","%s",buffer);
8087 //emitpcode(POC_CLRF, popRegFromString(buffer));
8088 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8091 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8092 pic14_emitcode("movwf","%s",buffer);
8094 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8095 emitpcode(POC_MOVWF, popRegFromString(buffer));
8102 freeAsmop(right,NULL,ic,TRUE);
8103 freeAsmop(result,NULL,ic,TRUE);
8106 /*-----------------------------------------------------------------*/
8107 /* genNearPointerSet - pic14_emitcode for near pointer put */
8108 /*-----------------------------------------------------------------*/
8109 static void genNearPointerSet (operand *right,
8116 sym_link *ptype = operandType(result);
8119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8120 retype= getSpec(operandType(right));
8122 aopOp(result,ic,FALSE);
8124 /* if the result is rematerializable &
8125 in data space & not a bit variable */
8126 if (AOP_TYPE(result) == AOP_IMMD &&
8127 DCL_TYPE(ptype) == POINTER &&
8128 !IS_BITVAR(retype)) {
8129 genDataPointerSet (right,result,ic);
8133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8135 /* if the value is already in a pointer register
8136 then don't need anything more */
8137 if (!AOP_INPREG(AOP(result))) {
8138 /* otherwise get a free pointer register */
8139 //aop = newAsmop(0);
8140 //preg = getFreePtr(ic,&aop,FALSE);
8141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8142 //pic14_emitcode("mov","%s,%s",
8144 // aopGet(AOP(result),0,FALSE,TRUE));
8145 //rname = preg->name ;
8146 pic14_emitcode("movwf","fsr");
8148 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8150 freeAsmop(result,NULL,ic,TRUE);
8151 aopOp (right,ic,FALSE);
8152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8154 /* if bitfield then unpack the bits */
8155 if (IS_BITVAR(retype)) {
8156 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8157 "The programmer is obviously confused");
8158 //genPackBits (retype,right,rname,POINTER);
8162 /* we have can just get the values */
8163 int size = AOP_SIZE(right);
8166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8168 l = aopGet(AOP(right),offset,FALSE,TRUE);
8171 //pic14_emitcode("mov","@%s,a",rname);
8172 pic14_emitcode("movf","indf,w ;1");
8175 if (AOP_TYPE(right) == AOP_LIT) {
8176 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8178 pic14_emitcode("movlw","%s",l);
8179 pic14_emitcode("movwf","indf ;2");
8181 pic14_emitcode("clrf","indf");
8183 pic14_emitcode("movf","%s,w",l);
8184 pic14_emitcode("movwf","indf ;2");
8186 //pic14_emitcode("mov","@%s,%s",rname,l);
8189 pic14_emitcode("incf","fsr,f ;3");
8190 //pic14_emitcode("inc","%s",rname);
8195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8196 /* now some housekeeping stuff */
8198 /* we had to allocate for this iCode */
8199 freeAsmop(NULL,aop,ic,TRUE);
8201 /* we did not allocate which means left
8202 already in a pointer register, then
8203 if size > 0 && this could be used again
8204 we have to point it back to where it
8206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8207 if (AOP_SIZE(right) > 1 &&
8208 !OP_SYMBOL(result)->remat &&
8209 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8211 int size = AOP_SIZE(right) - 1;
8213 pic14_emitcode("decf","fsr,f");
8214 //pic14_emitcode("dec","%s",rname);
8218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8220 freeAsmop(right,NULL,ic,TRUE);
8225 /*-----------------------------------------------------------------*/
8226 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8227 /*-----------------------------------------------------------------*/
8228 static void genPagedPointerSet (operand *right,
8237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8239 retype= getSpec(operandType(right));
8241 aopOp(result,ic,FALSE);
8243 /* if the value is already in a pointer register
8244 then don't need anything more */
8245 if (!AOP_INPREG(AOP(result))) {
8246 /* otherwise get a free pointer register */
8248 preg = getFreePtr(ic,&aop,FALSE);
8249 pic14_emitcode("mov","%s,%s",
8251 aopGet(AOP(result),0,FALSE,TRUE));
8252 rname = preg->name ;
8254 rname = aopGet(AOP(result),0,FALSE,FALSE);
8256 freeAsmop(result,NULL,ic,TRUE);
8257 aopOp (right,ic,FALSE);
8259 /* if bitfield then unpack the bits */
8260 if (IS_BITVAR(retype))
8261 genPackBits (retype,right,rname,PPOINTER);
8263 /* we have can just get the values */
8264 int size = AOP_SIZE(right);
8268 l = aopGet(AOP(right),offset,FALSE,TRUE);
8271 pic14_emitcode("movx","@%s,a",rname);
8274 pic14_emitcode("inc","%s",rname);
8280 /* now some housekeeping stuff */
8282 /* we had to allocate for this iCode */
8283 freeAsmop(NULL,aop,ic,TRUE);
8285 /* we did not allocate which means left
8286 already in a pointer register, then
8287 if size > 0 && this could be used again
8288 we have to point it back to where it
8290 if (AOP_SIZE(right) > 1 &&
8291 !OP_SYMBOL(result)->remat &&
8292 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8294 int size = AOP_SIZE(right) - 1;
8296 pic14_emitcode("dec","%s",rname);
8301 freeAsmop(right,NULL,ic,TRUE);
8306 /*-----------------------------------------------------------------*/
8307 /* genFarPointerSet - set value from far space */
8308 /*-----------------------------------------------------------------*/
8309 static void genFarPointerSet (operand *right,
8310 operand *result, iCode *ic)
8313 sym_link *retype = getSpec(operandType(right));
8315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8316 aopOp(result,ic,FALSE);
8318 /* if the operand is already in dptr
8319 then we do nothing else we move the value to dptr */
8320 if (AOP_TYPE(result) != AOP_STR) {
8321 /* if this is remateriazable */
8322 if (AOP_TYPE(result) == AOP_IMMD)
8323 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8324 else { /* we need to get it byte by byte */
8325 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8326 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8327 if (options.model == MODEL_FLAT24)
8329 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8333 /* so dptr know contains the address */
8334 freeAsmop(result,NULL,ic,TRUE);
8335 aopOp(right,ic,FALSE);
8337 /* if bit then unpack */
8338 if (IS_BITVAR(retype))
8339 genPackBits(retype,right,"dptr",FPOINTER);
8341 size = AOP_SIZE(right);
8345 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8347 pic14_emitcode("movx","@dptr,a");
8349 pic14_emitcode("inc","dptr");
8353 freeAsmop(right,NULL,ic,TRUE);
8356 /*-----------------------------------------------------------------*/
8357 /* genGenPointerSet - set value from generic pointer space */
8358 /*-----------------------------------------------------------------*/
8359 static void genGenPointerSet (operand *right,
8360 operand *result, iCode *ic)
8363 sym_link *retype = getSpec(operandType(right));
8365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8367 aopOp(result,ic,FALSE);
8368 aopOp(right,ic,FALSE);
8369 size = AOP_SIZE(right);
8371 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8373 /* if the operand is already in dptr
8374 then we do nothing else we move the value to dptr */
8375 if (AOP_TYPE(result) != AOP_STR) {
8376 /* if this is remateriazable */
8377 if (AOP_TYPE(result) == AOP_IMMD) {
8378 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8379 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8381 else { /* we need to get it byte by byte */
8382 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8383 size = AOP_SIZE(right);
8386 /* hack hack! see if this the FSR. If so don't load W */
8387 if(AOP_TYPE(right) != AOP_ACC) {
8389 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8390 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8393 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8395 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8396 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8400 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8401 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8404 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8411 if(aopIdx(AOP(result),0) != 4) {
8413 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8417 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8422 /* so dptr know contains the address */
8425 /* if bit then unpack */
8426 if (IS_BITVAR(retype))
8427 genPackBits(retype,right,"dptr",GPOINTER);
8429 size = AOP_SIZE(right);
8433 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8435 pic14_emitcode("incf","fsr,f");
8436 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8437 pic14_emitcode("movwf","indf");
8439 //DEBUGpic14_emitcode(";lcall","__gptrput");
8441 // pic14_emitcode("inc","dptr");
8446 freeAsmop(right,NULL,ic,TRUE);
8447 freeAsmop(result,NULL,ic,TRUE);
8450 /*-----------------------------------------------------------------*/
8451 /* genPointerSet - stores the value into a pointer location */
8452 /*-----------------------------------------------------------------*/
8453 static void genPointerSet (iCode *ic)
8455 operand *right, *result ;
8456 sym_link *type, *etype;
8459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8461 right = IC_RIGHT(ic);
8462 result = IC_RESULT(ic) ;
8464 /* depending on the type of pointer we need to
8465 move it to the correct pointer register */
8466 type = operandType(result);
8467 etype = getSpec(type);
8468 /* if left is of type of pointer then it is simple */
8469 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8470 p_type = DCL_TYPE(type);
8473 /* we have to go by the storage class */
8474 p_type = PTR_TYPE(SPEC_OCLS(etype));
8476 /* if (SPEC_OCLS(etype)->codesp ) { */
8477 /* p_type = CPOINTER ; */
8480 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8481 /* p_type = FPOINTER ; */
8483 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8484 /* p_type = PPOINTER ; */
8486 /* if (SPEC_OCLS(etype) == idata ) */
8487 /* p_type = IPOINTER ; */
8489 /* p_type = POINTER ; */
8492 /* now that we have the pointer type we assign
8493 the pointer values */
8498 genNearPointerSet (right,result,ic);
8502 genPagedPointerSet (right,result,ic);
8506 genFarPointerSet (right,result,ic);
8510 genGenPointerSet (right,result,ic);
8514 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8515 "genPointerSet: illegal pointer type");
8519 /*-----------------------------------------------------------------*/
8520 /* genIfx - generate code for Ifx statement */
8521 /*-----------------------------------------------------------------*/
8522 static void genIfx (iCode *ic, iCode *popIc)
8524 operand *cond = IC_COND(ic);
8527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8529 aopOp(cond,ic,FALSE);
8531 /* get the value into acc */
8532 if (AOP_TYPE(cond) != AOP_CRY)
8533 pic14_toBoolean(cond);
8536 /* the result is now in the accumulator */
8537 freeAsmop(cond,NULL,ic,TRUE);
8539 /* if there was something to be popped then do it */
8543 /* if the condition is a bit variable */
8544 if (isbit && IS_ITEMP(cond) &&
8546 genIfxJump(ic,SPIL_LOC(cond)->rname);
8547 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8550 if (isbit && !IS_ITEMP(cond))
8551 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8559 /*-----------------------------------------------------------------*/
8560 /* genAddrOf - generates code for address of */
8561 /*-----------------------------------------------------------------*/
8562 static void genAddrOf (iCode *ic)
8564 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8565 operand *right, *result, *left;
8566 //int size, offset ;
8568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8571 //aopOp(IC_RESULT(ic),ic,FALSE);
8573 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8574 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8575 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8577 DEBUGpic14_AopType(__LINE__,left,right,result);
8579 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8580 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8583 /* object not on stack then we need the name */
8584 size = AOP_SIZE(IC_RESULT(ic));
8588 char s[SDCC_NAME_MAX];
8590 sprintf(s,"#(%s >> %d)",
8594 sprintf(s,"#%s",sym->rname);
8595 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8600 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8601 freeAsmop(left,NULL,ic,FALSE);
8602 freeAsmop(result,NULL,ic,TRUE);
8607 /*-----------------------------------------------------------------*/
8608 /* genFarFarAssign - assignment when both are in far space */
8609 /*-----------------------------------------------------------------*/
8610 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8612 int size = AOP_SIZE(right);
8615 /* first push the right side on to the stack */
8617 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8619 pic14_emitcode ("push","acc");
8622 freeAsmop(right,NULL,ic,FALSE);
8623 /* now assign DPTR to result */
8624 aopOp(result,ic,FALSE);
8625 size = AOP_SIZE(result);
8627 pic14_emitcode ("pop","acc");
8628 aopPut(AOP(result),"a",--offset);
8630 freeAsmop(result,NULL,ic,FALSE);
8635 /*-----------------------------------------------------------------*/
8636 /* genAssign - generate code for assignment */
8637 /*-----------------------------------------------------------------*/
8638 static void genAssign (iCode *ic)
8640 operand *result, *right;
8641 int size, offset,know_W;
8642 unsigned long lit = 0L;
8644 result = IC_RESULT(ic);
8645 right = IC_RIGHT(ic) ;
8647 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8649 /* if they are the same */
8650 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8653 aopOp(right,ic,FALSE);
8654 aopOp(result,ic,TRUE);
8656 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8658 /* if they are the same registers */
8659 if (pic14_sameRegs(AOP(right),AOP(result)))
8662 /* if the result is a bit */
8663 if (AOP_TYPE(result) == AOP_CRY) {
8665 /* if the right size is a literal then
8666 we know what the value is */
8667 if (AOP_TYPE(right) == AOP_LIT) {
8669 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8670 popGet(AOP(result),0));
8672 if (((int) operandLitValue(right)))
8673 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8674 AOP(result)->aopu.aop_dir,
8675 AOP(result)->aopu.aop_dir);
8677 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8678 AOP(result)->aopu.aop_dir,
8679 AOP(result)->aopu.aop_dir);
8683 /* the right is also a bit variable */
8684 if (AOP_TYPE(right) == AOP_CRY) {
8685 emitpcode(POC_BCF, popGet(AOP(result),0));
8686 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8687 emitpcode(POC_BSF, popGet(AOP(result),0));
8689 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8690 AOP(result)->aopu.aop_dir,
8691 AOP(result)->aopu.aop_dir);
8692 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8693 AOP(right)->aopu.aop_dir,
8694 AOP(right)->aopu.aop_dir);
8695 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8696 AOP(result)->aopu.aop_dir,
8697 AOP(result)->aopu.aop_dir);
8702 emitpcode(POC_BCF, popGet(AOP(result),0));
8703 pic14_toBoolean(right);
8705 emitpcode(POC_BSF, popGet(AOP(result),0));
8706 //aopPut(AOP(result),"a",0);
8710 /* bit variables done */
8712 size = AOP_SIZE(result);
8714 if(AOP_TYPE(right) == AOP_LIT)
8715 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8717 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8719 if(aopIdx(AOP(result),0) == 4) {
8720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8721 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8722 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8725 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8731 if(AOP_TYPE(right) == AOP_LIT) {
8733 if(know_W != (lit&0xff))
8734 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8736 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8738 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8742 } else if (AOP_TYPE(right) == AOP_CRY) {
8743 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8745 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8746 emitpcode(POC_INCF, popGet(AOP(result),0));
8749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8750 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8751 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8759 freeAsmop (right,NULL,ic,FALSE);
8760 freeAsmop (result,NULL,ic,TRUE);
8763 /*-----------------------------------------------------------------*/
8764 /* genJumpTab - genrates code for jump table */
8765 /*-----------------------------------------------------------------*/
8766 static void genJumpTab (iCode *ic)
8771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8773 aopOp(IC_JTCOND(ic),ic,FALSE);
8774 /* get the condition into accumulator */
8775 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8777 /* multiply by three */
8778 pic14_emitcode("add","a,acc");
8779 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8781 jtab = newiTempLabel(NULL);
8782 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8783 pic14_emitcode("jmp","@a+dptr");
8784 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8786 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8787 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8789 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8790 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8791 emitpLabel(jtab->key);
8793 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8795 /* now generate the jump labels */
8796 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8797 jtab = setNextItem(IC_JTLABELS(ic))) {
8798 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8799 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8805 /*-----------------------------------------------------------------*/
8806 /* genMixedOperation - gen code for operators between mixed types */
8807 /*-----------------------------------------------------------------*/
8809 TSD - Written for the PIC port - but this unfortunately is buggy.
8810 This routine is good in that it is able to efficiently promote
8811 types to different (larger) sizes. Unfortunately, the temporary
8812 variables that are optimized out by this routine are sometimes
8813 used in other places. So until I know how to really parse the
8814 iCode tree, I'm going to not be using this routine :(.
8816 static int genMixedOperation (iCode *ic)
8819 operand *result = IC_RESULT(ic);
8820 sym_link *ctype = operandType(IC_LEFT(ic));
8821 operand *right = IC_RIGHT(ic);
8827 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8829 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8835 nextright = IC_RIGHT(nextic);
8836 nextleft = IC_LEFT(nextic);
8837 nextresult = IC_RESULT(nextic);
8839 aopOp(right,ic,FALSE);
8840 aopOp(result,ic,FALSE);
8841 aopOp(nextright, nextic, FALSE);
8842 aopOp(nextleft, nextic, FALSE);
8843 aopOp(nextresult, nextic, FALSE);
8845 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8851 pic14_emitcode(";remove right +","");
8853 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8859 pic14_emitcode(";remove left +","");
8863 big = AOP_SIZE(nextleft);
8864 small = AOP_SIZE(nextright);
8866 switch(nextic->op) {
8869 pic14_emitcode(";optimize a +","");
8870 /* if unsigned or not an integral type */
8871 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8872 pic14_emitcode(";add a bit to something","");
8875 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8877 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8878 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8879 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8881 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8889 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8890 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8891 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8894 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8896 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8897 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8898 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8899 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8900 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8903 pic14_emitcode("rlf","known_zero,w");
8910 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8911 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8912 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8914 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8924 freeAsmop(right,NULL,ic,TRUE);
8925 freeAsmop(result,NULL,ic,TRUE);
8926 freeAsmop(nextright,NULL,ic,TRUE);
8927 freeAsmop(nextleft,NULL,ic,TRUE);
8929 nextic->generated = 1;
8936 /*-----------------------------------------------------------------*/
8937 /* genCast - gen code for casting */
8938 /*-----------------------------------------------------------------*/
8939 static void genCast (iCode *ic)
8941 operand *result = IC_RESULT(ic);
8942 sym_link *ctype = operandType(IC_LEFT(ic));
8943 sym_link *rtype = operandType(IC_RIGHT(ic));
8944 operand *right = IC_RIGHT(ic);
8947 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8948 /* if they are equivalent then do nothing */
8949 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8952 aopOp(right,ic,FALSE) ;
8953 aopOp(result,ic,FALSE);
8955 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8957 /* if the result is a bit */
8958 if (AOP_TYPE(result) == AOP_CRY) {
8959 /* if the right size is a literal then
8960 we know what the value is */
8961 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8962 if (AOP_TYPE(right) == AOP_LIT) {
8964 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8965 popGet(AOP(result),0));
8967 if (((int) operandLitValue(right)))
8968 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8969 AOP(result)->aopu.aop_dir,
8970 AOP(result)->aopu.aop_dir);
8972 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8973 AOP(result)->aopu.aop_dir,
8974 AOP(result)->aopu.aop_dir);
8979 /* the right is also a bit variable */
8980 if (AOP_TYPE(right) == AOP_CRY) {
8983 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8985 pic14_emitcode("clrc","");
8986 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8987 AOP(right)->aopu.aop_dir,
8988 AOP(right)->aopu.aop_dir);
8989 aopPut(AOP(result),"c",0);
8994 if (AOP_TYPE(right) == AOP_REG) {
8995 emitpcode(POC_BCF, popGet(AOP(result),0));
8996 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
8997 emitpcode(POC_BSF, popGet(AOP(result),0));
8999 pic14_toBoolean(right);
9000 aopPut(AOP(result),"a",0);
9004 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9006 size = AOP_SIZE(result);
9008 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9010 emitpcode(POC_CLRF, popGet(AOP(result),0));
9011 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9012 emitpcode(POC_INCF, popGet(AOP(result),0));
9015 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9020 /* if they are the same size : or less */
9021 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9023 /* if they are in the same place */
9024 if (pic14_sameRegs(AOP(right),AOP(result)))
9027 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9028 if (IS_PTR_CONST(rtype))
9029 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9030 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9031 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9033 /* if they in different places then copy */
9034 size = AOP_SIZE(result);
9037 if(AOP_TYPE(right) == AOP_IMMD)
9038 emitpcode(POC_MOVLW, popGetImmd(AOP(right)->aopu.aop_dir,offset));
9040 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9041 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9043 //aopPut(AOP(result),
9044 // aopGet(AOP(right),offset,FALSE,FALSE),
9053 /* if the result is of type pointer */
9054 if (IS_PTR(ctype)) {
9057 sym_link *type = operandType(right);
9058 sym_link *etype = getSpec(type);
9059 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9061 /* pointer to generic pointer */
9062 if (IS_GENPTR(ctype)) {
9066 p_type = DCL_TYPE(type);
9068 /* we have to go by the storage class */
9069 p_type = PTR_TYPE(SPEC_OCLS(etype));
9071 /* if (SPEC_OCLS(etype)->codesp ) */
9072 /* p_type = CPOINTER ; */
9074 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9075 /* p_type = FPOINTER ; */
9077 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9078 /* p_type = PPOINTER; */
9080 /* if (SPEC_OCLS(etype) == idata ) */
9081 /* p_type = IPOINTER ; */
9083 /* p_type = POINTER ; */
9086 /* the first two bytes are known */
9087 size = GPTRSIZE - 1;
9090 if(offset < AOP_SIZE(right))
9092 aopGet(AOP(right),offset,FALSE,FALSE),
9095 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9098 /* the last byte depending on type */
9102 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9105 pic14_emitcode(";BUG!? ","%d",__LINE__);
9109 pic14_emitcode(";BUG!? ","%d",__LINE__);
9113 pic14_emitcode(";BUG!? ","%d",__LINE__);
9118 /* this should never happen */
9119 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9120 "got unknown pointer type");
9123 //aopPut(AOP(result),l, GPTRSIZE - 1);
9127 /* just copy the pointers */
9128 size = AOP_SIZE(result);
9132 aopGet(AOP(right),offset,FALSE,FALSE),
9141 /* so we now know that the size of destination is greater
9142 than the size of the source.
9143 Now, if the next iCode is an operator then we might be
9144 able to optimize the operation without performing a cast.
9146 if(genMixedOperation(ic))
9149 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9151 /* we move to result for the size of source */
9152 size = AOP_SIZE(right);
9155 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9156 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9160 /* now depending on the sign of the destination */
9161 size = AOP_SIZE(result) - AOP_SIZE(right);
9162 /* if unsigned or not an integral type */
9163 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9165 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9167 /* we need to extend the sign :{ */
9170 /* Save one instruction of casting char to int */
9171 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9172 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9173 emitpcode(POC_DECF, popGet(AOP(result),offset));
9175 emitpcodeNULLop(POC_CLRW);
9178 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9180 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9182 emitpcode(POC_MOVLW, popGetLit(0xff));
9185 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9190 freeAsmop(right,NULL,ic,TRUE);
9191 freeAsmop(result,NULL,ic,TRUE);
9195 /*-----------------------------------------------------------------*/
9196 /* genDjnz - generate decrement & jump if not zero instrucion */
9197 /*-----------------------------------------------------------------*/
9198 static int genDjnz (iCode *ic, iCode *ifx)
9201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9206 /* if the if condition has a false label
9207 then we cannot save */
9211 /* if the minus is not of the form
9213 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9214 !IS_OP_LITERAL(IC_RIGHT(ic)))
9217 if (operandLitValue(IC_RIGHT(ic)) != 1)
9220 /* if the size of this greater than one then no
9222 if (getSize(operandType(IC_RESULT(ic))) > 1)
9225 /* otherwise we can save BIG */
9226 lbl = newiTempLabel(NULL);
9227 lbl1= newiTempLabel(NULL);
9229 aopOp(IC_RESULT(ic),ic,FALSE);
9231 if (IS_AOP_PREG(IC_RESULT(ic))) {
9232 pic14_emitcode("dec","%s",
9233 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9234 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9235 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9239 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9240 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9242 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9243 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9246 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9247 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9248 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9249 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9252 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9257 /*-----------------------------------------------------------------*/
9258 /* genReceive - generate code for a receive iCode */
9259 /*-----------------------------------------------------------------*/
9260 static void genReceive (iCode *ic)
9262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9264 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9265 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9266 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9268 int size = getSize(operandType(IC_RESULT(ic)));
9269 int offset = fReturnSizePic - size;
9271 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9272 fReturn[fReturnSizePic - offset - 1] : "acc"));
9275 aopOp(IC_RESULT(ic),ic,FALSE);
9276 size = AOP_SIZE(IC_RESULT(ic));
9279 pic14_emitcode ("pop","acc");
9280 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9285 aopOp(IC_RESULT(ic),ic,FALSE);
9287 assignResultValue(IC_RESULT(ic));
9290 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9293 /*-----------------------------------------------------------------*/
9294 /* genpic14Code - generate code for pic14 based controllers */
9295 /*-----------------------------------------------------------------*/
9297 * At this point, ralloc.c has gone through the iCode and attempted
9298 * to optimize in a way suitable for a PIC. Now we've got to generate
9299 * PIC instructions that correspond to the iCode.
9301 * Once the instructions are generated, we'll pass through both the
9302 * peep hole optimizer and the pCode optimizer.
9303 *-----------------------------------------------------------------*/
9305 void genpic14Code (iCode *lic)
9310 lineHead = lineCurr = NULL;
9312 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9315 /* if debug information required */
9316 if (options.debug && currFunc) {
9318 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9320 if (IS_STATIC(currFunc->etype)) {
9321 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9322 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9324 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9325 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9332 for (ic = lic ; ic ; ic = ic->next ) {
9334 DEBUGpic14_emitcode(";ic","");
9335 if ( cln != ic->lineno ) {
9336 if ( options.debug ) {
9338 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9339 FileBaseName(ic->filename),ic->lineno,
9340 ic->level,ic->block);
9343 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9346 /* if the result is marked as
9347 spilt and rematerializable or code for
9348 this has already been generated then
9350 if (resultRemat(ic) || ic->generated )
9353 /* depending on the operation */
9372 /* IPOP happens only when trying to restore a
9373 spilt live range, if there is an ifx statement
9374 following this pop then the if statement might
9375 be using some of the registers being popped which
9376 would destory the contents of the register so
9377 we need to check for this condition and handle it */
9379 ic->next->op == IFX &&
9380 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9381 genIfx (ic->next,ic);
9399 genEndFunction (ic);
9419 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9436 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9440 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9447 /* note these two are xlated by algebraic equivalence
9448 during parsing SDCC.y */
9449 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9450 "got '>=' or '<=' shouldn't have come here");
9454 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9466 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9470 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9474 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9501 case GET_VALUE_AT_ADDRESS:
9506 if (POINTER_SET(ic))
9533 addSet(&_G.sendSet,ic);
9542 /* now we are ready to call the
9543 peep hole optimizer */
9544 if (!options.nopeep) {
9545 peepHole (&lineHead);
9547 /* now do the actual printing */
9548 printLine (lineHead,codeOutFile);
9551 DFPRINTF((stderr,"printing pBlock\n\n"));
9552 printpBlock(stdout,pb);