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 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1682 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1683 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1685 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1686 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1687 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1692 /* if type float then do float */
1693 if (IS_FLOAT(optype)) {
1694 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1698 size = AOP_SIZE(IC_RESULT(ic));
1700 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1701 emitpcode(POC_ANDLW,popGetLit(1));
1702 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1705 pic14_toBoolean(IC_LEFT(ic));
1707 tlbl = newiTempLabel(NULL);
1708 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1710 pic14_outBitC(IC_RESULT(ic));
1713 /* release the aops */
1714 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1715 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1719 /*-----------------------------------------------------------------*/
1720 /* genCpl - generate code for complement */
1721 /*-----------------------------------------------------------------*/
1722 static void genCpl (iCode *ic)
1728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 /* assign asmOps to operand & result */
1730 aopOp (IC_LEFT(ic),ic,FALSE);
1731 aopOp (IC_RESULT(ic),ic,TRUE);
1733 /* if both are in bit space then
1735 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1736 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1738 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1739 pic14_emitcode("cpl","c");
1740 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1744 size = AOP_SIZE(IC_RESULT(ic));
1746 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1748 pic14_emitcode("cpl","a");
1749 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1754 /* release the aops */
1755 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1756 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1759 /*-----------------------------------------------------------------*/
1760 /* genUminusFloat - unary minus for floating points */
1761 /*-----------------------------------------------------------------*/
1762 static void genUminusFloat(operand *op,operand *result)
1764 int size ,offset =0 ;
1767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1768 /* for this we just need to flip the
1769 first it then copy the rest in place */
1770 size = AOP_SIZE(op) - 1;
1771 l = aopGet(AOP(op),3,FALSE,FALSE);
1775 pic14_emitcode("cpl","acc.7");
1776 aopPut(AOP(result),"a",3);
1780 aopGet(AOP(op),offset,FALSE,FALSE),
1786 /*-----------------------------------------------------------------*/
1787 /* genUminus - unary minus code generation */
1788 /*-----------------------------------------------------------------*/
1789 static void genUminus (iCode *ic)
1792 sym_link *optype, *rtype;
1795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 aopOp(IC_LEFT(ic),ic,FALSE);
1798 aopOp(IC_RESULT(ic),ic,TRUE);
1800 /* if both in bit space then special
1802 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1803 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1805 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1806 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1807 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1812 optype = operandType(IC_LEFT(ic));
1813 rtype = operandType(IC_RESULT(ic));
1815 /* if float then do float stuff */
1816 if (IS_FLOAT(optype)) {
1817 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1821 /* otherwise subtract from zero by taking the 2's complement */
1822 size = AOP_SIZE(IC_LEFT(ic));
1824 for(i=0; i<size; i++) {
1825 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1826 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1828 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1829 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1833 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1834 for(i=1; i<size; i++) {
1836 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1840 /* release the aops */
1841 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1842 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1845 /*-----------------------------------------------------------------*/
1846 /* saveRegisters - will look for a call and save the registers */
1847 /*-----------------------------------------------------------------*/
1848 static void saveRegisters(iCode *lic)
1855 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1857 for (ic = lic ; ic ; ic = ic->next)
1858 if (ic->op == CALL || ic->op == PCALL)
1862 fprintf(stderr,"found parameter push with no function call\n");
1866 /* if the registers have been saved already then
1868 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1871 /* find the registers in use at this time
1872 and push them away to safety */
1873 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1877 if (options.useXstack) {
1878 if (bitVectBitValue(rsave,R0_IDX))
1879 pic14_emitcode("mov","b,r0");
1880 pic14_emitcode("mov","r0,%s",spname);
1881 for (i = 0 ; i < pic14_nRegs ; i++) {
1882 if (bitVectBitValue(rsave,i)) {
1884 pic14_emitcode("mov","a,b");
1886 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1887 pic14_emitcode("movx","@r0,a");
1888 pic14_emitcode("inc","r0");
1891 pic14_emitcode("mov","%s,r0",spname);
1892 if (bitVectBitValue(rsave,R0_IDX))
1893 pic14_emitcode("mov","r0,b");
1895 //for (i = 0 ; i < pic14_nRegs ; i++) {
1896 // if (bitVectBitValue(rsave,i))
1897 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1900 dtype = operandType(IC_LEFT(ic));
1901 if (currFunc && dtype &&
1902 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1903 IFFUNC_ISISR(currFunc->type) &&
1906 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1909 /*-----------------------------------------------------------------*/
1910 /* unsaveRegisters - pop the pushed registers */
1911 /*-----------------------------------------------------------------*/
1912 static void unsaveRegisters (iCode *ic)
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 /* find the registers in use at this time
1919 and push them away to safety */
1920 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1923 if (options.useXstack) {
1924 pic14_emitcode("mov","r0,%s",spname);
1925 for (i = pic14_nRegs ; i >= 0 ; i--) {
1926 if (bitVectBitValue(rsave,i)) {
1927 pic14_emitcode("dec","r0");
1928 pic14_emitcode("movx","a,@r0");
1930 pic14_emitcode("mov","b,a");
1932 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1936 pic14_emitcode("mov","%s,r0",spname);
1937 if (bitVectBitValue(rsave,R0_IDX))
1938 pic14_emitcode("mov","r0,b");
1940 //for (i = pic14_nRegs ; i >= 0 ; i--) {
1941 // if (bitVectBitValue(rsave,i))
1942 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1948 /*-----------------------------------------------------------------*/
1950 /*-----------------------------------------------------------------*/
1951 static void pushSide(operand * oper, int size)
1955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1957 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1958 if (AOP_TYPE(oper) != AOP_REG &&
1959 AOP_TYPE(oper) != AOP_DIR &&
1961 pic14_emitcode("mov","a,%s",l);
1962 pic14_emitcode("push","acc");
1964 pic14_emitcode("push","%s",l);
1969 /*-----------------------------------------------------------------*/
1970 /* assignResultValue - */
1971 /*-----------------------------------------------------------------*/
1972 static void assignResultValue(operand * oper)
1974 int size = AOP_SIZE(oper);
1976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1978 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
1980 if(!GpsuedoStkPtr) {
1981 /* The last byte in the assignment is in W */
1983 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1988 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
1990 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
1995 /*-----------------------------------------------------------------*/
1996 /* genIpush - genrate code for pushing this gets a little complex */
1997 /*-----------------------------------------------------------------*/
1998 static void genIpush (iCode *ic)
2001 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2003 int size, offset = 0 ;
2007 /* if this is not a parm push : ie. it is spill push
2008 and spill push is always done on the local stack */
2009 if (!ic->parmPush) {
2011 /* and the item is spilt then do nothing */
2012 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2015 aopOp(IC_LEFT(ic),ic,FALSE);
2016 size = AOP_SIZE(IC_LEFT(ic));
2017 /* push it on the stack */
2019 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2024 pic14_emitcode("push","%s",l);
2029 /* this is a paramter push: in this case we call
2030 the routine to find the call and save those
2031 registers that need to be saved */
2034 /* then do the push */
2035 aopOp(IC_LEFT(ic),ic,FALSE);
2038 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2039 size = AOP_SIZE(IC_LEFT(ic));
2042 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2043 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2044 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2046 pic14_emitcode("mov","a,%s",l);
2047 pic14_emitcode("push","acc");
2049 pic14_emitcode("push","%s",l);
2052 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2056 /*-----------------------------------------------------------------*/
2057 /* genIpop - recover the registers: can happen only for spilling */
2058 /*-----------------------------------------------------------------*/
2059 static void genIpop (iCode *ic)
2061 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2066 /* if the temp was not pushed then */
2067 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2070 aopOp(IC_LEFT(ic),ic,FALSE);
2071 size = AOP_SIZE(IC_LEFT(ic));
2074 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2077 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2081 /*-----------------------------------------------------------------*/
2082 /* unsaverbank - restores the resgister bank from stack */
2083 /*-----------------------------------------------------------------*/
2084 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2086 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2094 if (options.useXstack) {
2096 r = getFreePtr(ic,&aop,FALSE);
2099 pic14_emitcode("mov","%s,_spx",r->name);
2100 pic14_emitcode("movx","a,@%s",r->name);
2101 pic14_emitcode("mov","psw,a");
2102 pic14_emitcode("dec","%s",r->name);
2105 pic14_emitcode ("pop","psw");
2108 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2109 if (options.useXstack) {
2110 pic14_emitcode("movx","a,@%s",r->name);
2111 //pic14_emitcode("mov","(%s+%d),a",
2112 // regspic14[i].base,8*bank+regspic14[i].offset);
2113 pic14_emitcode("dec","%s",r->name);
2116 pic14_emitcode("pop",""); //"(%s+%d)",
2117 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2120 if (options.useXstack) {
2122 pic14_emitcode("mov","_spx,%s",r->name);
2123 freeAsmop(NULL,aop,ic,TRUE);
2129 /*-----------------------------------------------------------------*/
2130 /* saverbank - saves an entire register bank on the stack */
2131 /*-----------------------------------------------------------------*/
2132 static void saverbank (int bank, iCode *ic, bool pushPsw)
2134 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2141 if (options.useXstack) {
2144 r = getFreePtr(ic,&aop,FALSE);
2145 pic14_emitcode("mov","%s,_spx",r->name);
2149 for (i = 0 ; i < pic14_nRegs ;i++) {
2150 if (options.useXstack) {
2151 pic14_emitcode("inc","%s",r->name);
2152 //pic14_emitcode("mov","a,(%s+%d)",
2153 // regspic14[i].base,8*bank+regspic14[i].offset);
2154 pic14_emitcode("movx","@%s,a",r->name);
2156 pic14_emitcode("push","");// "(%s+%d)",
2157 //regspic14[i].base,8*bank+regspic14[i].offset);
2161 if (options.useXstack) {
2162 pic14_emitcode("mov","a,psw");
2163 pic14_emitcode("movx","@%s,a",r->name);
2164 pic14_emitcode("inc","%s",r->name);
2165 pic14_emitcode("mov","_spx,%s",r->name);
2166 freeAsmop (NULL,aop,ic,TRUE);
2169 pic14_emitcode("push","psw");
2171 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2177 /*-----------------------------------------------------------------*/
2178 /* genCall - generates a call statement */
2179 /*-----------------------------------------------------------------*/
2180 static void genCall (iCode *ic)
2184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2186 /* if caller saves & we have not saved then */
2190 /* if we are calling a function that is not using
2191 the same register bank then we need to save the
2192 destination registers on the stack */
2193 dtype = operandType(IC_LEFT(ic));
2194 if (currFunc && dtype &&
2195 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2196 IFFUNC_ISISR(currFunc->type) &&
2199 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2201 /* if send set is not empty the assign */
2204 /* For the Pic port, there is no data stack.
2205 * So parameters passed to functions are stored
2206 * in registers. (The pCode optimizer will get
2207 * rid of most of these :).
2209 int psuedoStkPtr=-1;
2210 int firstTimeThruLoop = 1;
2212 _G.sendSet = reverseSet(_G.sendSet);
2214 /* First figure how many parameters are getting passed */
2215 for (sic = setFirstItem(_G.sendSet) ; sic ;
2216 sic = setNextItem(_G.sendSet)) {
2218 aopOp(IC_LEFT(sic),sic,FALSE);
2219 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2220 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2223 for (sic = setFirstItem(_G.sendSet) ; sic ;
2224 sic = setNextItem(_G.sendSet)) {
2225 int size, offset = 0;
2227 aopOp(IC_LEFT(sic),sic,FALSE);
2228 size = AOP_SIZE(IC_LEFT(sic));
2232 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2233 AopType(AOP_TYPE(IC_LEFT(sic))));
2235 if(!firstTimeThruLoop) {
2236 /* If this is not the first time we've been through the loop
2237 * then we need to save the parameter in a temporary
2238 * register. The last byte of the last parameter is
2240 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2243 firstTimeThruLoop=0;
2245 //if (strcmp(l,fReturn[offset])) {
2247 if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2248 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2249 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2251 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2256 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2261 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2262 OP_SYMBOL(IC_LEFT(ic))->rname :
2263 OP_SYMBOL(IC_LEFT(ic))->name));
2266 /* if we need assign a result value */
2267 if ((IS_ITEMP(IC_RESULT(ic)) &&
2268 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2269 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2270 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2273 aopOp(IC_RESULT(ic),ic,FALSE);
2276 assignResultValue(IC_RESULT(ic));
2278 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2279 AopType(AOP_TYPE(IC_RESULT(ic))));
2281 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2284 /* adjust the stack for parameters if
2286 if (ic->parmBytes) {
2288 if (ic->parmBytes > 3) {
2289 pic14_emitcode("mov","a,%s",spname);
2290 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2291 pic14_emitcode("mov","%s,a",spname);
2293 for ( i = 0 ; i < ic->parmBytes ;i++)
2294 pic14_emitcode("dec","%s",spname);
2298 /* if register bank was saved then pop them */
2300 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2302 /* if we hade saved some registers then unsave them */
2303 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2304 unsaveRegisters (ic);
2309 /*-----------------------------------------------------------------*/
2310 /* genPcall - generates a call by pointer statement */
2311 /*-----------------------------------------------------------------*/
2312 static void genPcall (iCode *ic)
2315 symbol *rlbl = newiTempLabel(NULL);
2318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2319 /* if caller saves & we have not saved then */
2323 /* if we are calling a function that is not using
2324 the same register bank then we need to save the
2325 destination registers on the stack */
2326 dtype = operandType(IC_LEFT(ic));
2327 if (currFunc && dtype &&
2328 IFFUNC_ISISR(currFunc->type) &&
2329 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2330 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2333 /* push the return address on to the stack */
2334 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2335 pic14_emitcode("push","acc");
2336 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2337 pic14_emitcode("push","acc");
2339 if (options.model == MODEL_FLAT24)
2341 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2342 pic14_emitcode("push","acc");
2345 /* now push the calling address */
2346 aopOp(IC_LEFT(ic),ic,FALSE);
2348 pushSide(IC_LEFT(ic), FPTRSIZE);
2350 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2352 /* if send set is not empty the assign */
2356 for (sic = setFirstItem(_G.sendSet) ; sic ;
2357 sic = setNextItem(_G.sendSet)) {
2358 int size, offset = 0;
2359 aopOp(IC_LEFT(sic),sic,FALSE);
2360 size = AOP_SIZE(IC_LEFT(sic));
2362 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2364 if (strcmp(l,fReturn[offset]))
2365 pic14_emitcode("mov","%s,%s",
2370 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2375 pic14_emitcode("ret","");
2376 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2379 /* if we need assign a result value */
2380 if ((IS_ITEMP(IC_RESULT(ic)) &&
2381 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2382 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2383 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2386 aopOp(IC_RESULT(ic),ic,FALSE);
2389 assignResultValue(IC_RESULT(ic));
2391 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2394 /* adjust the stack for parameters if
2396 if (ic->parmBytes) {
2398 if (ic->parmBytes > 3) {
2399 pic14_emitcode("mov","a,%s",spname);
2400 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2401 pic14_emitcode("mov","%s,a",spname);
2403 for ( i = 0 ; i < ic->parmBytes ;i++)
2404 pic14_emitcode("dec","%s",spname);
2408 /* if register bank was saved then unsave them */
2409 if (currFunc && dtype &&
2410 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2411 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2413 /* if we hade saved some registers then
2416 unsaveRegisters (ic);
2420 /*-----------------------------------------------------------------*/
2421 /* resultRemat - result is rematerializable */
2422 /*-----------------------------------------------------------------*/
2423 static int resultRemat (iCode *ic)
2425 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2426 if (SKIP_IC(ic) || ic->op == IFX)
2429 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2430 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2431 if (sym->remat && !POINTER_SET(ic))
2438 #if defined(__BORLANDC__) || defined(_MSC_VER)
2439 #define STRCASECMP stricmp
2441 #define STRCASECMP strcasecmp
2444 /*-----------------------------------------------------------------*/
2445 /* inExcludeList - return 1 if the string is in exclude Reg list */
2446 /*-----------------------------------------------------------------*/
2447 static bool inExcludeList(char *s)
2449 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2454 if (options.excludeRegs[i] &&
2455 STRCASECMP(options.excludeRegs[i],"none") == 0)
2458 for ( i = 0 ; options.excludeRegs[i]; i++) {
2459 if (options.excludeRegs[i] &&
2460 STRCASECMP(s,options.excludeRegs[i]) == 0)
2467 /*-----------------------------------------------------------------*/
2468 /* genFunction - generated code for function entry */
2469 /*-----------------------------------------------------------------*/
2470 static void genFunction (iCode *ic)
2475 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2477 labelOffset += (max_key+4);
2481 /* create the function header */
2482 pic14_emitcode(";","-----------------------------------------");
2483 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2484 pic14_emitcode(";","-----------------------------------------");
2486 pic14_emitcode("","%s:",sym->rname);
2487 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2489 ftype = operandType(IC_LEFT(ic));
2491 /* if critical function then turn interrupts off */
2492 if (IFFUNC_ISCRITICAL(ftype))
2493 pic14_emitcode("clr","ea");
2495 /* here we need to generate the equates for the
2496 register bank if required */
2498 if (FUNC_REGBANK(ftype) != rbank) {
2501 rbank = FUNC_REGBANK(ftype);
2502 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2503 if (strcmp(regspic14[i].base,"0") == 0)
2504 pic14_emitcode("","%s = 0x%02x",
2506 8*rbank+regspic14[i].offset);
2508 pic14_emitcode ("","%s = %s + 0x%02x",
2511 8*rbank+regspic14[i].offset);
2516 /* if this is an interrupt service routine then
2517 save acc, b, dpl, dph */
2518 if (IFFUNC_ISISR(sym->type)) {
2519 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2520 emitpcodeNULLop(POC_NOP);
2521 emitpcodeNULLop(POC_NOP);
2522 emitpcodeNULLop(POC_NOP);
2523 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2524 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2525 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2526 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2528 pBlockConvert2ISR(pb);
2530 if (!inExcludeList("acc"))
2531 pic14_emitcode ("push","acc");
2532 if (!inExcludeList("b"))
2533 pic14_emitcode ("push","b");
2534 if (!inExcludeList("dpl"))
2535 pic14_emitcode ("push","dpl");
2536 if (!inExcludeList("dph"))
2537 pic14_emitcode ("push","dph");
2538 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2540 pic14_emitcode ("push", "dpx");
2541 /* Make sure we're using standard DPTR */
2542 pic14_emitcode ("push", "dps");
2543 pic14_emitcode ("mov", "dps, #0x00");
2544 if (options.stack10bit)
2546 /* This ISR could conceivably use DPTR2. Better save it. */
2547 pic14_emitcode ("push", "dpl1");
2548 pic14_emitcode ("push", "dph1");
2549 pic14_emitcode ("push", "dpx1");
2552 /* if this isr has no bank i.e. is going to
2553 run with bank 0 , then we need to save more
2555 if (!FUNC_REGBANK(sym->type)) {
2557 /* if this function does not call any other
2558 function then we can be economical and
2559 save only those registers that are used */
2560 if (! IFFUNC_HASFCALL(sym->type)) {
2563 /* if any registers used */
2564 if (sym->regsUsed) {
2565 /* save the registers used */
2566 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2567 if (bitVectBitValue(sym->regsUsed,i) ||
2568 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2569 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2574 /* this function has a function call cannot
2575 determines register usage so we will have the
2577 saverbank(0,ic,FALSE);
2582 /* if callee-save to be used for this function
2583 then save the registers being used in this function */
2584 if (IFFUNC_CALLEESAVES(sym->type)) {
2587 /* if any registers used */
2588 if (sym->regsUsed) {
2589 /* save the registers used */
2590 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2591 if (bitVectBitValue(sym->regsUsed,i) ||
2592 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2593 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2601 /* set the register bank to the desired value */
2602 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2603 pic14_emitcode("push","psw");
2604 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2607 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2609 if (options.useXstack) {
2610 pic14_emitcode("mov","r0,%s",spname);
2611 pic14_emitcode("mov","a,_bp");
2612 pic14_emitcode("movx","@r0,a");
2613 pic14_emitcode("inc","%s",spname);
2617 /* set up the stack */
2618 pic14_emitcode ("push","_bp"); /* save the callers stack */
2620 pic14_emitcode ("mov","_bp,%s",spname);
2623 /* adjust the stack for the function */
2628 werror(W_STACK_OVERFLOW,sym->name);
2630 if (i > 3 && sym->recvSize < 4) {
2632 pic14_emitcode ("mov","a,sp");
2633 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2634 pic14_emitcode ("mov","sp,a");
2639 pic14_emitcode("inc","sp");
2644 pic14_emitcode ("mov","a,_spx");
2645 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2646 pic14_emitcode ("mov","_spx,a");
2651 /*-----------------------------------------------------------------*/
2652 /* genEndFunction - generates epilogue for functions */
2653 /*-----------------------------------------------------------------*/
2654 static void genEndFunction (iCode *ic)
2656 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2658 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2660 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2662 pic14_emitcode ("mov","%s,_bp",spname);
2665 /* if use external stack but some variables were
2666 added to the local stack then decrement the
2668 if (options.useXstack && sym->stack) {
2669 pic14_emitcode("mov","a,sp");
2670 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2671 pic14_emitcode("mov","sp,a");
2675 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2676 if (options.useXstack) {
2677 pic14_emitcode("mov","r0,%s",spname);
2678 pic14_emitcode("movx","a,@r0");
2679 pic14_emitcode("mov","_bp,a");
2680 pic14_emitcode("dec","%s",spname);
2684 pic14_emitcode ("pop","_bp");
2688 /* restore the register bank */
2689 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2690 pic14_emitcode ("pop","psw");
2692 if (IFFUNC_ISISR(sym->type)) {
2694 /* now we need to restore the registers */
2695 /* if this isr has no bank i.e. is going to
2696 run with bank 0 , then we need to save more
2698 if (!FUNC_REGBANK(sym->type)) {
2700 /* if this function does not call any other
2701 function then we can be economical and
2702 save only those registers that are used */
2703 if (! IFFUNC_HASFCALL(sym->type)) {
2706 /* if any registers used */
2707 if (sym->regsUsed) {
2708 /* save the registers used */
2709 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2710 if (bitVectBitValue(sym->regsUsed,i) ||
2711 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2712 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2717 /* this function has a function call cannot
2718 determines register usage so we will have the
2720 unsaverbank(0,ic,FALSE);
2724 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2726 if (options.stack10bit)
2728 pic14_emitcode ("pop", "dpx1");
2729 pic14_emitcode ("pop", "dph1");
2730 pic14_emitcode ("pop", "dpl1");
2732 pic14_emitcode ("pop", "dps");
2733 pic14_emitcode ("pop", "dpx");
2735 if (!inExcludeList("dph"))
2736 pic14_emitcode ("pop","dph");
2737 if (!inExcludeList("dpl"))
2738 pic14_emitcode ("pop","dpl");
2739 if (!inExcludeList("b"))
2740 pic14_emitcode ("pop","b");
2741 if (!inExcludeList("acc"))
2742 pic14_emitcode ("pop","acc");
2744 if (IFFUNC_ISCRITICAL(sym->type))
2745 pic14_emitcode("setb","ea");
2748 /* if debug then send end of function */
2749 /* if (options.debug && currFunc) { */
2752 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2753 FileBaseName(ic->filename),currFunc->lastLine,
2754 ic->level,ic->block);
2755 if (IS_STATIC(currFunc->etype))
2756 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2758 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2762 pic14_emitcode ("reti","");
2764 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2765 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2766 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2767 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2768 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2769 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2771 emitpcodeNULLop(POC_RETFIE);
2775 if (IFFUNC_ISCRITICAL(sym->type))
2776 pic14_emitcode("setb","ea");
2778 if (IFFUNC_CALLEESAVES(sym->type)) {
2781 /* if any registers used */
2782 if (sym->regsUsed) {
2783 /* save the registers used */
2784 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2785 if (bitVectBitValue(sym->regsUsed,i) ||
2786 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2787 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2793 /* if debug then send end of function */
2796 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2797 FileBaseName(ic->filename),currFunc->lastLine,
2798 ic->level,ic->block);
2799 if (IS_STATIC(currFunc->etype))
2800 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2802 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2806 pic14_emitcode ("return","");
2807 emitpcodeNULLop(POC_RETURN);
2809 /* Mark the end of a function */
2810 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2815 /*-----------------------------------------------------------------*/
2816 /* genRet - generate code for return statement */
2817 /*-----------------------------------------------------------------*/
2818 static void genRet (iCode *ic)
2820 int size,offset = 0 , pushed = 0;
2822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2823 /* if we have no return value then
2824 just generate the "ret" */
2828 /* we have something to return then
2829 move the return value into place */
2830 aopOp(IC_LEFT(ic),ic,FALSE);
2831 size = AOP_SIZE(IC_LEFT(ic));
2835 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2837 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2839 pic14_emitcode("push","%s",l);
2842 l = aopGet(AOP(IC_LEFT(ic)),offset,
2844 if (strcmp(fReturn[offset],l)) {
2845 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2846 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2847 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2849 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2852 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2853 pic14_emitcode("movwf","%s",fReturn[offset]);
2863 if (strcmp(fReturn[pushed],"a"))
2864 pic14_emitcode("pop",fReturn[pushed]);
2866 pic14_emitcode("pop","acc");
2869 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2872 /* generate a jump to the return label
2873 if the next is not the return statement */
2874 if (!(ic->next && ic->next->op == LABEL &&
2875 IC_LABEL(ic->next) == returnLabel)) {
2877 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2878 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2883 /*-----------------------------------------------------------------*/
2884 /* genLabel - generates a label */
2885 /*-----------------------------------------------------------------*/
2886 static void genLabel (iCode *ic)
2888 /* special case never generate */
2889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2890 if (IC_LABEL(ic) == entryLabel)
2893 emitpLabel(IC_LABEL(ic)->key);
2894 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2897 /*-----------------------------------------------------------------*/
2898 /* genGoto - generates a goto */
2899 /*-----------------------------------------------------------------*/
2901 static void genGoto (iCode *ic)
2903 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2904 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2908 /*-----------------------------------------------------------------*/
2909 /* genMultbits :- multiplication of bits */
2910 /*-----------------------------------------------------------------*/
2911 static void genMultbits (operand *left,
2915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2917 if(!pic14_sameRegs(AOP(result),AOP(right)))
2918 emitpcode(POC_BSF, popGet(AOP(result),0));
2920 emitpcode(POC_BTFSC,popGet(AOP(right),0));
2921 emitpcode(POC_BTFSS,popGet(AOP(left),0));
2922 emitpcode(POC_BCF, popGet(AOP(result),0));
2927 /*-----------------------------------------------------------------*/
2928 /* genMultOneByte : 8 bit multiplication & division */
2929 /*-----------------------------------------------------------------*/
2930 static void genMultOneByte (operand *left,
2934 sym_link *opetype = operandType(result);
2939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2940 DEBUGpic14_AopType(__LINE__,left,right,result);
2942 /* (if two literals, the value is computed before) */
2943 /* if one literal, literal on the right */
2944 if (AOP_TYPE(left) == AOP_LIT){
2950 size = AOP_SIZE(result);
2951 /* signed or unsigned */
2952 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
2953 l = aopGet(AOP(left),0,FALSE,FALSE);
2955 pic14_emitcode("mul","ab");
2956 /* if result size = 1, mul signed = mul unsigned */
2957 aopPut(AOP(result),"a",0);
2959 if (SPEC_USIGN(opetype)){
2960 aopPut(AOP(result),"b",1);
2962 /* for filling the MSBs */
2963 pic14_emitcode("clr","a");
2966 pic14_emitcode("mov","a,b");
2968 /* adjust the MSB if left or right neg */
2970 /* if one literal */
2971 if (AOP_TYPE(right) == AOP_LIT){
2972 /* AND literal negative */
2973 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
2974 /* adjust MSB (c==0 after mul) */
2975 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2979 lbl = newiTempLabel(NULL);
2980 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2981 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2982 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2983 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
2984 lbl = newiTempLabel(NULL);
2985 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2986 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
2987 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2990 lbl = newiTempLabel(NULL);
2991 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2992 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
2993 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
2994 pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
2995 lbl = newiTempLabel(NULL);
2996 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
2997 pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
2998 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3000 aopPut(AOP(result),"a",1);
3003 pic14_emitcode("rlc","a");
3004 pic14_emitcode("subb","a,acc");
3011 aopPut(AOP(result),"a",offset++);
3015 /*-----------------------------------------------------------------*/
3016 /* genMult - generates code for multiplication */
3017 /*-----------------------------------------------------------------*/
3018 static void genMult (iCode *ic)
3020 operand *left = IC_LEFT(ic);
3021 operand *right = IC_RIGHT(ic);
3022 operand *result= IC_RESULT(ic);
3024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3025 /* assign the amsops */
3026 aopOp (left,ic,FALSE);
3027 aopOp (right,ic,FALSE);
3028 aopOp (result,ic,TRUE);
3030 DEBUGpic14_AopType(__LINE__,left,right,result);
3032 /* special cases first */
3034 if (AOP_TYPE(left) == AOP_CRY &&
3035 AOP_TYPE(right)== AOP_CRY) {
3036 genMultbits(left,right,result);
3040 /* if both are of size == 1 */
3041 if (AOP_SIZE(left) == 1 &&
3042 AOP_SIZE(right) == 1 ) {
3043 genMultOneByte(left,right,result);
3047 /* should have been converted to function call */
3051 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3052 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3053 freeAsmop(result,NULL,ic,TRUE);
3056 /*-----------------------------------------------------------------*/
3057 /* genDivbits :- division of bits */
3058 /*-----------------------------------------------------------------*/
3059 static void genDivbits (operand *left,
3066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3067 /* the result must be bit */
3068 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3069 l = aopGet(AOP(left),0,FALSE,FALSE);
3073 pic14_emitcode("div","ab");
3074 pic14_emitcode("rrc","a");
3075 aopPut(AOP(result),"c",0);
3078 /*-----------------------------------------------------------------*/
3079 /* genDivOneByte : 8 bit division */
3080 /*-----------------------------------------------------------------*/
3081 static void genDivOneByte (operand *left,
3085 sym_link *opetype = operandType(result);
3090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3091 size = AOP_SIZE(result) - 1;
3093 /* signed or unsigned */
3094 if (SPEC_USIGN(opetype)) {
3095 /* unsigned is easy */
3096 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3097 l = aopGet(AOP(left),0,FALSE,FALSE);
3099 pic14_emitcode("div","ab");
3100 aopPut(AOP(result),"a",0);
3102 aopPut(AOP(result),zero,offset++);
3106 /* signed is a little bit more difficult */
3108 /* save the signs of the operands */
3109 l = aopGet(AOP(left),0,FALSE,FALSE);
3111 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3112 pic14_emitcode("push","acc"); /* save it on the stack */
3114 /* now sign adjust for both left & right */
3115 l = aopGet(AOP(right),0,FALSE,FALSE);
3117 lbl = newiTempLabel(NULL);
3118 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3119 pic14_emitcode("cpl","a");
3120 pic14_emitcode("inc","a");
3121 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3122 pic14_emitcode("mov","b,a");
3124 /* sign adjust left side */
3125 l = aopGet(AOP(left),0,FALSE,FALSE);
3128 lbl = newiTempLabel(NULL);
3129 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3130 pic14_emitcode("cpl","a");
3131 pic14_emitcode("inc","a");
3132 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3134 /* now the division */
3135 pic14_emitcode("div","ab");
3136 /* we are interested in the lower order
3138 pic14_emitcode("mov","b,a");
3139 lbl = newiTempLabel(NULL);
3140 pic14_emitcode("pop","acc");
3141 /* if there was an over flow we don't
3142 adjust the sign of the result */
3143 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3144 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3146 pic14_emitcode("clr","a");
3147 pic14_emitcode("subb","a,b");
3148 pic14_emitcode("mov","b,a");
3149 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3151 /* now we are done */
3152 aopPut(AOP(result),"b",0);
3154 pic14_emitcode("mov","c,b.7");
3155 pic14_emitcode("subb","a,acc");
3158 aopPut(AOP(result),"a",offset++);
3162 /*-----------------------------------------------------------------*/
3163 /* genDiv - generates code for division */
3164 /*-----------------------------------------------------------------*/
3165 static void genDiv (iCode *ic)
3167 operand *left = IC_LEFT(ic);
3168 operand *right = IC_RIGHT(ic);
3169 operand *result= IC_RESULT(ic);
3171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3172 /* assign the amsops */
3173 aopOp (left,ic,FALSE);
3174 aopOp (right,ic,FALSE);
3175 aopOp (result,ic,TRUE);
3177 /* special cases first */
3179 if (AOP_TYPE(left) == AOP_CRY &&
3180 AOP_TYPE(right)== AOP_CRY) {
3181 genDivbits(left,right,result);
3185 /* if both are of size == 1 */
3186 if (AOP_SIZE(left) == 1 &&
3187 AOP_SIZE(right) == 1 ) {
3188 genDivOneByte(left,right,result);
3192 /* should have been converted to function call */
3195 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3196 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3197 freeAsmop(result,NULL,ic,TRUE);
3200 /*-----------------------------------------------------------------*/
3201 /* genModbits :- modulus of bits */
3202 /*-----------------------------------------------------------------*/
3203 static void genModbits (operand *left,
3210 /* the result must be bit */
3211 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3212 l = aopGet(AOP(left),0,FALSE,FALSE);
3216 pic14_emitcode("div","ab");
3217 pic14_emitcode("mov","a,b");
3218 pic14_emitcode("rrc","a");
3219 aopPut(AOP(result),"c",0);
3222 /*-----------------------------------------------------------------*/
3223 /* genModOneByte : 8 bit modulus */
3224 /*-----------------------------------------------------------------*/
3225 static void genModOneByte (operand *left,
3229 sym_link *opetype = operandType(result);
3233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3234 /* signed or unsigned */
3235 if (SPEC_USIGN(opetype)) {
3236 /* unsigned is easy */
3237 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3238 l = aopGet(AOP(left),0,FALSE,FALSE);
3240 pic14_emitcode("div","ab");
3241 aopPut(AOP(result),"b",0);
3245 /* signed is a little bit more difficult */
3247 /* save the signs of the operands */
3248 l = aopGet(AOP(left),0,FALSE,FALSE);
3251 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3252 pic14_emitcode("push","acc"); /* save it on the stack */
3254 /* now sign adjust for both left & right */
3255 l = aopGet(AOP(right),0,FALSE,FALSE);
3258 lbl = newiTempLabel(NULL);
3259 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("cpl","a");
3261 pic14_emitcode("inc","a");
3262 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263 pic14_emitcode("mov","b,a");
3265 /* sign adjust left side */
3266 l = aopGet(AOP(left),0,FALSE,FALSE);
3269 lbl = newiTempLabel(NULL);
3270 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3271 pic14_emitcode("cpl","a");
3272 pic14_emitcode("inc","a");
3273 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3275 /* now the multiplication */
3276 pic14_emitcode("div","ab");
3277 /* we are interested in the lower order
3279 lbl = newiTempLabel(NULL);
3280 pic14_emitcode("pop","acc");
3281 /* if there was an over flow we don't
3282 adjust the sign of the result */
3283 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3284 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3286 pic14_emitcode("clr","a");
3287 pic14_emitcode("subb","a,b");
3288 pic14_emitcode("mov","b,a");
3289 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3291 /* now we are done */
3292 aopPut(AOP(result),"b",0);
3296 /*-----------------------------------------------------------------*/
3297 /* genMod - generates code for division */
3298 /*-----------------------------------------------------------------*/
3299 static void genMod (iCode *ic)
3301 operand *left = IC_LEFT(ic);
3302 operand *right = IC_RIGHT(ic);
3303 operand *result= IC_RESULT(ic);
3305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3306 /* assign the amsops */
3307 aopOp (left,ic,FALSE);
3308 aopOp (right,ic,FALSE);
3309 aopOp (result,ic,TRUE);
3311 /* special cases first */
3313 if (AOP_TYPE(left) == AOP_CRY &&
3314 AOP_TYPE(right)== AOP_CRY) {
3315 genModbits(left,right,result);
3319 /* if both are of size == 1 */
3320 if (AOP_SIZE(left) == 1 &&
3321 AOP_SIZE(right) == 1 ) {
3322 genModOneByte(left,right,result);
3326 /* should have been converted to function call */
3330 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3331 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3332 freeAsmop(result,NULL,ic,TRUE);
3335 /*-----------------------------------------------------------------*/
3336 /* genIfxJump :- will create a jump depending on the ifx */
3337 /*-----------------------------------------------------------------*/
3339 note: May need to add parameter to indicate when a variable is in bit space.
3341 static void genIfxJump (iCode *ic, char *jval)
3344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3345 /* if true label then we jump if condition
3347 if ( IC_TRUE(ic) ) {
3349 if(strcmp(jval,"a") == 0)
3351 else if (strcmp(jval,"c") == 0)
3354 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3355 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3358 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3359 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3363 /* false label is present */
3364 if(strcmp(jval,"a") == 0)
3366 else if (strcmp(jval,"c") == 0)
3369 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3370 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3373 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3374 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3379 /* mark the icode as generated */
3383 /*-----------------------------------------------------------------*/
3385 /*-----------------------------------------------------------------*/
3386 static void genSkip(iCode *ifx,int status_bit)
3391 if ( IC_TRUE(ifx) ) {
3392 switch(status_bit) {
3407 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3408 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3412 switch(status_bit) {
3426 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3427 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3433 /*-----------------------------------------------------------------*/
3435 /*-----------------------------------------------------------------*/
3436 static void genSkipc(resolvedIfx *rifx)
3446 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3447 rifx->generated = 1;
3450 /*-----------------------------------------------------------------*/
3452 /*-----------------------------------------------------------------*/
3453 static void genSkipz2(resolvedIfx *rifx)
3463 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3464 rifx->generated = 1;
3467 /*-----------------------------------------------------------------*/
3469 /*-----------------------------------------------------------------*/
3470 static void genSkipz(iCode *ifx, int condition)
3481 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3483 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3486 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3488 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3491 /*-----------------------------------------------------------------*/
3493 /*-----------------------------------------------------------------*/
3494 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3500 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3502 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3505 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3506 rifx->generated = 1;
3510 /*-----------------------------------------------------------------*/
3511 /* genChkZeroes :- greater or less than comparison */
3512 /* For each byte in a literal that is zero, inclusive or the */
3513 /* the corresponding byte in the operand with W */
3514 /* returns true if any of the bytes are zero */
3515 /*-----------------------------------------------------------------*/
3516 static int genChkZeroes(operand *op, int lit, int size)
3523 i = (lit >> (size*8)) & 0xff;
3527 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3529 emitpcode(POC_IORFW, popGet(AOP(op),size));
3538 /*-----------------------------------------------------------------*/
3539 /* genCmp :- greater or less than comparison */
3540 /*-----------------------------------------------------------------*/
3541 static void genCmp (operand *left,operand *right,
3542 operand *result, iCode *ifx, int sign)
3544 int size, offset = 0 ;
3545 unsigned long lit = 0L,i = 0;
3546 resolvedIfx rFalseIfx;
3547 // resolvedIfx rTrueIfx;
3549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3551 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3552 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3556 resolveIfx(&rFalseIfx,ifx);
3557 truelbl = newiTempLabel(NULL);
3559 //if(IC_TRUE(ifx) == NULL)
3560 /* if left & right are bit variables */
3561 if (AOP_TYPE(left) == AOP_CRY &&
3562 AOP_TYPE(right) == AOP_CRY ) {
3563 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3564 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3566 /* subtract right from left if at the
3567 end the carry flag is set then we know that
3568 left is greater than right */
3569 size = max(AOP_SIZE(left),AOP_SIZE(right));
3571 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3572 if((size == 1) && !sign &&
3573 (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3574 symbol *lbl = newiTempLabel(NULL);
3575 pic14_emitcode("cjne","%s,%s,%05d_DS_",
3576 aopGet(AOP(left),offset,FALSE,FALSE),
3577 aopGet(AOP(right),offset,FALSE,FALSE),
3579 pic14_emitcode("","%05d_DS_:",lbl->key+100);
3582 symbol *lbl = newiTempLabel(NULL);
3584 if(AOP_TYPE(right) == AOP_LIT) {
3586 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3588 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3595 genSkipCond(&rFalseIfx,left,size-1,7);
3597 /* no need to compare to 0...*/
3598 /* NOTE: this is a de-generate compare that most certainly
3599 * creates some dead code. */
3600 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3602 if(ifx) ifx->generated = 1;
3609 //i = (lit >> (size*8)) & 0xff;
3610 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3612 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3614 i = ((0-lit) & 0xff);
3617 /* lit is 0x7f, all signed chars are less than
3618 * this except for 0x7f itself */
3619 emitpcode(POC_XORLW, popGetLit(0x7f));
3620 genSkipz2(&rFalseIfx);
3622 emitpcode(POC_ADDLW, popGetLit(0x80));
3623 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3624 genSkipc(&rFalseIfx);
3628 emitpcode(POC_ADDLW, popGetLit(i));
3629 genSkipc(&rFalseIfx);
3633 if(ifx) ifx->generated = 1;
3637 /* chars are out of the way. now do ints and longs */
3640 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3647 genSkipCond(&rFalseIfx,left,size,7);
3648 if(ifx) ifx->generated = 1;
3653 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3655 //rFalseIfx.condition ^= 1;
3656 //genSkipCond(&rFalseIfx,left,size,7);
3657 //rFalseIfx.condition ^= 1;
3659 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3660 if(rFalseIfx.condition)
3661 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3663 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3665 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3666 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3667 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3670 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3672 if(rFalseIfx.condition) {
3674 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3680 genSkipc(&rFalseIfx);
3681 emitpLabel(truelbl->key);
3682 if(ifx) ifx->generated = 1;
3689 if( (lit & 0xff) == 0) {
3690 /* lower byte is zero */
3691 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3692 i = ((lit >> 8) & 0xff) ^0x80;
3693 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3694 emitpcode(POC_ADDLW, popGetLit( 0x80));
3695 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3696 genSkipc(&rFalseIfx);
3699 if(ifx) ifx->generated = 1;
3704 /* Special cases for signed longs */
3705 if( (lit & 0xffffff) == 0) {
3706 /* lower byte is zero */
3707 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3708 i = ((lit >> 8*3) & 0xff) ^0x80;
3709 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3710 emitpcode(POC_ADDLW, popGetLit( 0x80));
3711 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3712 genSkipc(&rFalseIfx);
3715 if(ifx) ifx->generated = 1;
3723 if(lit & (0x80 << (size*8))) {
3724 /* lit is negative */
3725 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3727 //genSkipCond(&rFalseIfx,left,size,7);
3729 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3731 if(rFalseIfx.condition)
3732 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3734 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3738 /* lit is positive */
3739 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3740 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3741 if(rFalseIfx.condition)
3742 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3744 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3746 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3747 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3748 //rFalseIfx.condition ^= 1;
3749 //genSkipCond(&rFalseIfx,left,size,7);
3750 //rFalseIfx.condition ^= 1;
3754 This works, but is only good for ints.
3755 It also requires a "known zero" register.
3756 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3757 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3758 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3759 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3760 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3761 genSkipc(&rFalseIfx);
3763 emitpLabel(truelbl->key);
3764 if(ifx) ifx->generated = 1;
3768 /* There are no more special cases, so perform a general compare */
3770 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3771 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3775 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3777 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3779 //rFalseIfx.condition ^= 1;
3780 genSkipc(&rFalseIfx);
3782 emitpLabel(truelbl->key);
3784 if(ifx) ifx->generated = 1;
3791 /* sign is out of the way. So now do an unsigned compare */
3792 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3795 //genChkZeroes(left)
3797 /* General case - compare to an unsigned literal on the right.*/
3799 i = (lit >> (size*8)) & 0xff;
3800 emitpcode(POC_MOVLW, popGetLit(i));
3801 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3803 i = (lit >> (size*8)) & 0xff;
3806 emitpcode(POC_MOVLW, popGetLit(i));
3808 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3810 /* this byte of the lit is zero,
3811 *if it's not the last then OR in the variable */
3813 emitpcode(POC_IORFW, popGet(AOP(left),size));
3818 emitpLabel(lbl->key);
3819 //if(emitFinalCheck)
3820 genSkipc(&rFalseIfx);
3822 emitpLabel(truelbl->key);
3824 if(ifx) ifx->generated = 1;
3830 if(AOP_TYPE(left) == AOP_LIT) {
3831 //symbol *lbl = newiTempLabel(NULL);
3833 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3836 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3839 if((lit == 0) && (sign == 0)){
3842 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3844 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3846 //rFalseIfx.condition ^= 1;
3847 genSkipz2(&rFalseIfx);
3848 if(ifx) ifx->generated = 1;
3855 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3856 /* degenerate compare can never be true */
3857 if(rFalseIfx.condition == 0)
3858 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3860 if(ifx) ifx->generated = 1;
3866 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3867 emitpcode(POC_ADDLW, popGetLit(0x80));
3868 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
3869 rFalseIfx.condition ^= 1;
3870 genSkipc(&rFalseIfx);
3872 rFalseIfx.condition ^= 1;
3873 genSkipCond(&rFalseIfx,right,0,7);
3878 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3879 emitpcode(POC_SUBFW, popGet(AOP(right),0));
3880 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3881 rFalseIfx.condition ^= 1;
3882 genSkipc(&rFalseIfx);
3884 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3885 genSkipz2(&rFalseIfx);
3889 if(ifx) ifx->generated = 1;
3894 /* Size is greater than 1 */
3904 /* this means lit = 0xffffffff, or -1 */
3907 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
3908 rFalseIfx.condition ^= 1;
3909 genSkipCond(&rFalseIfx,right,size,7);
3910 if(ifx) ifx->generated = 1;
3917 if(rFalseIfx.condition) {
3918 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3919 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3922 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3924 emitpcode(POC_IORFW, popGet(AOP(right),size));
3928 if(rFalseIfx.condition) {
3929 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3930 emitpLabel(truelbl->key);
3932 rFalseIfx.condition ^= 1;
3933 genSkipCond(&rFalseIfx,right,s,7);
3936 if(ifx) ifx->generated = 1;
3941 if(lit & (0x80 << (size*8))) {
3942 /* Lit is less than zero */
3943 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
3944 //rFalseIfx.condition ^= 1;
3945 //genSkipCond(&rFalseIfx,left,size,7);
3946 //rFalseIfx.condition ^= 1;
3947 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3948 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3950 if(rFalseIfx.condition)
3951 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3953 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3957 /* Lit is greater than or equal to zero */
3958 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
3959 //rFalseIfx.condition ^= 1;
3960 //genSkipCond(&rFalseIfx,right,size,7);
3961 //rFalseIfx.condition ^= 1;
3963 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3964 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3966 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3967 if(rFalseIfx.condition)
3968 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3970 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3973 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3974 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3978 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
3980 emitpcode(POC_SUBFW, popGet(AOP(right),size));
3982 rFalseIfx.condition ^= 1;
3983 //rFalseIfx.condition = 1;
3984 genSkipc(&rFalseIfx);
3986 emitpLabel(truelbl->key);
3988 if(ifx) ifx->generated = 1;
3992 /* Unsigned compare for sizes greater than 1 */
3995 i = (lit >> (size*8)) & 0xff;
3999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4000 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4001 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4003 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4006 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4007 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4014 emitpLabel(lbl->key);
4016 rFalseIfx.condition ^= 1;
4017 genSkipc(&rFalseIfx);
4021 emitpLabel(truelbl->key);
4022 if(ifx) ifx->generated = 1;
4026 /* Compare two variables */
4028 DEBUGpic14_emitcode(";sign","%d",sign);
4032 /* Sigh. thus sucks... */
4034 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4035 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4036 emitpcode(POC_MOVLW, popGetLit(0x80));
4037 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4038 emitpcode(POC_XORFW, popGet(AOP(right),size));
4039 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4041 /* Signed char comparison */
4042 /* Special thanks to Nikolai Golovchenko for this snippet */
4043 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4044 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4045 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4046 emitpcode(POC_XORFW, popGet(AOP(left),0));
4047 emitpcode(POC_XORFW, popGet(AOP(right),0));
4048 emitpcode(POC_ADDLW, popGetLit(0x80));
4050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4051 genSkipc(&rFalseIfx);
4053 if(ifx) ifx->generated = 1;
4059 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4060 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4064 /* The rest of the bytes of a multi-byte compare */
4068 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4071 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4072 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4077 emitpLabel(lbl->key);
4079 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4080 genSkipc(&rFalseIfx);
4081 if(ifx) ifx->generated = 1;
4088 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4089 pic14_outBitC(result);
4091 /* if the result is used in the next
4092 ifx conditional branch then generate
4093 code a little differently */
4095 genIfxJump (ifx,"c");
4097 pic14_outBitC(result);
4098 /* leave the result in acc */
4103 /*-----------------------------------------------------------------*/
4104 /* genCmpGt :- greater than comparison */
4105 /*-----------------------------------------------------------------*/
4106 static void genCmpGt (iCode *ic, iCode *ifx)
4108 operand *left, *right, *result;
4109 sym_link *letype , *retype;
4112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4114 right= IC_RIGHT(ic);
4115 result = IC_RESULT(ic);
4117 letype = getSpec(operandType(left));
4118 retype =getSpec(operandType(right));
4119 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4120 /* assign the amsops */
4121 aopOp (left,ic,FALSE);
4122 aopOp (right,ic,FALSE);
4123 aopOp (result,ic,TRUE);
4125 genCmp(right, left, result, ifx, sign);
4127 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4128 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4129 freeAsmop(result,NULL,ic,TRUE);
4132 /*-----------------------------------------------------------------*/
4133 /* genCmpLt - less than comparisons */
4134 /*-----------------------------------------------------------------*/
4135 static void genCmpLt (iCode *ic, iCode *ifx)
4137 operand *left, *right, *result;
4138 sym_link *letype , *retype;
4141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4143 right= IC_RIGHT(ic);
4144 result = IC_RESULT(ic);
4146 letype = getSpec(operandType(left));
4147 retype =getSpec(operandType(right));
4148 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4150 /* assign the amsops */
4151 aopOp (left,ic,FALSE);
4152 aopOp (right,ic,FALSE);
4153 aopOp (result,ic,TRUE);
4155 genCmp(left, right, result, ifx, sign);
4157 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4158 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4159 freeAsmop(result,NULL,ic,TRUE);
4162 /*-----------------------------------------------------------------*/
4163 /* genc16bit2lit - compare a 16 bit value to a literal */
4164 /*-----------------------------------------------------------------*/
4165 static void genc16bit2lit(operand *op, int lit, int offset)
4169 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4170 if( (lit&0xff) == 0)
4175 switch( BYTEofLONG(lit,i)) {
4177 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4180 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4183 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4186 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4187 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4192 switch( BYTEofLONG(lit,i)) {
4194 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4198 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4202 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4205 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4207 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4213 /*-----------------------------------------------------------------*/
4214 /* gencjneshort - compare and jump if not equal */
4215 /*-----------------------------------------------------------------*/
4216 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4218 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4223 unsigned long lit = 0L;
4224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4225 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4227 resolveIfx(&rIfx,ifx);
4228 lbl = newiTempLabel(NULL);
4231 /* if the left side is a literal or
4232 if the right is in a pointer register and left
4234 if ((AOP_TYPE(left) == AOP_LIT) ||
4235 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4240 if(AOP_TYPE(right) == AOP_LIT)
4241 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4243 /* if the right side is a literal then anything goes */
4244 if (AOP_TYPE(right) == AOP_LIT &&
4245 AOP_TYPE(left) != AOP_DIR ) {
4248 genc16bit2lit(left, lit, 0);
4250 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4255 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4256 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4258 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4262 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4270 /* if the right side is in a register or in direct space or
4271 if the left is a pointer register & right is not */
4272 else if (AOP_TYPE(right) == AOP_REG ||
4273 AOP_TYPE(right) == AOP_DIR ||
4274 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4275 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4278 genc16bit2lit(left, lit, 0);
4280 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4285 if((AOP_TYPE(left) == AOP_DIR) &&
4286 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4288 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4289 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4291 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4293 switch (lit & 0xff) {
4295 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4298 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4299 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4303 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4304 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4308 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4309 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4314 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4317 if(AOP_TYPE(result) == AOP_CRY) {
4318 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4323 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4325 /* fix me. probably need to check result size too */
4326 emitpcode(POC_CLRF,popGet(AOP(result),0));
4331 emitpcode(POC_INCF,popGet(AOP(result),0));
4341 } else if(AOP_TYPE(right) == AOP_REG &&
4342 AOP_TYPE(left) != AOP_DIR){
4345 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4346 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4347 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4352 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4357 /* right is a pointer reg need both a & b */
4359 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4361 pic14_emitcode("mov","b,%s",l);
4362 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4363 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4367 emitpLabel(lbl->key);
4374 /*-----------------------------------------------------------------*/
4375 /* gencjne - compare and jump if not equal */
4376 /*-----------------------------------------------------------------*/
4377 static void gencjne(operand *left, operand *right, iCode *ifx)
4379 symbol *tlbl = newiTempLabel(NULL);
4381 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4382 gencjneshort(left, right, lbl);
4384 pic14_emitcode("mov","a,%s",one);
4385 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4386 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4387 pic14_emitcode("clr","a");
4388 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4390 emitpLabel(lbl->key);
4391 emitpLabel(tlbl->key);
4396 /*-----------------------------------------------------------------*/
4397 /* genCmpEq - generates code for equal to */
4398 /*-----------------------------------------------------------------*/
4399 static void genCmpEq (iCode *ic, iCode *ifx)
4401 operand *left, *right, *result;
4402 unsigned long lit = 0L;
4405 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4408 DEBUGpic14_emitcode ("; ifx is non-null","");
4410 DEBUGpic14_emitcode ("; ifx is null","");
4412 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4413 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4414 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4416 size = max(AOP_SIZE(left),AOP_SIZE(right));
4418 DEBUGpic14_AopType(__LINE__,left,right,result);
4420 /* if literal, literal on the right or
4421 if the right is in a pointer register and left
4423 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4424 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4425 operand *tmp = right ;
4431 if(ifx && !AOP_SIZE(result)){
4433 /* if they are both bit variables */
4434 if (AOP_TYPE(left) == AOP_CRY &&
4435 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4436 if(AOP_TYPE(right) == AOP_LIT){
4437 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4439 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4440 pic14_emitcode("cpl","c");
4441 } else if(lit == 1L) {
4442 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4444 pic14_emitcode("clr","c");
4446 /* AOP_TYPE(right) == AOP_CRY */
4448 symbol *lbl = newiTempLabel(NULL);
4449 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4450 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4451 pic14_emitcode("cpl","c");
4452 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4454 /* if true label then we jump if condition
4456 tlbl = newiTempLabel(NULL);
4457 if ( IC_TRUE(ifx) ) {
4458 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4459 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4461 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4462 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4464 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4467 /* left and right are both bit variables, result is carry */
4470 resolveIfx(&rIfx,ifx);
4472 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4473 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4474 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4475 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4480 /* They're not both bit variables. Is the right a literal? */
4481 if(AOP_TYPE(right) == AOP_LIT) {
4482 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4487 switch(lit & 0xff) {
4489 if ( IC_TRUE(ifx) ) {
4490 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4492 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4494 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4495 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4499 if ( IC_TRUE(ifx) ) {
4500 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4502 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4504 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4505 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4509 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4511 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4516 /* end of size == 1 */
4520 genc16bit2lit(left,lit,offset);
4523 /* end of size == 2 */
4528 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4529 emitpcode(POC_IORFW,popGet(AOP(left),1));
4530 emitpcode(POC_IORFW,popGet(AOP(left),2));
4531 emitpcode(POC_IORFW,popGet(AOP(left),3));
4535 /* search for patterns that can be optimized */
4537 genc16bit2lit(left,lit,0);
4540 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4542 genc16bit2lit(left,lit,2);
4544 emitpcode(POC_IORFW,popGet(AOP(left),2));
4545 emitpcode(POC_IORFW,popGet(AOP(left),3));
4558 } else if(AOP_TYPE(right) == AOP_CRY ) {
4559 /* we know the left is not a bit, but that the right is */
4560 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4561 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4562 popGet(AOP(right),offset));
4563 emitpcode(POC_XORLW,popGetLit(1));
4565 /* if the two are equal, then W will be 0 and the Z bit is set
4566 * we could test Z now, or go ahead and check the high order bytes if
4567 * the variable we're comparing is larger than a byte. */
4570 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4572 if ( IC_TRUE(ifx) ) {
4574 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4575 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4578 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4579 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4583 /* They're both variables that are larger than bits */
4586 tlbl = newiTempLabel(NULL);
4589 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4590 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4592 if ( IC_TRUE(ifx) ) {
4595 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4596 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4599 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4600 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4604 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4605 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4609 if(s>1 && IC_TRUE(ifx)) {
4610 emitpLabel(tlbl->key);
4611 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4615 /* mark the icode as generated */
4620 /* if they are both bit variables */
4621 if (AOP_TYPE(left) == AOP_CRY &&
4622 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4623 if(AOP_TYPE(right) == AOP_LIT){
4624 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4626 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4627 pic14_emitcode("cpl","c");
4628 } else if(lit == 1L) {
4629 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4631 pic14_emitcode("clr","c");
4633 /* AOP_TYPE(right) == AOP_CRY */
4635 symbol *lbl = newiTempLabel(NULL);
4636 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4637 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4638 pic14_emitcode("cpl","c");
4639 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4642 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4643 pic14_outBitC(result);
4647 genIfxJump (ifx,"c");
4650 /* if the result is used in an arithmetic operation
4651 then put the result in place */
4652 pic14_outBitC(result);
4655 gencjne(left,right,result,ifx);
4658 gencjne(left,right,newiTempLabel(NULL));
4660 if(IC_TRUE(ifx)->key)
4661 gencjne(left,right,IC_TRUE(ifx)->key);
4663 gencjne(left,right,IC_FALSE(ifx)->key);
4667 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4668 aopPut(AOP(result),"a",0);
4673 genIfxJump (ifx,"a");
4677 /* if the result is used in an arithmetic operation
4678 then put the result in place */
4680 if (AOP_TYPE(result) != AOP_CRY)
4681 pic14_outAcc(result);
4683 /* leave the result in acc */
4687 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4688 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4689 freeAsmop(result,NULL,ic,TRUE);
4692 /*-----------------------------------------------------------------*/
4693 /* ifxForOp - returns the icode containing the ifx for operand */
4694 /*-----------------------------------------------------------------*/
4695 static iCode *ifxForOp ( operand *op, iCode *ic )
4697 /* if true symbol then needs to be assigned */
4698 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4699 if (IS_TRUE_SYMOP(op))
4702 /* if this has register type condition and
4703 the next instruction is ifx with the same operand
4704 and live to of the operand is upto the ifx only then */
4706 ic->next->op == IFX &&
4707 IC_COND(ic->next)->key == op->key &&
4708 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4712 ic->next->op == IFX &&
4713 IC_COND(ic->next)->key == op->key) {
4714 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4718 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4720 ic->next->op == IFX)
4721 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4724 ic->next->op == IFX &&
4725 IC_COND(ic->next)->key == op->key) {
4726 DEBUGpic14_emitcode ("; "," key is okay");
4727 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4728 OP_SYMBOL(op)->liveTo,
4735 /*-----------------------------------------------------------------*/
4736 /* genAndOp - for && operation */
4737 /*-----------------------------------------------------------------*/
4738 static void genAndOp (iCode *ic)
4740 operand *left,*right, *result;
4743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4744 /* note here that && operations that are in an
4745 if statement are taken away by backPatchLabels
4746 only those used in arthmetic operations remain */
4747 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4748 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4749 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4751 /* if both are bit variables */
4752 if (AOP_TYPE(left) == AOP_CRY &&
4753 AOP_TYPE(right) == AOP_CRY ) {
4754 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4755 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4756 pic14_outBitC(result);
4758 tlbl = newiTempLabel(NULL);
4759 pic14_toBoolean(left);
4760 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4761 pic14_toBoolean(right);
4762 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4763 pic14_outBitAcc(result);
4766 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4767 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4768 freeAsmop(result,NULL,ic,TRUE);
4772 /*-----------------------------------------------------------------*/
4773 /* genOrOp - for || operation */
4774 /*-----------------------------------------------------------------*/
4777 modified this code, but it doesn't appear to ever get called
4780 static void genOrOp (iCode *ic)
4782 operand *left,*right, *result;
4785 /* note here that || operations that are in an
4786 if statement are taken away by backPatchLabels
4787 only those used in arthmetic operations remain */
4788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4789 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4790 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4791 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4793 DEBUGpic14_AopType(__LINE__,left,right,result);
4795 /* if both are bit variables */
4796 if (AOP_TYPE(left) == AOP_CRY &&
4797 AOP_TYPE(right) == AOP_CRY ) {
4798 pic14_emitcode("clrc","");
4799 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4800 AOP(left)->aopu.aop_dir,
4801 AOP(left)->aopu.aop_dir);
4802 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4803 AOP(right)->aopu.aop_dir,
4804 AOP(right)->aopu.aop_dir);
4805 pic14_emitcode("setc","");
4808 tlbl = newiTempLabel(NULL);
4809 pic14_toBoolean(left);
4811 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4812 pic14_toBoolean(right);
4813 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4815 pic14_outBitAcc(result);
4818 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4819 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4820 freeAsmop(result,NULL,ic,TRUE);
4823 /*-----------------------------------------------------------------*/
4824 /* isLiteralBit - test if lit == 2^n */
4825 /*-----------------------------------------------------------------*/
4826 static int isLiteralBit(unsigned long lit)
4828 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4829 0x100L,0x200L,0x400L,0x800L,
4830 0x1000L,0x2000L,0x4000L,0x8000L,
4831 0x10000L,0x20000L,0x40000L,0x80000L,
4832 0x100000L,0x200000L,0x400000L,0x800000L,
4833 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4834 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4838 for(idx = 0; idx < 32; idx++)
4844 /*-----------------------------------------------------------------*/
4845 /* continueIfTrue - */
4846 /*-----------------------------------------------------------------*/
4847 static void continueIfTrue (iCode *ic)
4849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4851 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4855 /*-----------------------------------------------------------------*/
4857 /*-----------------------------------------------------------------*/
4858 static void jumpIfTrue (iCode *ic)
4860 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4862 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4866 /*-----------------------------------------------------------------*/
4867 /* jmpTrueOrFalse - */
4868 /*-----------------------------------------------------------------*/
4869 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4871 // ugly but optimized by peephole
4872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4874 symbol *nlbl = newiTempLabel(NULL);
4875 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
4876 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4877 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4878 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4881 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4882 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4887 /*-----------------------------------------------------------------*/
4888 /* genAnd - code for and */
4889 /*-----------------------------------------------------------------*/
4890 static void genAnd (iCode *ic, iCode *ifx)
4892 operand *left, *right, *result;
4894 unsigned long lit = 0L;
4899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4900 aopOp((left = IC_LEFT(ic)),ic,FALSE);
4901 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4902 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4904 resolveIfx(&rIfx,ifx);
4906 /* if left is a literal & right is not then exchange them */
4907 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4908 AOP_NEEDSACC(left)) {
4909 operand *tmp = right ;
4914 /* if result = right then exchange them */
4915 if(pic14_sameRegs(AOP(result),AOP(right))){
4916 operand *tmp = right ;
4921 /* if right is bit then exchange them */
4922 if (AOP_TYPE(right) == AOP_CRY &&
4923 AOP_TYPE(left) != AOP_CRY){
4924 operand *tmp = right ;
4928 if(AOP_TYPE(right) == AOP_LIT)
4929 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4931 size = AOP_SIZE(result);
4933 DEBUGpic14_AopType(__LINE__,left,right,result);
4936 // result = bit & yy;
4937 if (AOP_TYPE(left) == AOP_CRY){
4938 // c = bit & literal;
4939 if(AOP_TYPE(right) == AOP_LIT){
4941 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4944 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4947 if(size && (AOP_TYPE(result) == AOP_CRY)){
4948 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4951 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4955 pic14_emitcode("clr","c");
4958 if (AOP_TYPE(right) == AOP_CRY){
4960 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4961 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4964 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4966 pic14_emitcode("rrc","a");
4967 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4973 pic14_outBitC(result);
4975 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4976 genIfxJump(ifx, "c");
4980 // if(val & 0xZZ) - size = 0, ifx != FALSE -
4981 // bit = val & 0xZZ - size = 1, ifx = FALSE -
4982 if((AOP_TYPE(right) == AOP_LIT) &&
4983 (AOP_TYPE(result) == AOP_CRY) &&
4984 (AOP_TYPE(left) != AOP_CRY)){
4985 int posbit = isLiteralBit(lit);
4989 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4992 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4998 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4999 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5001 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5002 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5005 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5006 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5007 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5014 symbol *tlbl = newiTempLabel(NULL);
5015 int sizel = AOP_SIZE(left);
5017 pic14_emitcode("setb","c");
5019 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5020 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5022 if((posbit = isLiteralBit(bytelit)) != 0)
5023 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5025 if(bytelit != 0x0FFL)
5026 pic14_emitcode("anl","a,%s",
5027 aopGet(AOP(right),offset,FALSE,TRUE));
5028 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5033 // bit = left & literal
5035 pic14_emitcode("clr","c");
5036 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5038 // if(left & literal)
5041 jmpTrueOrFalse(ifx, tlbl);
5045 pic14_outBitC(result);
5049 /* if left is same as result */
5050 if(pic14_sameRegs(AOP(result),AOP(left))){
5052 for(;size--; offset++,lit>>=8) {
5053 if(AOP_TYPE(right) == AOP_LIT){
5054 switch(lit & 0xff) {
5056 /* and'ing with 0 has clears the result */
5057 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5058 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5061 /* and'ing with 0xff is a nop when the result and left are the same */
5066 int p = my_powof2( (~lit) & 0xff );
5068 /* only one bit is set in the literal, so use a bcf instruction */
5069 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5070 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5073 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5074 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5075 if(know_W != (lit&0xff))
5076 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5078 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5083 if (AOP_TYPE(left) == AOP_ACC) {
5084 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5086 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5087 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5094 // left & result in different registers
5095 if(AOP_TYPE(result) == AOP_CRY){
5097 // if(size), result in bit
5098 // if(!size && ifx), conditional oper: if(left & right)
5099 symbol *tlbl = newiTempLabel(NULL);
5100 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5102 pic14_emitcode("setb","c");
5104 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5105 pic14_emitcode("anl","a,%s",
5106 aopGet(AOP(left),offset,FALSE,FALSE));
5107 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5112 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5113 pic14_outBitC(result);
5115 jmpTrueOrFalse(ifx, tlbl);
5117 for(;(size--);offset++) {
5119 // result = left & right
5120 if(AOP_TYPE(right) == AOP_LIT){
5121 int t = (lit >> (offset*8)) & 0x0FFL;
5124 pic14_emitcode("clrf","%s",
5125 aopGet(AOP(result),offset,FALSE,FALSE));
5126 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5129 pic14_emitcode("movf","%s,w",
5130 aopGet(AOP(left),offset,FALSE,FALSE));
5131 pic14_emitcode("movwf","%s",
5132 aopGet(AOP(result),offset,FALSE,FALSE));
5133 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5134 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5137 pic14_emitcode("movlw","0x%x",t);
5138 pic14_emitcode("andwf","%s,w",
5139 aopGet(AOP(left),offset,FALSE,FALSE));
5140 pic14_emitcode("movwf","%s",
5141 aopGet(AOP(result),offset,FALSE,FALSE));
5143 emitpcode(POC_MOVLW, popGetLit(t));
5144 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5145 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5150 if (AOP_TYPE(left) == AOP_ACC) {
5151 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5152 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5154 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5155 pic14_emitcode("andwf","%s,w",
5156 aopGet(AOP(left),offset,FALSE,FALSE));
5157 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5158 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5160 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5161 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5167 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5168 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5169 freeAsmop(result,NULL,ic,TRUE);
5172 /*-----------------------------------------------------------------*/
5173 /* genOr - code for or */
5174 /*-----------------------------------------------------------------*/
5175 static void genOr (iCode *ic, iCode *ifx)
5177 operand *left, *right, *result;
5179 unsigned long lit = 0L;
5181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5183 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5184 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5185 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5187 DEBUGpic14_AopType(__LINE__,left,right,result);
5189 /* if left is a literal & right is not then exchange them */
5190 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5191 AOP_NEEDSACC(left)) {
5192 operand *tmp = right ;
5197 /* if result = right then exchange them */
5198 if(pic14_sameRegs(AOP(result),AOP(right))){
5199 operand *tmp = right ;
5204 /* if right is bit then exchange them */
5205 if (AOP_TYPE(right) == AOP_CRY &&
5206 AOP_TYPE(left) != AOP_CRY){
5207 operand *tmp = right ;
5212 DEBUGpic14_AopType(__LINE__,left,right,result);
5214 if(AOP_TYPE(right) == AOP_LIT)
5215 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5217 size = AOP_SIZE(result);
5221 if (AOP_TYPE(left) == AOP_CRY){
5222 if(AOP_TYPE(right) == AOP_LIT){
5223 // c = bit & literal;
5225 // lit != 0 => result = 1
5226 if(AOP_TYPE(result) == AOP_CRY){
5228 emitpcode(POC_BSF, popGet(AOP(result),0));
5229 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5230 // AOP(result)->aopu.aop_dir,
5231 // AOP(result)->aopu.aop_dir);
5233 continueIfTrue(ifx);
5237 // lit == 0 => result = left
5238 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5240 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5243 if (AOP_TYPE(right) == AOP_CRY){
5244 if(pic14_sameRegs(AOP(result),AOP(left))){
5246 emitpcode(POC_BCF, popGet(AOP(result),0));
5247 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5248 emitpcode(POC_BSF, popGet(AOP(result),0));
5250 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5251 AOP(result)->aopu.aop_dir,
5252 AOP(result)->aopu.aop_dir);
5253 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5254 AOP(right)->aopu.aop_dir,
5255 AOP(right)->aopu.aop_dir);
5256 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5257 AOP(result)->aopu.aop_dir,
5258 AOP(result)->aopu.aop_dir);
5260 if( AOP_TYPE(result) == AOP_ACC) {
5261 emitpcode(POC_MOVLW, popGetLit(0));
5262 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5263 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5264 emitpcode(POC_MOVLW, popGetLit(1));
5268 emitpcode(POC_BCF, popGet(AOP(result),0));
5269 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5270 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5271 emitpcode(POC_BSF, popGet(AOP(result),0));
5273 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5274 AOP(result)->aopu.aop_dir,
5275 AOP(result)->aopu.aop_dir);
5276 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5277 AOP(right)->aopu.aop_dir,
5278 AOP(right)->aopu.aop_dir);
5279 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5280 AOP(left)->aopu.aop_dir,
5281 AOP(left)->aopu.aop_dir);
5282 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5283 AOP(result)->aopu.aop_dir,
5284 AOP(result)->aopu.aop_dir);
5289 symbol *tlbl = newiTempLabel(NULL);
5290 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5293 emitpcode(POC_BCF, popGet(AOP(result),0));
5294 if( AOP_TYPE(right) == AOP_ACC) {
5295 emitpcode(POC_IORLW, popGetLit(0));
5297 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5298 emitpcode(POC_BSF, popGet(AOP(result),0));
5303 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5304 pic14_emitcode(";XXX setb","c");
5305 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5306 AOP(left)->aopu.aop_dir,tlbl->key+100);
5307 pic14_toBoolean(right);
5308 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5309 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5310 jmpTrueOrFalse(ifx, tlbl);
5314 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5321 pic14_outBitC(result);
5323 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5324 genIfxJump(ifx, "c");
5328 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5329 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5330 if((AOP_TYPE(right) == AOP_LIT) &&
5331 (AOP_TYPE(result) == AOP_CRY) &&
5332 (AOP_TYPE(left) != AOP_CRY)){
5334 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5337 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5339 continueIfTrue(ifx);
5342 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5343 // lit = 0, result = boolean(left)
5345 pic14_emitcode(";XXX setb","c");
5346 pic14_toBoolean(right);
5348 symbol *tlbl = newiTempLabel(NULL);
5349 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5351 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5353 genIfxJump (ifx,"a");
5357 pic14_outBitC(result);
5361 /* if left is same as result */
5362 if(pic14_sameRegs(AOP(result),AOP(left))){
5364 for(;size--; offset++,lit>>=8) {
5365 if(AOP_TYPE(right) == AOP_LIT){
5366 if((lit & 0xff) == 0)
5367 /* or'ing with 0 has no effect */
5370 int p = my_powof2(lit & 0xff);
5372 /* only one bit is set in the literal, so use a bsf instruction */
5374 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5376 if(know_W != (lit & 0xff))
5377 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5378 know_W = lit & 0xff;
5379 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5384 if (AOP_TYPE(left) == AOP_ACC) {
5385 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5386 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5388 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5389 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5391 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5392 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5398 // left & result in different registers
5399 if(AOP_TYPE(result) == AOP_CRY){
5401 // if(size), result in bit
5402 // if(!size && ifx), conditional oper: if(left | right)
5403 symbol *tlbl = newiTempLabel(NULL);
5404 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5405 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5409 pic14_emitcode(";XXX setb","c");
5411 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5412 pic14_emitcode(";XXX orl","a,%s",
5413 aopGet(AOP(left),offset,FALSE,FALSE));
5414 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5419 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5420 pic14_outBitC(result);
5422 jmpTrueOrFalse(ifx, tlbl);
5423 } else for(;(size--);offset++){
5425 // result = left & right
5426 if(AOP_TYPE(right) == AOP_LIT){
5427 int t = (lit >> (offset*8)) & 0x0FFL;
5430 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5431 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5433 pic14_emitcode("movf","%s,w",
5434 aopGet(AOP(left),offset,FALSE,FALSE));
5435 pic14_emitcode("movwf","%s",
5436 aopGet(AOP(result),offset,FALSE,FALSE));
5439 emitpcode(POC_MOVLW, popGetLit(t));
5440 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5441 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5443 pic14_emitcode("movlw","0x%x",t);
5444 pic14_emitcode("iorwf","%s,w",
5445 aopGet(AOP(left),offset,FALSE,FALSE));
5446 pic14_emitcode("movwf","%s",
5447 aopGet(AOP(result),offset,FALSE,FALSE));
5453 // faster than result <- left, anl result,right
5454 // and better if result is SFR
5455 if (AOP_TYPE(left) == AOP_ACC) {
5456 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5457 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5459 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5460 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5462 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5463 pic14_emitcode("iorwf","%s,w",
5464 aopGet(AOP(left),offset,FALSE,FALSE));
5466 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5467 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5472 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5473 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5474 freeAsmop(result,NULL,ic,TRUE);
5477 /*-----------------------------------------------------------------*/
5478 /* genXor - code for xclusive or */
5479 /*-----------------------------------------------------------------*/
5480 static void genXor (iCode *ic, iCode *ifx)
5482 operand *left, *right, *result;
5484 unsigned long lit = 0L;
5486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5488 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5489 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5490 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5492 /* if left is a literal & right is not ||
5493 if left needs acc & right does not */
5494 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5495 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5496 operand *tmp = right ;
5501 /* if result = right then exchange them */
5502 if(pic14_sameRegs(AOP(result),AOP(right))){
5503 operand *tmp = right ;
5508 /* if right is bit then exchange them */
5509 if (AOP_TYPE(right) == AOP_CRY &&
5510 AOP_TYPE(left) != AOP_CRY){
5511 operand *tmp = right ;
5515 if(AOP_TYPE(right) == AOP_LIT)
5516 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5518 size = AOP_SIZE(result);
5522 if (AOP_TYPE(left) == AOP_CRY){
5523 if(AOP_TYPE(right) == AOP_LIT){
5524 // c = bit & literal;
5526 // lit>>1 != 0 => result = 1
5527 if(AOP_TYPE(result) == AOP_CRY){
5529 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5530 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5532 continueIfTrue(ifx);
5535 pic14_emitcode("setb","c");
5539 // lit == 0, result = left
5540 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5542 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5544 // lit == 1, result = not(left)
5545 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5546 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5547 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5548 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5551 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5552 pic14_emitcode("cpl","c");
5559 symbol *tlbl = newiTempLabel(NULL);
5560 if (AOP_TYPE(right) == AOP_CRY){
5562 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5565 int sizer = AOP_SIZE(right);
5567 // if val>>1 != 0, result = 1
5568 pic14_emitcode("setb","c");
5570 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5572 // test the msb of the lsb
5573 pic14_emitcode("anl","a,#0xfe");
5574 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5578 pic14_emitcode("rrc","a");
5580 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5581 pic14_emitcode("cpl","c");
5582 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5587 pic14_outBitC(result);
5589 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5590 genIfxJump(ifx, "c");
5594 if(pic14_sameRegs(AOP(result),AOP(left))){
5595 /* if left is same as result */
5596 for(;size--; offset++) {
5597 if(AOP_TYPE(right) == AOP_LIT){
5598 int t = (lit >> (offset*8)) & 0x0FFL;
5602 if (IS_AOP_PREG(left)) {
5603 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5604 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5605 aopPut(AOP(result),"a",offset);
5607 emitpcode(POC_MOVLW, popGetLit(t));
5608 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5609 pic14_emitcode("xrl","%s,%s",
5610 aopGet(AOP(left),offset,FALSE,TRUE),
5611 aopGet(AOP(right),offset,FALSE,FALSE));
5614 if (AOP_TYPE(left) == AOP_ACC)
5615 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5617 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5618 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5620 if (IS_AOP_PREG(left)) {
5621 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5622 aopPut(AOP(result),"a",offset);
5624 pic14_emitcode("xrl","%s,a",
5625 aopGet(AOP(left),offset,FALSE,TRUE));
5631 // left & result in different registers
5632 if(AOP_TYPE(result) == AOP_CRY){
5634 // if(size), result in bit
5635 // if(!size && ifx), conditional oper: if(left ^ right)
5636 symbol *tlbl = newiTempLabel(NULL);
5637 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5639 pic14_emitcode("setb","c");
5641 if((AOP_TYPE(right) == AOP_LIT) &&
5642 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5643 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5645 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5646 pic14_emitcode("xrl","a,%s",
5647 aopGet(AOP(left),offset,FALSE,FALSE));
5649 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5654 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5655 pic14_outBitC(result);
5657 jmpTrueOrFalse(ifx, tlbl);
5658 } else for(;(size--);offset++){
5660 // result = left & right
5661 if(AOP_TYPE(right) == AOP_LIT){
5662 int t = (lit >> (offset*8)) & 0x0FFL;
5665 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5666 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5667 pic14_emitcode("movf","%s,w",
5668 aopGet(AOP(left),offset,FALSE,FALSE));
5669 pic14_emitcode("movwf","%s",
5670 aopGet(AOP(result),offset,FALSE,FALSE));
5673 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5674 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5675 pic14_emitcode("comf","%s,w",
5676 aopGet(AOP(left),offset,FALSE,FALSE));
5677 pic14_emitcode("movwf","%s",
5678 aopGet(AOP(result),offset,FALSE,FALSE));
5681 emitpcode(POC_MOVLW, popGetLit(t));
5682 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5683 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5684 pic14_emitcode("movlw","0x%x",t);
5685 pic14_emitcode("xorwf","%s,w",
5686 aopGet(AOP(left),offset,FALSE,FALSE));
5687 pic14_emitcode("movwf","%s",
5688 aopGet(AOP(result),offset,FALSE,FALSE));
5694 // faster than result <- left, anl result,right
5695 // and better if result is SFR
5696 if (AOP_TYPE(left) == AOP_ACC) {
5697 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5698 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5700 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5701 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5702 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5703 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5705 if ( AOP_TYPE(result) != AOP_ACC){
5706 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5707 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5713 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5714 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5715 freeAsmop(result,NULL,ic,TRUE);
5718 /*-----------------------------------------------------------------*/
5719 /* genInline - write the inline code out */
5720 /*-----------------------------------------------------------------*/
5721 static void genInline (iCode *ic)
5723 char *buffer, *bp, *bp1;
5725 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5727 _G.inLine += (!options.asmpeep);
5729 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5730 strcpy(buffer,IC_INLINE(ic));
5732 /* emit each line as a code */
5736 pic14_emitcode(bp1,"");
5743 pic14_emitcode(bp1,"");
5750 pic14_emitcode(bp1,"");
5751 /* pic14_emitcode("",buffer); */
5752 _G.inLine -= (!options.asmpeep);
5755 /*-----------------------------------------------------------------*/
5756 /* genRRC - rotate right with carry */
5757 /*-----------------------------------------------------------------*/
5758 static void genRRC (iCode *ic)
5760 operand *left , *result ;
5761 int size, offset = 0, same;
5763 /* rotate right with carry */
5765 result=IC_RESULT(ic);
5766 aopOp (left,ic,FALSE);
5767 aopOp (result,ic,FALSE);
5769 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5771 same = pic14_sameRegs(AOP(result),AOP(left));
5773 size = AOP_SIZE(result);
5775 /* get the lsb and put it into the carry */
5776 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5783 emitpcode(POC_RRF, popGet(AOP(left),offset));
5785 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5786 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5792 freeAsmop(left,NULL,ic,TRUE);
5793 freeAsmop(result,NULL,ic,TRUE);
5796 /*-----------------------------------------------------------------*/
5797 /* genRLC - generate code for rotate left with carry */
5798 /*-----------------------------------------------------------------*/
5799 static void genRLC (iCode *ic)
5801 operand *left , *result ;
5802 int size, offset = 0;
5805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5806 /* rotate right with carry */
5808 result=IC_RESULT(ic);
5809 aopOp (left,ic,FALSE);
5810 aopOp (result,ic,FALSE);
5812 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5814 same = pic14_sameRegs(AOP(result),AOP(left));
5816 /* move it to the result */
5817 size = AOP_SIZE(result);
5819 /* get the msb and put it into the carry */
5820 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5827 emitpcode(POC_RLF, popGet(AOP(left),offset));
5829 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5830 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5837 freeAsmop(left,NULL,ic,TRUE);
5838 freeAsmop(result,NULL,ic,TRUE);
5841 /*-----------------------------------------------------------------*/
5842 /* genGetHbit - generates code get highest order bit */
5843 /*-----------------------------------------------------------------*/
5844 static void genGetHbit (iCode *ic)
5846 operand *left, *result;
5848 result=IC_RESULT(ic);
5849 aopOp (left,ic,FALSE);
5850 aopOp (result,ic,FALSE);
5852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5853 /* get the highest order byte into a */
5854 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5855 if(AOP_TYPE(result) == AOP_CRY){
5856 pic14_emitcode("rlc","a");
5857 pic14_outBitC(result);
5860 pic14_emitcode("rl","a");
5861 pic14_emitcode("anl","a,#0x01");
5862 pic14_outAcc(result);
5866 freeAsmop(left,NULL,ic,TRUE);
5867 freeAsmop(result,NULL,ic,TRUE);
5870 /*-----------------------------------------------------------------*/
5871 /* AccRol - rotate left accumulator by known count */
5872 /*-----------------------------------------------------------------*/
5873 static void AccRol (int shCount)
5875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5876 shCount &= 0x0007; // shCount : 0..7
5881 pic14_emitcode("rl","a");
5884 pic14_emitcode("rl","a");
5885 pic14_emitcode("rl","a");
5888 pic14_emitcode("swap","a");
5889 pic14_emitcode("rr","a");
5892 pic14_emitcode("swap","a");
5895 pic14_emitcode("swap","a");
5896 pic14_emitcode("rl","a");
5899 pic14_emitcode("rr","a");
5900 pic14_emitcode("rr","a");
5903 pic14_emitcode("rr","a");
5908 /*-----------------------------------------------------------------*/
5909 /* AccLsh - left shift accumulator by known count */
5910 /*-----------------------------------------------------------------*/
5911 static void AccLsh (int shCount)
5913 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5916 pic14_emitcode("add","a,acc");
5919 pic14_emitcode("add","a,acc");
5920 pic14_emitcode("add","a,acc");
5922 /* rotate left accumulator */
5924 /* and kill the lower order bits */
5925 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5930 /*-----------------------------------------------------------------*/
5931 /* AccRsh - right shift accumulator by known count */
5932 /*-----------------------------------------------------------------*/
5933 static void AccRsh (int shCount)
5935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5939 pic14_emitcode("rrc","a");
5941 /* rotate right accumulator */
5942 AccRol(8 - shCount);
5943 /* and kill the higher order bits */
5944 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5950 /*-----------------------------------------------------------------*/
5951 /* AccSRsh - signed right shift accumulator by known count */
5952 /*-----------------------------------------------------------------*/
5953 static void AccSRsh (int shCount)
5956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5959 pic14_emitcode("mov","c,acc.7");
5960 pic14_emitcode("rrc","a");
5961 } else if(shCount == 2){
5962 pic14_emitcode("mov","c,acc.7");
5963 pic14_emitcode("rrc","a");
5964 pic14_emitcode("mov","c,acc.7");
5965 pic14_emitcode("rrc","a");
5967 tlbl = newiTempLabel(NULL);
5968 /* rotate right accumulator */
5969 AccRol(8 - shCount);
5970 /* and kill the higher order bits */
5971 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5972 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5973 pic14_emitcode("orl","a,#0x%02x",
5974 (unsigned char)~SRMask[shCount]);
5975 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5980 /*-----------------------------------------------------------------*/
5981 /* shiftR1Left2Result - shift right one byte from left to result */
5982 /*-----------------------------------------------------------------*/
5983 static void shiftR1Left2ResultSigned (operand *left, int offl,
5984 operand *result, int offr,
5989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5991 same = (left == result) || (AOP(left) == AOP(result));
5995 emitpcode(POC_RLFW, popGet(AOP(left),offl));
5997 emitpcode(POC_RRF, popGet(AOP(result),offr));
5999 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6000 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6010 /*-----------------------------------------------------------------*/
6011 /* shiftR1Left2Result - shift right one byte from left to result */
6012 /*-----------------------------------------------------------------*/
6013 static void shiftR1Left2Result (operand *left, int offl,
6014 operand *result, int offr,
6015 int shCount, int sign)
6019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6021 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6023 /* Copy the msb into the carry if signed. */
6025 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6035 emitpcode(POC_RRF, popGet(AOP(result),offr));
6037 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6038 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6044 emitpcode(POC_RRF, popGet(AOP(result),offr));
6046 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6047 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6050 emitpcode(POC_RRF, popGet(AOP(result),offr));
6055 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6057 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6058 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6061 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6062 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6063 emitpcode(POC_ANDLW, popGetLit(0x1f));
6064 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6068 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6069 emitpcode(POC_ANDLW, popGetLit(0x0f));
6070 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6074 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6075 emitpcode(POC_ANDLW, popGetLit(0x0f));
6076 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6078 emitpcode(POC_RRF, popGet(AOP(result),offr));
6083 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6084 emitpcode(POC_ANDLW, popGetLit(0x80));
6085 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6086 emitpcode(POC_RLF, popGet(AOP(result),offr));
6087 emitpcode(POC_RLF, popGet(AOP(result),offr));
6092 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6093 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6094 emitpcode(POC_RLF, popGet(AOP(result),offr));
6105 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6107 /* shift right accumulator */
6112 aopPut(AOP(result),"a",offr);
6116 /*-----------------------------------------------------------------*/
6117 /* shiftL1Left2Result - shift left one byte from left to result */
6118 /*-----------------------------------------------------------------*/
6119 static void shiftL1Left2Result (operand *left, int offl,
6120 operand *result, int offr, int shCount)
6125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6127 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6128 DEBUGpic14_emitcode ("; ***","same = %d",same);
6129 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6131 /* shift left accumulator */
6132 //AccLsh(shCount); // don't comment out just yet...
6133 // aopPut(AOP(result),"a",offr);
6137 /* Shift left 1 bit position */
6138 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6140 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6142 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6143 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6147 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6148 emitpcode(POC_ANDLW,popGetLit(0x7e));
6149 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6150 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6153 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6154 emitpcode(POC_ANDLW,popGetLit(0x3e));
6155 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6156 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6157 emitpcode(POC_RLF, popGet(AOP(result),offr));
6160 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6161 emitpcode(POC_ANDLW, popGetLit(0xf0));
6162 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6165 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6166 emitpcode(POC_ANDLW, popGetLit(0xf0));
6167 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6168 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6171 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6172 emitpcode(POC_ANDLW, popGetLit(0x30));
6173 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6174 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6175 emitpcode(POC_RLF, popGet(AOP(result),offr));
6178 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6179 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6180 emitpcode(POC_RRF, popGet(AOP(result),offr));
6184 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6189 /*-----------------------------------------------------------------*/
6190 /* movLeft2Result - move byte from left to result */
6191 /*-----------------------------------------------------------------*/
6192 static void movLeft2Result (operand *left, int offl,
6193 operand *result, int offr, int sign)
6196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6198 l = aopGet(AOP(left),offl,FALSE,FALSE);
6200 if (*l == '@' && (IS_AOP_PREG(result))) {
6201 pic14_emitcode("mov","a,%s",l);
6202 aopPut(AOP(result),"a",offr);
6205 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6206 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6208 //aopPut(AOP(result),l,offr);
6210 /* MSB sign in acc.7 ! */
6211 if(pic14_getDataSize(left) == offl+1){
6212 pic14_emitcode("mov","a,%s",l);
6213 aopPut(AOP(result),"a",offr);
6220 /*-----------------------------------------------------------------*/
6221 /* shiftL2Left2Result - shift left two bytes from left to result */
6222 /*-----------------------------------------------------------------*/
6223 static void shiftL2Left2Result (operand *left, int offl,
6224 operand *result, int offr, int shCount)
6228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6230 if(pic14_sameRegs(AOP(result), AOP(left))) {
6238 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6239 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6240 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6244 emitpcode(POC_RLF, popGet(AOP(result),offr));
6245 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6251 emitpcode(POC_MOVLW, popGetLit(0x0f));
6252 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6253 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6254 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6255 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6256 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6257 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6259 emitpcode(POC_RLF, popGet(AOP(result),offr));
6260 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6264 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6265 emitpcode(POC_RRF, popGet(AOP(result),offr));
6266 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6267 emitpcode(POC_RRF, popGet(AOP(result),offr));
6268 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6269 emitpcode(POC_ANDLW,popGetLit(0xc0));
6270 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6271 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6272 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6273 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6276 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6277 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6278 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6279 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6280 emitpcode(POC_RRF, popGet(AOP(result),offr));
6290 /* note, use a mov/add for the shift since the mov has a
6291 chance of getting optimized out */
6292 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6293 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6294 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6295 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6296 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6300 emitpcode(POC_RLF, popGet(AOP(result),offr));
6301 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6307 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6308 emitpcode(POC_ANDLW, popGetLit(0xF0));
6309 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6310 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6311 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6312 emitpcode(POC_ANDLW, popGetLit(0xF0));
6313 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6314 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6318 emitpcode(POC_RLF, popGet(AOP(result),offr));
6319 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6323 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6324 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6325 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6326 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6328 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6329 emitpcode(POC_RRF, popGet(AOP(result),offr));
6330 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6331 emitpcode(POC_ANDLW,popGetLit(0xc0));
6332 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6333 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6334 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6335 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6338 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6339 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6340 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6341 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6342 emitpcode(POC_RRF, popGet(AOP(result),offr));
6347 /*-----------------------------------------------------------------*/
6348 /* shiftR2Left2Result - shift right two bytes from left to result */
6349 /*-----------------------------------------------------------------*/
6350 static void shiftR2Left2Result (operand *left, int offl,
6351 operand *result, int offr,
6352 int shCount, int sign)
6356 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6357 same = pic14_sameRegs(AOP(result), AOP(left));
6359 if(same && ((offl + MSB16) == offr)){
6361 /* don't crash result[offr] */
6362 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6363 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6365 movLeft2Result(left,offl, result, offr, 0);
6366 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6368 /* a:x >> shCount (x = lsb(result))*/
6371 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6373 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6383 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6384 emitpcode(POC_RRF,popGet(AOP(result),offr));
6387 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6388 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6389 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6390 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6395 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6396 emitpcode(POC_RRF,popGet(AOP(result),offr));
6403 emitpcode(POC_MOVLW, popGetLit(0xf0));
6404 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6405 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6407 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6408 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6409 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6410 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6412 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6413 emitpcode(POC_ANDLW, popGetLit(0x0f));
6414 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6417 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6418 emitpcode(POC_ANDLW, popGetLit(0xf0));
6419 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6420 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6424 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6425 emitpcode(POC_RRF, popGet(AOP(result),offr));
6433 emitpcode(POC_RLF, popGet(AOP(result),offr));
6434 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6436 emitpcode(POC_RLF, popGet(AOP(result),offr));
6437 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6438 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6439 emitpcode(POC_ANDLW,popGetLit(0x03));
6440 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6441 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6442 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6443 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6445 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6446 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6447 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6448 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6449 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6450 emitpcode(POC_RLF, popGet(AOP(result),offr));
6451 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6452 emitpcode(POC_ANDLW,popGetLit(0x03));
6453 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6458 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6459 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6460 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6461 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6462 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6467 /*-----------------------------------------------------------------*/
6468 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6469 /*-----------------------------------------------------------------*/
6470 static void shiftLLeftOrResult (operand *left, int offl,
6471 operand *result, int offr, int shCount)
6473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6474 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6475 /* shift left accumulator */
6477 /* or with result */
6478 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6479 /* back to result */
6480 aopPut(AOP(result),"a",offr);
6483 /*-----------------------------------------------------------------*/
6484 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6485 /*-----------------------------------------------------------------*/
6486 static void shiftRLeftOrResult (operand *left, int offl,
6487 operand *result, int offr, int shCount)
6489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6490 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6491 /* shift right accumulator */
6493 /* or with result */
6494 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6495 /* back to result */
6496 aopPut(AOP(result),"a",offr);
6499 /*-----------------------------------------------------------------*/
6500 /* genlshOne - left shift a one byte quantity by known count */
6501 /*-----------------------------------------------------------------*/
6502 static void genlshOne (operand *result, operand *left, int shCount)
6504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6505 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6508 /*-----------------------------------------------------------------*/
6509 /* genlshTwo - left shift two bytes by known amount != 0 */
6510 /*-----------------------------------------------------------------*/
6511 static void genlshTwo (operand *result,operand *left, int shCount)
6515 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6516 size = pic14_getDataSize(result);
6518 /* if shCount >= 8 */
6524 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6526 movLeft2Result(left, LSB, result, MSB16, 0);
6528 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6531 /* 1 <= shCount <= 7 */
6534 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6536 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6540 /*-----------------------------------------------------------------*/
6541 /* shiftLLong - shift left one long from left to result */
6542 /* offl = LSB or MSB16 */
6543 /*-----------------------------------------------------------------*/
6544 static void shiftLLong (operand *left, operand *result, int offr )
6547 int size = AOP_SIZE(result);
6549 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6550 if(size >= LSB+offr){
6551 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6553 pic14_emitcode("add","a,acc");
6554 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6555 size >= MSB16+offr && offr != LSB )
6556 pic14_emitcode("xch","a,%s",
6557 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6559 aopPut(AOP(result),"a",LSB+offr);
6562 if(size >= MSB16+offr){
6563 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6564 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6567 pic14_emitcode("rlc","a");
6568 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6569 size >= MSB24+offr && offr != LSB)
6570 pic14_emitcode("xch","a,%s",
6571 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6573 aopPut(AOP(result),"a",MSB16+offr);
6576 if(size >= MSB24+offr){
6577 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6578 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6581 pic14_emitcode("rlc","a");
6582 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6583 size >= MSB32+offr && offr != LSB )
6584 pic14_emitcode("xch","a,%s",
6585 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6587 aopPut(AOP(result),"a",MSB24+offr);
6590 if(size > MSB32+offr){
6591 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6592 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6595 pic14_emitcode("rlc","a");
6596 aopPut(AOP(result),"a",MSB32+offr);
6599 aopPut(AOP(result),zero,LSB);
6602 /*-----------------------------------------------------------------*/
6603 /* genlshFour - shift four byte by a known amount != 0 */
6604 /*-----------------------------------------------------------------*/
6605 static void genlshFour (operand *result, operand *left, int shCount)
6609 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6610 size = AOP_SIZE(result);
6612 /* if shifting more that 3 bytes */
6613 if (shCount >= 24 ) {
6616 /* lowest order of left goes to the highest
6617 order of the destination */
6618 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6620 movLeft2Result(left, LSB, result, MSB32, 0);
6621 aopPut(AOP(result),zero,LSB);
6622 aopPut(AOP(result),zero,MSB16);
6623 aopPut(AOP(result),zero,MSB32);
6627 /* more than two bytes */
6628 else if ( shCount >= 16 ) {
6629 /* lower order two bytes goes to higher order two bytes */
6631 /* if some more remaining */
6633 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6635 movLeft2Result(left, MSB16, result, MSB32, 0);
6636 movLeft2Result(left, LSB, result, MSB24, 0);
6638 aopPut(AOP(result),zero,MSB16);
6639 aopPut(AOP(result),zero,LSB);
6643 /* if more than 1 byte */
6644 else if ( shCount >= 8 ) {
6645 /* lower order three bytes goes to higher order three bytes */
6649 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6651 movLeft2Result(left, LSB, result, MSB16, 0);
6653 else{ /* size = 4 */
6655 movLeft2Result(left, MSB24, result, MSB32, 0);
6656 movLeft2Result(left, MSB16, result, MSB24, 0);
6657 movLeft2Result(left, LSB, result, MSB16, 0);
6658 aopPut(AOP(result),zero,LSB);
6660 else if(shCount == 1)
6661 shiftLLong(left, result, MSB16);
6663 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6664 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6665 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6666 aopPut(AOP(result),zero,LSB);
6671 /* 1 <= shCount <= 7 */
6672 else if(shCount <= 2){
6673 shiftLLong(left, result, LSB);
6675 shiftLLong(result, result, LSB);
6677 /* 3 <= shCount <= 7, optimize */
6679 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6680 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6681 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6685 /*-----------------------------------------------------------------*/
6686 /* genLeftShiftLiteral - left shifting by known count */
6687 /*-----------------------------------------------------------------*/
6688 static void genLeftShiftLiteral (operand *left,
6693 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6696 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6697 freeAsmop(right,NULL,ic,TRUE);
6699 aopOp(left,ic,FALSE);
6700 aopOp(result,ic,FALSE);
6702 size = getSize(operandType(result));
6705 pic14_emitcode("; shift left ","result %d, left %d",size,
6709 /* I suppose that the left size >= result size */
6712 movLeft2Result(left, size, result, size, 0);
6716 else if(shCount >= (size * 8))
6718 aopPut(AOP(result),zero,size);
6722 genlshOne (result,left,shCount);
6727 genlshTwo (result,left,shCount);
6731 genlshFour (result,left,shCount);
6735 freeAsmop(left,NULL,ic,TRUE);
6736 freeAsmop(result,NULL,ic,TRUE);
6739 /*-----------------------------------------------------------------*
6740 * genMultiAsm - repeat assembly instruction for size of register.
6741 * if endian == 1, then the high byte (i.e base address + size of
6742 * register) is used first else the low byte is used first;
6743 *-----------------------------------------------------------------*/
6744 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6749 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6762 emitpcode(poc, popGet(AOP(reg),offset));
6767 /*-----------------------------------------------------------------*/
6768 /* genLeftShift - generates code for left shifting */
6769 /*-----------------------------------------------------------------*/
6770 static void genLeftShift (iCode *ic)
6772 operand *left,*right, *result;
6775 symbol *tlbl , *tlbl1;
6777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6779 right = IC_RIGHT(ic);
6781 result = IC_RESULT(ic);
6783 aopOp(right,ic,FALSE);
6785 /* if the shift count is known then do it
6786 as efficiently as possible */
6787 if (AOP_TYPE(right) == AOP_LIT) {
6788 genLeftShiftLiteral (left,right,result,ic);
6792 /* shift count is unknown then we have to form
6793 a loop get the loop count in B : Note: we take
6794 only the lower order byte since shifting
6795 more that 32 bits make no sense anyway, ( the
6796 largest size of an object can be only 32 bits ) */
6799 aopOp(left,ic,FALSE);
6800 aopOp(result,ic,FALSE);
6802 /* now move the left to the result if they are not the
6804 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6805 AOP_SIZE(result) > 1) {
6807 size = AOP_SIZE(result);
6810 l = aopGet(AOP(left),offset,FALSE,TRUE);
6811 if (*l == '@' && (IS_AOP_PREG(result))) {
6813 pic14_emitcode("mov","a,%s",l);
6814 aopPut(AOP(result),"a",offset);
6816 aopPut(AOP(result),l,offset);
6821 size = AOP_SIZE(result);
6823 /* if it is only one byte then */
6825 if(optimized_for_speed) {
6826 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6827 emitpcode(POC_ANDLW, popGetLit(0xf0));
6828 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6829 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6830 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6831 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6832 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6833 emitpcode(POC_RLFW, popGet(AOP(result),0));
6834 emitpcode(POC_ANDLW, popGetLit(0xfe));
6835 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6836 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6837 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6840 tlbl = newiTempLabel(NULL);
6841 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6842 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6843 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6846 emitpcode(POC_COMFW, popGet(AOP(right),0));
6847 emitpcode(POC_RRF, popGet(AOP(result),0));
6848 emitpLabel(tlbl->key);
6849 emitpcode(POC_RLF, popGet(AOP(result),0));
6850 emitpcode(POC_ADDLW, popGetLit(1));
6852 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6857 if (pic14_sameRegs(AOP(left),AOP(result))) {
6859 tlbl = newiTempLabel(NULL);
6860 emitpcode(POC_COMFW, popGet(AOP(right),0));
6861 genMultiAsm(POC_RRF, result, size,1);
6862 emitpLabel(tlbl->key);
6863 genMultiAsm(POC_RLF, result, size,0);
6864 emitpcode(POC_ADDLW, popGetLit(1));
6866 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6870 tlbl = newiTempLabel(NULL);
6872 tlbl1 = newiTempLabel(NULL);
6874 reAdjustPreg(AOP(result));
6876 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6877 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6878 l = aopGet(AOP(result),offset,FALSE,FALSE);
6880 pic14_emitcode("add","a,acc");
6881 aopPut(AOP(result),"a",offset++);
6883 l = aopGet(AOP(result),offset,FALSE,FALSE);
6885 pic14_emitcode("rlc","a");
6886 aopPut(AOP(result),"a",offset++);
6888 reAdjustPreg(AOP(result));
6890 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6891 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6893 freeAsmop (right,NULL,ic,TRUE);
6894 freeAsmop(left,NULL,ic,TRUE);
6895 freeAsmop(result,NULL,ic,TRUE);
6898 /*-----------------------------------------------------------------*/
6899 /* genrshOne - right shift a one byte quantity by known count */
6900 /*-----------------------------------------------------------------*/
6901 static void genrshOne (operand *result, operand *left,
6902 int shCount, int sign)
6904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6905 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6908 /*-----------------------------------------------------------------*/
6909 /* genrshTwo - right shift two bytes by known amount != 0 */
6910 /*-----------------------------------------------------------------*/
6911 static void genrshTwo (operand *result,operand *left,
6912 int shCount, int sign)
6914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6915 /* if shCount >= 8 */
6919 shiftR1Left2Result(left, MSB16, result, LSB,
6922 movLeft2Result(left, MSB16, result, LSB, sign);
6924 addSign(result, MSB16, sign);
6926 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
6930 /* 1 <= shCount <= 7 */
6932 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
6935 /*-----------------------------------------------------------------*/
6936 /* shiftRLong - shift right one long from left to result */
6937 /* offl = LSB or MSB16 */
6938 /*-----------------------------------------------------------------*/
6939 static void shiftRLong (operand *left, int offl,
6940 operand *result, int sign)
6942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6944 pic14_emitcode("clr","c");
6945 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6947 pic14_emitcode("mov","c,acc.7");
6948 pic14_emitcode("rrc","a");
6949 aopPut(AOP(result),"a",MSB32-offl);
6951 /* add sign of "a" */
6952 addSign(result, MSB32, sign);
6954 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6955 pic14_emitcode("rrc","a");
6956 aopPut(AOP(result),"a",MSB24-offl);
6958 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6959 pic14_emitcode("rrc","a");
6960 aopPut(AOP(result),"a",MSB16-offl);
6963 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6964 pic14_emitcode("rrc","a");
6965 aopPut(AOP(result),"a",LSB);
6969 /*-----------------------------------------------------------------*/
6970 /* genrshFour - shift four byte by a known amount != 0 */
6971 /*-----------------------------------------------------------------*/
6972 static void genrshFour (operand *result, operand *left,
6973 int shCount, int sign)
6975 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6976 /* if shifting more that 3 bytes */
6977 if(shCount >= 24 ) {
6980 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6982 movLeft2Result(left, MSB32, result, LSB, sign);
6983 addSign(result, MSB16, sign);
6985 else if(shCount >= 16){
6988 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6990 movLeft2Result(left, MSB24, result, LSB, 0);
6991 movLeft2Result(left, MSB32, result, MSB16, sign);
6993 addSign(result, MSB24, sign);
6995 else if(shCount >= 8){
6998 shiftRLong(left, MSB16, result, sign);
6999 else if(shCount == 0){
7000 movLeft2Result(left, MSB16, result, LSB, 0);
7001 movLeft2Result(left, MSB24, result, MSB16, 0);
7002 movLeft2Result(left, MSB32, result, MSB24, sign);
7003 addSign(result, MSB32, sign);
7006 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7007 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7008 /* the last shift is signed */
7009 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7010 addSign(result, MSB32, sign);
7013 else{ /* 1 <= shCount <= 7 */
7015 shiftRLong(left, LSB, result, sign);
7017 shiftRLong(result, LSB, result, sign);
7020 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7021 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7022 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7027 /*-----------------------------------------------------------------*/
7028 /* genRightShiftLiteral - right shifting by known count */
7029 /*-----------------------------------------------------------------*/
7030 static void genRightShiftLiteral (operand *left,
7036 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7040 freeAsmop(right,NULL,ic,TRUE);
7042 aopOp(left,ic,FALSE);
7043 aopOp(result,ic,FALSE);
7046 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7050 size = pic14_getDataSize(left);
7051 /* test the LEFT size !!! */
7053 /* I suppose that the left size >= result size */
7055 size = pic14_getDataSize(result);
7057 movLeft2Result(left, size, result, size, 0);
7060 else if(shCount >= (size * 8)){
7062 /* get sign in acc.7 */
7063 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7064 addSign(result, LSB, sign);
7068 genrshOne (result,left,shCount,sign);
7072 genrshTwo (result,left,shCount,sign);
7076 genrshFour (result,left,shCount,sign);
7082 freeAsmop(left,NULL,ic,TRUE);
7083 freeAsmop(result,NULL,ic,TRUE);
7087 /*-----------------------------------------------------------------*/
7088 /* genSignedRightShift - right shift of signed number */
7089 /*-----------------------------------------------------------------*/
7090 static void genSignedRightShift (iCode *ic)
7092 operand *right, *left, *result;
7095 symbol *tlbl, *tlbl1 ;
7097 /* we do it the hard way put the shift count in b
7098 and loop thru preserving the sign */
7099 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7101 right = IC_RIGHT(ic);
7103 result = IC_RESULT(ic);
7105 aopOp(right,ic,FALSE);
7108 if ( AOP_TYPE(right) == AOP_LIT) {
7109 genRightShiftLiteral (left,right,result,ic,1);
7112 /* shift count is unknown then we have to form
7113 a loop get the loop count in B : Note: we take
7114 only the lower order byte since shifting
7115 more that 32 bits make no sense anyway, ( the
7116 largest size of an object can be only 32 bits ) */
7118 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7119 pic14_emitcode("inc","b");
7120 freeAsmop (right,NULL,ic,TRUE);
7121 aopOp(left,ic,FALSE);
7122 aopOp(result,ic,FALSE);
7124 /* now move the left to the result if they are not the
7126 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7127 AOP_SIZE(result) > 1) {
7129 size = AOP_SIZE(result);
7132 l = aopGet(AOP(left),offset,FALSE,TRUE);
7133 if (*l == '@' && IS_AOP_PREG(result)) {
7135 pic14_emitcode("mov","a,%s",l);
7136 aopPut(AOP(result),"a",offset);
7138 aopPut(AOP(result),l,offset);
7143 /* mov the highest order bit to OVR */
7144 tlbl = newiTempLabel(NULL);
7145 tlbl1= newiTempLabel(NULL);
7147 size = AOP_SIZE(result);
7149 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7150 pic14_emitcode("rlc","a");
7151 pic14_emitcode("mov","ov,c");
7152 /* if it is only one byte then */
7154 l = aopGet(AOP(left),0,FALSE,FALSE);
7156 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7157 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7158 pic14_emitcode("mov","c,ov");
7159 pic14_emitcode("rrc","a");
7160 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7161 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7162 aopPut(AOP(result),"a",0);
7166 reAdjustPreg(AOP(result));
7167 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7168 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7169 pic14_emitcode("mov","c,ov");
7171 l = aopGet(AOP(result),offset,FALSE,FALSE);
7173 pic14_emitcode("rrc","a");
7174 aopPut(AOP(result),"a",offset--);
7176 reAdjustPreg(AOP(result));
7177 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7178 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7181 freeAsmop(left,NULL,ic,TRUE);
7182 freeAsmop(result,NULL,ic,TRUE);
7185 /*-----------------------------------------------------------------*/
7186 /* genRightShift - generate code for right shifting */
7187 /*-----------------------------------------------------------------*/
7188 static void genRightShift (iCode *ic)
7190 operand *right, *left, *result;
7194 symbol *tlbl, *tlbl1 ;
7196 /* if signed then we do it the hard way preserve the
7197 sign bit moving it inwards */
7198 retype = getSpec(operandType(IC_RESULT(ic)));
7199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7201 if (!SPEC_USIGN(retype)) {
7202 genSignedRightShift (ic);
7206 /* signed & unsigned types are treated the same : i.e. the
7207 signed is NOT propagated inwards : quoting from the
7208 ANSI - standard : "for E1 >> E2, is equivalent to division
7209 by 2**E2 if unsigned or if it has a non-negative value,
7210 otherwise the result is implementation defined ", MY definition
7211 is that the sign does not get propagated */
7213 right = IC_RIGHT(ic);
7215 result = IC_RESULT(ic);
7217 aopOp(right,ic,FALSE);
7219 /* if the shift count is known then do it
7220 as efficiently as possible */
7221 if (AOP_TYPE(right) == AOP_LIT) {
7222 genRightShiftLiteral (left,right,result,ic, 0);
7226 /* shift count is unknown then we have to form
7227 a loop get the loop count in B : Note: we take
7228 only the lower order byte since shifting
7229 more that 32 bits make no sense anyway, ( the
7230 largest size of an object can be only 32 bits ) */
7232 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7233 pic14_emitcode("inc","b");
7234 aopOp(left,ic,FALSE);
7235 aopOp(result,ic,FALSE);
7237 /* now move the left to the result if they are not the
7239 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7240 AOP_SIZE(result) > 1) {
7242 size = AOP_SIZE(result);
7245 l = aopGet(AOP(left),offset,FALSE,TRUE);
7246 if (*l == '@' && IS_AOP_PREG(result)) {
7248 pic14_emitcode("mov","a,%s",l);
7249 aopPut(AOP(result),"a",offset);
7251 aopPut(AOP(result),l,offset);
7256 tlbl = newiTempLabel(NULL);
7257 tlbl1= newiTempLabel(NULL);
7258 size = AOP_SIZE(result);
7261 /* if it is only one byte then */
7264 l = aopGet(AOP(left),0,FALSE,FALSE);
7266 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7267 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7269 pic14_emitcode("rrc","a");
7270 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7271 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7272 aopPut(AOP(result),"a",0);
7274 tlbl = newiTempLabel(NULL);
7275 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7276 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7277 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7280 emitpcode(POC_COMFW, popGet(AOP(right),0));
7281 emitpcode(POC_RLF, popGet(AOP(result),0));
7282 emitpLabel(tlbl->key);
7283 emitpcode(POC_RRF, popGet(AOP(result),0));
7284 emitpcode(POC_ADDLW, popGetLit(1));
7286 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7291 reAdjustPreg(AOP(result));
7292 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7293 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7296 l = aopGet(AOP(result),offset,FALSE,FALSE);
7298 pic14_emitcode("rrc","a");
7299 aopPut(AOP(result),"a",offset--);
7301 reAdjustPreg(AOP(result));
7303 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7304 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7307 freeAsmop(left,NULL,ic,TRUE);
7308 freeAsmop (right,NULL,ic,TRUE);
7309 freeAsmop(result,NULL,ic,TRUE);
7312 /*-----------------------------------------------------------------*/
7313 /* genUnpackBits - generates code for unpacking bits */
7314 /*-----------------------------------------------------------------*/
7315 static void genUnpackBits (operand *result, char *rname, int ptype)
7322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7323 etype = getSpec(operandType(result));
7325 /* read the first byte */
7330 pic14_emitcode("mov","a,@%s",rname);
7334 pic14_emitcode("movx","a,@%s",rname);
7338 pic14_emitcode("movx","a,@dptr");
7342 pic14_emitcode("clr","a");
7343 pic14_emitcode("movc","a","@a+dptr");
7347 pic14_emitcode("lcall","__gptrget");
7351 /* if we have bitdisplacement then it fits */
7352 /* into this byte completely or if length is */
7353 /* less than a byte */
7354 if ((shCnt = SPEC_BSTR(etype)) ||
7355 (SPEC_BLEN(etype) <= 8)) {
7357 /* shift right acc */
7360 pic14_emitcode("anl","a,#0x%02x",
7361 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7362 aopPut(AOP(result),"a",offset);
7366 /* bit field did not fit in a byte */
7367 rlen = SPEC_BLEN(etype) - 8;
7368 aopPut(AOP(result),"a",offset++);
7375 pic14_emitcode("inc","%s",rname);
7376 pic14_emitcode("mov","a,@%s",rname);
7380 pic14_emitcode("inc","%s",rname);
7381 pic14_emitcode("movx","a,@%s",rname);
7385 pic14_emitcode("inc","dptr");
7386 pic14_emitcode("movx","a,@dptr");
7390 pic14_emitcode("clr","a");
7391 pic14_emitcode("inc","dptr");
7392 pic14_emitcode("movc","a","@a+dptr");
7396 pic14_emitcode("inc","dptr");
7397 pic14_emitcode("lcall","__gptrget");
7402 /* if we are done */
7406 aopPut(AOP(result),"a",offset++);
7411 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7412 aopPut(AOP(result),"a",offset);
7419 /*-----------------------------------------------------------------*/
7420 /* genDataPointerGet - generates code when ptr offset is known */
7421 /*-----------------------------------------------------------------*/
7422 static void genDataPointerGet (operand *left,
7426 int size , offset = 0;
7429 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7432 /* optimization - most of the time, left and result are the same
7433 * address, but different types. for the pic code, we could omit
7437 aopOp(result,ic,TRUE);
7439 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7441 size = AOP_SIZE(result);
7444 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7448 freeAsmop(left,NULL,ic,TRUE);
7449 freeAsmop(result,NULL,ic,TRUE);
7452 /*-----------------------------------------------------------------*/
7453 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7454 /*-----------------------------------------------------------------*/
7455 static void genNearPointerGet (operand *left,
7462 sym_link *rtype, *retype;
7463 sym_link *ltype = operandType(left);
7466 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7468 rtype = operandType(result);
7469 retype= getSpec(rtype);
7471 aopOp(left,ic,FALSE);
7473 /* if left is rematerialisable and
7474 result is not bit variable type and
7475 the left is pointer to data space i.e
7476 lower 128 bytes of space */
7477 if (AOP_TYPE(left) == AOP_IMMD &&
7478 !IS_BITVAR(retype) &&
7479 DCL_TYPE(ltype) == POINTER) {
7480 genDataPointerGet (left,result,ic);
7484 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7486 /* if the value is already in a pointer register
7487 then don't need anything more */
7488 if (!AOP_INPREG(AOP(left))) {
7489 /* otherwise get a free pointer register */
7490 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7492 preg = getFreePtr(ic,&aop,FALSE);
7493 pic14_emitcode("mov","%s,%s",
7495 aopGet(AOP(left),0,FALSE,TRUE));
7496 rname = preg->name ;
7498 rname = aopGet(AOP(left),0,FALSE,FALSE);
7500 freeAsmop(left,NULL,ic,TRUE);
7501 aopOp (result,ic,FALSE);
7503 /* if bitfield then unpack the bits */
7504 if (IS_BITVAR(retype))
7505 genUnpackBits (result,rname,POINTER);
7507 /* we have can just get the values */
7508 int size = AOP_SIZE(result);
7511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7513 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7515 pic14_emitcode("mov","a,@%s",rname);
7516 aopPut(AOP(result),"a",offset);
7518 sprintf(buffer,"@%s",rname);
7519 aopPut(AOP(result),buffer,offset);
7523 pic14_emitcode("inc","%s",rname);
7527 /* now some housekeeping stuff */
7529 /* we had to allocate for this iCode */
7530 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7531 freeAsmop(NULL,aop,ic,TRUE);
7533 /* we did not allocate which means left
7534 already in a pointer register, then
7535 if size > 0 && this could be used again
7536 we have to point it back to where it
7538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7539 if (AOP_SIZE(result) > 1 &&
7540 !OP_SYMBOL(left)->remat &&
7541 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7543 int size = AOP_SIZE(result) - 1;
7545 pic14_emitcode("dec","%s",rname);
7550 freeAsmop(result,NULL,ic,TRUE);
7554 /*-----------------------------------------------------------------*/
7555 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7556 /*-----------------------------------------------------------------*/
7557 static void genPagedPointerGet (operand *left,
7564 sym_link *rtype, *retype;
7566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7568 rtype = operandType(result);
7569 retype= getSpec(rtype);
7571 aopOp(left,ic,FALSE);
7573 /* if the value is already in a pointer register
7574 then don't need anything more */
7575 if (!AOP_INPREG(AOP(left))) {
7576 /* otherwise get a free pointer register */
7578 preg = getFreePtr(ic,&aop,FALSE);
7579 pic14_emitcode("mov","%s,%s",
7581 aopGet(AOP(left),0,FALSE,TRUE));
7582 rname = preg->name ;
7584 rname = aopGet(AOP(left),0,FALSE,FALSE);
7586 freeAsmop(left,NULL,ic,TRUE);
7587 aopOp (result,ic,FALSE);
7589 /* if bitfield then unpack the bits */
7590 if (IS_BITVAR(retype))
7591 genUnpackBits (result,rname,PPOINTER);
7593 /* we have can just get the values */
7594 int size = AOP_SIZE(result);
7599 pic14_emitcode("movx","a,@%s",rname);
7600 aopPut(AOP(result),"a",offset);
7605 pic14_emitcode("inc","%s",rname);
7609 /* now some housekeeping stuff */
7611 /* we had to allocate for this iCode */
7612 freeAsmop(NULL,aop,ic,TRUE);
7614 /* we did not allocate which means left
7615 already in a pointer register, then
7616 if size > 0 && this could be used again
7617 we have to point it back to where it
7619 if (AOP_SIZE(result) > 1 &&
7620 !OP_SYMBOL(left)->remat &&
7621 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7623 int size = AOP_SIZE(result) - 1;
7625 pic14_emitcode("dec","%s",rname);
7630 freeAsmop(result,NULL,ic,TRUE);
7635 /*-----------------------------------------------------------------*/
7636 /* genFarPointerGet - gget value from far space */
7637 /*-----------------------------------------------------------------*/
7638 static void genFarPointerGet (operand *left,
7639 operand *result, iCode *ic)
7642 sym_link *retype = getSpec(operandType(result));
7644 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7646 aopOp(left,ic,FALSE);
7648 /* if the operand is already in dptr
7649 then we do nothing else we move the value to dptr */
7650 if (AOP_TYPE(left) != AOP_STR) {
7651 /* if this is remateriazable */
7652 if (AOP_TYPE(left) == AOP_IMMD)
7653 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7654 else { /* we need to get it byte by byte */
7655 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7656 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7657 if (options.model == MODEL_FLAT24)
7659 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7663 /* so dptr know contains the address */
7664 freeAsmop(left,NULL,ic,TRUE);
7665 aopOp(result,ic,FALSE);
7667 /* if bit then unpack */
7668 if (IS_BITVAR(retype))
7669 genUnpackBits(result,"dptr",FPOINTER);
7671 size = AOP_SIZE(result);
7675 pic14_emitcode("movx","a,@dptr");
7676 aopPut(AOP(result),"a",offset++);
7678 pic14_emitcode("inc","dptr");
7682 freeAsmop(result,NULL,ic,TRUE);
7685 /*-----------------------------------------------------------------*/
7686 /* genCodePointerGet - get value from code space */
7687 /*-----------------------------------------------------------------*/
7688 static void genCodePointerGet (operand *left,
7689 operand *result, iCode *ic)
7692 sym_link *retype = getSpec(operandType(result));
7694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7696 aopOp(left,ic,FALSE);
7698 /* if the operand is already in dptr
7699 then we do nothing else we move the value to dptr */
7700 if (AOP_TYPE(left) != AOP_STR) {
7701 /* if this is remateriazable */
7702 if (AOP_TYPE(left) == AOP_IMMD)
7703 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7704 else { /* we need to get it byte by byte */
7705 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7706 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7707 if (options.model == MODEL_FLAT24)
7709 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7713 /* so dptr know contains the address */
7714 freeAsmop(left,NULL,ic,TRUE);
7715 aopOp(result,ic,FALSE);
7717 /* if bit then unpack */
7718 if (IS_BITVAR(retype))
7719 genUnpackBits(result,"dptr",CPOINTER);
7721 size = AOP_SIZE(result);
7725 pic14_emitcode("clr","a");
7726 pic14_emitcode("movc","a,@a+dptr");
7727 aopPut(AOP(result),"a",offset++);
7729 pic14_emitcode("inc","dptr");
7733 freeAsmop(result,NULL,ic,TRUE);
7736 /*-----------------------------------------------------------------*/
7737 /* genGenPointerGet - gget value from generic pointer space */
7738 /*-----------------------------------------------------------------*/
7739 static void genGenPointerGet (operand *left,
7740 operand *result, iCode *ic)
7743 sym_link *retype = getSpec(operandType(result));
7745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7746 aopOp(left,ic,FALSE);
7747 aopOp(result,ic,FALSE);
7750 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7752 /* if the operand is already in dptr
7753 then we do nothing else we move the value to dptr */
7754 // if (AOP_TYPE(left) != AOP_STR) {
7755 /* if this is remateriazable */
7756 if (AOP_TYPE(left) == AOP_IMMD) {
7757 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7758 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7760 else { /* we need to get it byte by byte */
7762 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7763 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7765 size = AOP_SIZE(result);
7769 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7770 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7772 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7777 /* so dptr know contains the address */
7779 /* if bit then unpack */
7780 //if (IS_BITVAR(retype))
7781 // genUnpackBits(result,"dptr",GPOINTER);
7784 freeAsmop(left,NULL,ic,TRUE);
7785 freeAsmop(result,NULL,ic,TRUE);
7789 /*-----------------------------------------------------------------*/
7790 /* genConstPointerGet - get value from const generic pointer space */
7791 /*-----------------------------------------------------------------*/
7792 static void genConstPointerGet (operand *left,
7793 operand *result, iCode *ic)
7795 sym_link *retype = getSpec(operandType(result));
7796 symbol *albl = newiTempLabel(NULL);
7797 symbol *blbl = newiTempLabel(NULL);
7800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7801 aopOp(left,ic,FALSE);
7802 aopOp(result,ic,FALSE);
7805 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7807 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
7809 emitpcode(POC_CALL,popGetLabel(albl->key));
7810 emitpcode(POC_GOTO,popGetLabel(blbl->key));
7811 emitpLabel(albl->key);
7813 poc = ( (AOP_TYPE(left) == AOP_IMMD) ? POC_MOVLW : POC_MOVFW);
7815 emitpcode(poc,popGet(AOP(left),1));
7816 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
7817 emitpcode(poc,popGet(AOP(left),0));
7818 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
7820 emitpLabel(blbl->key);
7822 emitpcode(POC_MOVWF,popGet(AOP(result),0));
7825 freeAsmop(left,NULL,ic,TRUE);
7826 freeAsmop(result,NULL,ic,TRUE);
7829 /*-----------------------------------------------------------------*/
7830 /* genPointerGet - generate code for pointer get */
7831 /*-----------------------------------------------------------------*/
7832 static void genPointerGet (iCode *ic)
7834 operand *left, *result ;
7835 sym_link *type, *etype;
7838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7841 result = IC_RESULT(ic) ;
7843 /* depending on the type of pointer we need to
7844 move it to the correct pointer register */
7845 type = operandType(left);
7846 etype = getSpec(type);
7848 if (IS_PTR_CONST(type))
7849 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
7851 /* if left is of type of pointer then it is simple */
7852 if (IS_PTR(type) && !IS_FUNC(type->next))
7853 p_type = DCL_TYPE(type);
7855 /* we have to go by the storage class */
7856 p_type = PTR_TYPE(SPEC_OCLS(etype));
7858 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
7860 if (SPEC_OCLS(etype)->codesp ) {
7861 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
7862 //p_type = CPOINTER ;
7865 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
7866 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
7867 /*p_type = FPOINTER ;*/
7869 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
7870 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
7871 /* p_type = PPOINTER; */
7873 if (SPEC_OCLS(etype) == idata )
7874 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
7875 /* p_type = IPOINTER; */
7877 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
7878 /* p_type = POINTER ; */
7881 /* now that we have the pointer type we assign
7882 the pointer values */
7887 genNearPointerGet (left,result,ic);
7891 genPagedPointerGet(left,result,ic);
7895 genFarPointerGet (left,result,ic);
7899 genConstPointerGet (left,result,ic);
7900 //pic14_emitcodePointerGet (left,result,ic);
7904 if (IS_PTR_CONST(type))
7905 genConstPointerGet (left,result,ic);
7907 genGenPointerGet (left,result,ic);
7913 /*-----------------------------------------------------------------*/
7914 /* genPackBits - generates code for packed bit storage */
7915 /*-----------------------------------------------------------------*/
7916 static void genPackBits (sym_link *etype ,
7918 char *rname, int p_type)
7926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7927 blen = SPEC_BLEN(etype);
7928 bstr = SPEC_BSTR(etype);
7930 l = aopGet(AOP(right),offset++,FALSE,FALSE);
7933 /* if the bit lenth is less than or */
7934 /* it exactly fits a byte then */
7935 if (SPEC_BLEN(etype) <= 8 ) {
7936 shCount = SPEC_BSTR(etype) ;
7938 /* shift left acc */
7941 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7946 pic14_emitcode ("mov","b,a");
7947 pic14_emitcode("mov","a,@%s",rname);
7951 pic14_emitcode ("mov","b,a");
7952 pic14_emitcode("movx","a,@dptr");
7956 pic14_emitcode ("push","b");
7957 pic14_emitcode ("push","acc");
7958 pic14_emitcode ("lcall","__gptrget");
7959 pic14_emitcode ("pop","b");
7963 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7964 ((unsigned char)(0xFF << (blen+bstr)) |
7965 (unsigned char)(0xFF >> (8-bstr)) ) );
7966 pic14_emitcode ("orl","a,b");
7967 if (p_type == GPOINTER)
7968 pic14_emitcode("pop","b");
7974 pic14_emitcode("mov","@%s,a",rname);
7978 pic14_emitcode("movx","@dptr,a");
7982 DEBUGpic14_emitcode(";lcall","__gptrput");
7987 if ( SPEC_BLEN(etype) <= 8 )
7990 pic14_emitcode("inc","%s",rname);
7991 rLen = SPEC_BLEN(etype) ;
7993 /* now generate for lengths greater than one byte */
7996 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8006 pic14_emitcode("mov","@%s,a",rname);
8008 pic14_emitcode("mov","@%s,%s",rname,l);
8013 pic14_emitcode("movx","@dptr,a");
8018 DEBUGpic14_emitcode(";lcall","__gptrput");
8021 pic14_emitcode ("inc","%s",rname);
8026 /* last last was not complete */
8028 /* save the byte & read byte */
8031 pic14_emitcode ("mov","b,a");
8032 pic14_emitcode("mov","a,@%s",rname);
8036 pic14_emitcode ("mov","b,a");
8037 pic14_emitcode("movx","a,@dptr");
8041 pic14_emitcode ("push","b");
8042 pic14_emitcode ("push","acc");
8043 pic14_emitcode ("lcall","__gptrget");
8044 pic14_emitcode ("pop","b");
8048 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8049 pic14_emitcode ("orl","a,b");
8052 if (p_type == GPOINTER)
8053 pic14_emitcode("pop","b");
8058 pic14_emitcode("mov","@%s,a",rname);
8062 pic14_emitcode("movx","@dptr,a");
8066 DEBUGpic14_emitcode(";lcall","__gptrput");
8070 /*-----------------------------------------------------------------*/
8071 /* genDataPointerSet - remat pointer to data space */
8072 /*-----------------------------------------------------------------*/
8073 static void genDataPointerSet(operand *right,
8077 int size, offset = 0 ;
8078 char *l, buffer[256];
8080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8081 aopOp(right,ic,FALSE);
8083 l = aopGet(AOP(result),0,FALSE,TRUE);
8084 size = AOP_SIZE(right);
8085 // tsd, was l+1 - the underline `_' prefix was being stripped
8088 sprintf(buffer,"(%s + %d)",l,offset);
8090 sprintf(buffer,"%s",l);
8092 if (AOP_TYPE(right) == AOP_LIT) {
8093 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8094 lit = lit >> (8*offset);
8096 pic14_emitcode("movlw","%d",lit);
8097 pic14_emitcode("movwf","%s",buffer);
8099 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8100 emitpcode(POC_MOVWF, popRegFromString(buffer));
8103 pic14_emitcode("clrf","%s",buffer);
8104 //emitpcode(POC_CLRF, popRegFromString(buffer));
8105 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8108 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8109 pic14_emitcode("movwf","%s",buffer);
8111 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8112 emitpcode(POC_MOVWF, popRegFromString(buffer));
8119 freeAsmop(right,NULL,ic,TRUE);
8120 freeAsmop(result,NULL,ic,TRUE);
8123 /*-----------------------------------------------------------------*/
8124 /* genNearPointerSet - pic14_emitcode for near pointer put */
8125 /*-----------------------------------------------------------------*/
8126 static void genNearPointerSet (operand *right,
8133 sym_link *ptype = operandType(result);
8136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8137 retype= getSpec(operandType(right));
8139 aopOp(result,ic,FALSE);
8141 /* if the result is rematerializable &
8142 in data space & not a bit variable */
8143 if (AOP_TYPE(result) == AOP_IMMD &&
8144 DCL_TYPE(ptype) == POINTER &&
8145 !IS_BITVAR(retype)) {
8146 genDataPointerSet (right,result,ic);
8150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8152 /* if the value is already in a pointer register
8153 then don't need anything more */
8154 if (!AOP_INPREG(AOP(result))) {
8155 /* otherwise get a free pointer register */
8156 //aop = newAsmop(0);
8157 //preg = getFreePtr(ic,&aop,FALSE);
8158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 //pic14_emitcode("mov","%s,%s",
8161 // aopGet(AOP(result),0,FALSE,TRUE));
8162 //rname = preg->name ;
8163 pic14_emitcode("movwf","fsr");
8165 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8167 freeAsmop(result,NULL,ic,TRUE);
8168 aopOp (right,ic,FALSE);
8169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8171 /* if bitfield then unpack the bits */
8172 if (IS_BITVAR(retype)) {
8173 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8174 "The programmer is obviously confused");
8175 //genPackBits (retype,right,rname,POINTER);
8179 /* we have can just get the values */
8180 int size = AOP_SIZE(right);
8183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8185 l = aopGet(AOP(right),offset,FALSE,TRUE);
8188 //pic14_emitcode("mov","@%s,a",rname);
8189 pic14_emitcode("movf","indf,w ;1");
8192 if (AOP_TYPE(right) == AOP_LIT) {
8193 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8195 pic14_emitcode("movlw","%s",l);
8196 pic14_emitcode("movwf","indf ;2");
8198 pic14_emitcode("clrf","indf");
8200 pic14_emitcode("movf","%s,w",l);
8201 pic14_emitcode("movwf","indf ;2");
8203 //pic14_emitcode("mov","@%s,%s",rname,l);
8206 pic14_emitcode("incf","fsr,f ;3");
8207 //pic14_emitcode("inc","%s",rname);
8212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8213 /* now some housekeeping stuff */
8215 /* we had to allocate for this iCode */
8216 freeAsmop(NULL,aop,ic,TRUE);
8218 /* we did not allocate which means left
8219 already in a pointer register, then
8220 if size > 0 && this could be used again
8221 we have to point it back to where it
8223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8224 if (AOP_SIZE(right) > 1 &&
8225 !OP_SYMBOL(result)->remat &&
8226 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8228 int size = AOP_SIZE(right) - 1;
8230 pic14_emitcode("decf","fsr,f");
8231 //pic14_emitcode("dec","%s",rname);
8235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8237 freeAsmop(right,NULL,ic,TRUE);
8242 /*-----------------------------------------------------------------*/
8243 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8244 /*-----------------------------------------------------------------*/
8245 static void genPagedPointerSet (operand *right,
8254 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8256 retype= getSpec(operandType(right));
8258 aopOp(result,ic,FALSE);
8260 /* if the value is already in a pointer register
8261 then don't need anything more */
8262 if (!AOP_INPREG(AOP(result))) {
8263 /* otherwise get a free pointer register */
8265 preg = getFreePtr(ic,&aop,FALSE);
8266 pic14_emitcode("mov","%s,%s",
8268 aopGet(AOP(result),0,FALSE,TRUE));
8269 rname = preg->name ;
8271 rname = aopGet(AOP(result),0,FALSE,FALSE);
8273 freeAsmop(result,NULL,ic,TRUE);
8274 aopOp (right,ic,FALSE);
8276 /* if bitfield then unpack the bits */
8277 if (IS_BITVAR(retype))
8278 genPackBits (retype,right,rname,PPOINTER);
8280 /* we have can just get the values */
8281 int size = AOP_SIZE(right);
8285 l = aopGet(AOP(right),offset,FALSE,TRUE);
8288 pic14_emitcode("movx","@%s,a",rname);
8291 pic14_emitcode("inc","%s",rname);
8297 /* now some housekeeping stuff */
8299 /* we had to allocate for this iCode */
8300 freeAsmop(NULL,aop,ic,TRUE);
8302 /* we did not allocate which means left
8303 already in a pointer register, then
8304 if size > 0 && this could be used again
8305 we have to point it back to where it
8307 if (AOP_SIZE(right) > 1 &&
8308 !OP_SYMBOL(result)->remat &&
8309 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8311 int size = AOP_SIZE(right) - 1;
8313 pic14_emitcode("dec","%s",rname);
8318 freeAsmop(right,NULL,ic,TRUE);
8323 /*-----------------------------------------------------------------*/
8324 /* genFarPointerSet - set value from far space */
8325 /*-----------------------------------------------------------------*/
8326 static void genFarPointerSet (operand *right,
8327 operand *result, iCode *ic)
8330 sym_link *retype = getSpec(operandType(right));
8332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8333 aopOp(result,ic,FALSE);
8335 /* if the operand is already in dptr
8336 then we do nothing else we move the value to dptr */
8337 if (AOP_TYPE(result) != AOP_STR) {
8338 /* if this is remateriazable */
8339 if (AOP_TYPE(result) == AOP_IMMD)
8340 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8341 else { /* we need to get it byte by byte */
8342 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8343 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8344 if (options.model == MODEL_FLAT24)
8346 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8350 /* so dptr know contains the address */
8351 freeAsmop(result,NULL,ic,TRUE);
8352 aopOp(right,ic,FALSE);
8354 /* if bit then unpack */
8355 if (IS_BITVAR(retype))
8356 genPackBits(retype,right,"dptr",FPOINTER);
8358 size = AOP_SIZE(right);
8362 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8364 pic14_emitcode("movx","@dptr,a");
8366 pic14_emitcode("inc","dptr");
8370 freeAsmop(right,NULL,ic,TRUE);
8373 /*-----------------------------------------------------------------*/
8374 /* genGenPointerSet - set value from generic pointer space */
8375 /*-----------------------------------------------------------------*/
8376 static void genGenPointerSet (operand *right,
8377 operand *result, iCode *ic)
8380 sym_link *retype = getSpec(operandType(right));
8382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8384 aopOp(result,ic,FALSE);
8385 aopOp(right,ic,FALSE);
8386 size = AOP_SIZE(right);
8388 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8390 /* if the operand is already in dptr
8391 then we do nothing else we move the value to dptr */
8392 if (AOP_TYPE(result) != AOP_STR) {
8393 /* if this is remateriazable */
8394 if (AOP_TYPE(result) == AOP_IMMD) {
8395 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8396 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8398 else { /* we need to get it byte by byte */
8399 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8400 size = AOP_SIZE(right);
8403 /* hack hack! see if this the FSR. If so don't load W */
8404 if(AOP_TYPE(right) != AOP_ACC) {
8406 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8407 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8410 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8412 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8413 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8417 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8418 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8421 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8428 if(aopIdx(AOP(result),0) != 4) {
8430 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8434 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8439 /* so dptr know contains the address */
8442 /* if bit then unpack */
8443 if (IS_BITVAR(retype))
8444 genPackBits(retype,right,"dptr",GPOINTER);
8446 size = AOP_SIZE(right);
8450 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8452 pic14_emitcode("incf","fsr,f");
8453 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8454 pic14_emitcode("movwf","indf");
8456 //DEBUGpic14_emitcode(";lcall","__gptrput");
8458 // pic14_emitcode("inc","dptr");
8463 freeAsmop(right,NULL,ic,TRUE);
8464 freeAsmop(result,NULL,ic,TRUE);
8467 /*-----------------------------------------------------------------*/
8468 /* genPointerSet - stores the value into a pointer location */
8469 /*-----------------------------------------------------------------*/
8470 static void genPointerSet (iCode *ic)
8472 operand *right, *result ;
8473 sym_link *type, *etype;
8476 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8478 right = IC_RIGHT(ic);
8479 result = IC_RESULT(ic) ;
8481 /* depending on the type of pointer we need to
8482 move it to the correct pointer register */
8483 type = operandType(result);
8484 etype = getSpec(type);
8485 /* if left is of type of pointer then it is simple */
8486 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8487 p_type = DCL_TYPE(type);
8490 /* we have to go by the storage class */
8491 p_type = PTR_TYPE(SPEC_OCLS(etype));
8493 /* if (SPEC_OCLS(etype)->codesp ) { */
8494 /* p_type = CPOINTER ; */
8497 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8498 /* p_type = FPOINTER ; */
8500 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8501 /* p_type = PPOINTER ; */
8503 /* if (SPEC_OCLS(etype) == idata ) */
8504 /* p_type = IPOINTER ; */
8506 /* p_type = POINTER ; */
8509 /* now that we have the pointer type we assign
8510 the pointer values */
8515 genNearPointerSet (right,result,ic);
8519 genPagedPointerSet (right,result,ic);
8523 genFarPointerSet (right,result,ic);
8527 genGenPointerSet (right,result,ic);
8531 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8532 "genPointerSet: illegal pointer type");
8536 /*-----------------------------------------------------------------*/
8537 /* genIfx - generate code for Ifx statement */
8538 /*-----------------------------------------------------------------*/
8539 static void genIfx (iCode *ic, iCode *popIc)
8541 operand *cond = IC_COND(ic);
8544 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8546 aopOp(cond,ic,FALSE);
8548 /* get the value into acc */
8549 if (AOP_TYPE(cond) != AOP_CRY)
8550 pic14_toBoolean(cond);
8553 /* the result is now in the accumulator */
8554 freeAsmop(cond,NULL,ic,TRUE);
8556 /* if there was something to be popped then do it */
8560 /* if the condition is a bit variable */
8561 if (isbit && IS_ITEMP(cond) &&
8563 genIfxJump(ic,SPIL_LOC(cond)->rname);
8564 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8567 if (isbit && !IS_ITEMP(cond))
8568 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8576 /*-----------------------------------------------------------------*/
8577 /* genAddrOf - generates code for address of */
8578 /*-----------------------------------------------------------------*/
8579 static void genAddrOf (iCode *ic)
8581 //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8582 operand *right, *result, *left;
8583 //int size, offset ;
8585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8588 //aopOp(IC_RESULT(ic),ic,FALSE);
8590 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8591 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8592 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8594 DEBUGpic14_AopType(__LINE__,left,right,result);
8596 emitpcode(POC_MOVLW, popGet(AOP(left),0));
8597 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8600 /* object not on stack then we need the name */
8601 size = AOP_SIZE(IC_RESULT(ic));
8605 char s[SDCC_NAME_MAX];
8607 sprintf(s,"#(%s >> %d)",
8611 sprintf(s,"#%s",sym->rname);
8612 aopPut(AOP(IC_RESULT(ic)),s,offset++);
8617 // freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8618 freeAsmop(left,NULL,ic,FALSE);
8619 freeAsmop(result,NULL,ic,TRUE);
8624 /*-----------------------------------------------------------------*/
8625 /* genFarFarAssign - assignment when both are in far space */
8626 /*-----------------------------------------------------------------*/
8627 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8629 int size = AOP_SIZE(right);
8632 /* first push the right side on to the stack */
8634 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8636 pic14_emitcode ("push","acc");
8639 freeAsmop(right,NULL,ic,FALSE);
8640 /* now assign DPTR to result */
8641 aopOp(result,ic,FALSE);
8642 size = AOP_SIZE(result);
8644 pic14_emitcode ("pop","acc");
8645 aopPut(AOP(result),"a",--offset);
8647 freeAsmop(result,NULL,ic,FALSE);
8652 /*-----------------------------------------------------------------*/
8653 /* genAssign - generate code for assignment */
8654 /*-----------------------------------------------------------------*/
8655 static void genAssign (iCode *ic)
8657 operand *result, *right;
8658 int size, offset,know_W;
8659 unsigned long lit = 0L;
8661 result = IC_RESULT(ic);
8662 right = IC_RIGHT(ic) ;
8664 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8666 /* if they are the same */
8667 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8670 aopOp(right,ic,FALSE);
8671 aopOp(result,ic,TRUE);
8673 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8675 /* if they are the same registers */
8676 if (pic14_sameRegs(AOP(right),AOP(result)))
8679 /* if the result is a bit */
8680 if (AOP_TYPE(result) == AOP_CRY) {
8682 /* if the right size is a literal then
8683 we know what the value is */
8684 if (AOP_TYPE(right) == AOP_LIT) {
8686 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8687 popGet(AOP(result),0));
8689 if (((int) operandLitValue(right)))
8690 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8691 AOP(result)->aopu.aop_dir,
8692 AOP(result)->aopu.aop_dir);
8694 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8695 AOP(result)->aopu.aop_dir,
8696 AOP(result)->aopu.aop_dir);
8700 /* the right is also a bit variable */
8701 if (AOP_TYPE(right) == AOP_CRY) {
8702 emitpcode(POC_BCF, popGet(AOP(result),0));
8703 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8704 emitpcode(POC_BSF, popGet(AOP(result),0));
8706 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8707 AOP(result)->aopu.aop_dir,
8708 AOP(result)->aopu.aop_dir);
8709 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8710 AOP(right)->aopu.aop_dir,
8711 AOP(right)->aopu.aop_dir);
8712 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8713 AOP(result)->aopu.aop_dir,
8714 AOP(result)->aopu.aop_dir);
8719 emitpcode(POC_BCF, popGet(AOP(result),0));
8720 pic14_toBoolean(right);
8722 emitpcode(POC_BSF, popGet(AOP(result),0));
8723 //aopPut(AOP(result),"a",0);
8727 /* bit variables done */
8729 size = AOP_SIZE(result);
8731 if(AOP_TYPE(right) == AOP_LIT)
8732 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8734 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8735 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8736 if(aopIdx(AOP(result),0) == 4) {
8737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8738 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8739 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8742 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8748 if(AOP_TYPE(right) == AOP_LIT) {
8750 if(know_W != (lit&0xff))
8751 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8753 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8755 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8759 } else if (AOP_TYPE(right) == AOP_CRY) {
8760 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8762 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8763 emitpcode(POC_INCF, popGet(AOP(result),0));
8766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8768 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8776 freeAsmop (right,NULL,ic,FALSE);
8777 freeAsmop (result,NULL,ic,TRUE);
8780 /*-----------------------------------------------------------------*/
8781 /* genJumpTab - genrates code for jump table */
8782 /*-----------------------------------------------------------------*/
8783 static void genJumpTab (iCode *ic)
8788 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8790 aopOp(IC_JTCOND(ic),ic,FALSE);
8791 /* get the condition into accumulator */
8792 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8794 /* multiply by three */
8795 pic14_emitcode("add","a,acc");
8796 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8798 jtab = newiTempLabel(NULL);
8799 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8800 pic14_emitcode("jmp","@a+dptr");
8801 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8803 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8804 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8806 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8807 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8808 emitpLabel(jtab->key);
8810 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8812 /* now generate the jump labels */
8813 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8814 jtab = setNextItem(IC_JTLABELS(ic))) {
8815 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8816 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8822 /*-----------------------------------------------------------------*/
8823 /* genMixedOperation - gen code for operators between mixed types */
8824 /*-----------------------------------------------------------------*/
8826 TSD - Written for the PIC port - but this unfortunately is buggy.
8827 This routine is good in that it is able to efficiently promote
8828 types to different (larger) sizes. Unfortunately, the temporary
8829 variables that are optimized out by this routine are sometimes
8830 used in other places. So until I know how to really parse the
8831 iCode tree, I'm going to not be using this routine :(.
8833 static int genMixedOperation (iCode *ic)
8836 operand *result = IC_RESULT(ic);
8837 sym_link *ctype = operandType(IC_LEFT(ic));
8838 operand *right = IC_RIGHT(ic);
8844 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8846 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8852 nextright = IC_RIGHT(nextic);
8853 nextleft = IC_LEFT(nextic);
8854 nextresult = IC_RESULT(nextic);
8856 aopOp(right,ic,FALSE);
8857 aopOp(result,ic,FALSE);
8858 aopOp(nextright, nextic, FALSE);
8859 aopOp(nextleft, nextic, FALSE);
8860 aopOp(nextresult, nextic, FALSE);
8862 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8868 pic14_emitcode(";remove right +","");
8870 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8876 pic14_emitcode(";remove left +","");
8880 big = AOP_SIZE(nextleft);
8881 small = AOP_SIZE(nextright);
8883 switch(nextic->op) {
8886 pic14_emitcode(";optimize a +","");
8887 /* if unsigned or not an integral type */
8888 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8889 pic14_emitcode(";add a bit to something","");
8892 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8894 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8895 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8896 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8898 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8906 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8907 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8908 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8911 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8913 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8914 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8915 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8916 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8917 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8920 pic14_emitcode("rlf","known_zero,w");
8927 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8928 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8929 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8931 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8941 freeAsmop(right,NULL,ic,TRUE);
8942 freeAsmop(result,NULL,ic,TRUE);
8943 freeAsmop(nextright,NULL,ic,TRUE);
8944 freeAsmop(nextleft,NULL,ic,TRUE);
8946 nextic->generated = 1;
8953 /*-----------------------------------------------------------------*/
8954 /* genCast - gen code for casting */
8955 /*-----------------------------------------------------------------*/
8956 static void genCast (iCode *ic)
8958 operand *result = IC_RESULT(ic);
8959 sym_link *ctype = operandType(IC_LEFT(ic));
8960 sym_link *rtype = operandType(IC_RIGHT(ic));
8961 operand *right = IC_RIGHT(ic);
8964 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8965 /* if they are equivalent then do nothing */
8966 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8969 aopOp(right,ic,FALSE) ;
8970 aopOp(result,ic,FALSE);
8972 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8974 /* if the result is a bit */
8975 if (AOP_TYPE(result) == AOP_CRY) {
8976 /* if the right size is a literal then
8977 we know what the value is */
8978 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8979 if (AOP_TYPE(right) == AOP_LIT) {
8981 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8982 popGet(AOP(result),0));
8984 if (((int) operandLitValue(right)))
8985 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8986 AOP(result)->aopu.aop_dir,
8987 AOP(result)->aopu.aop_dir);
8989 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8990 AOP(result)->aopu.aop_dir,
8991 AOP(result)->aopu.aop_dir);
8996 /* the right is also a bit variable */
8997 if (AOP_TYPE(right) == AOP_CRY) {
9000 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9002 pic14_emitcode("clrc","");
9003 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9004 AOP(right)->aopu.aop_dir,
9005 AOP(right)->aopu.aop_dir);
9006 aopPut(AOP(result),"c",0);
9011 if (AOP_TYPE(right) == AOP_REG) {
9012 emitpcode(POC_BCF, popGet(AOP(result),0));
9013 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9014 emitpcode(POC_BSF, popGet(AOP(result),0));
9016 pic14_toBoolean(right);
9017 aopPut(AOP(result),"a",0);
9021 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9023 size = AOP_SIZE(result);
9025 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9027 emitpcode(POC_CLRF, popGet(AOP(result),0));
9028 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9029 emitpcode(POC_INCF, popGet(AOP(result),0));
9032 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9037 /* if they are the same size : or less */
9038 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9040 /* if they are in the same place */
9041 if (pic14_sameRegs(AOP(right),AOP(result)))
9044 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9045 if (IS_PTR_CONST(rtype))
9046 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9047 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9048 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9050 /* if they in different places then copy */
9051 size = AOP_SIZE(result);
9054 if(AOP_TYPE(right) == AOP_IMMD)
9055 emitpcode(POC_MOVLW, popGetImmd(AOP(right)->aopu.aop_dir,offset));
9057 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9058 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9060 //aopPut(AOP(result),
9061 // aopGet(AOP(right),offset,FALSE,FALSE),
9070 /* if the result is of type pointer */
9071 if (IS_PTR(ctype)) {
9074 sym_link *type = operandType(right);
9075 sym_link *etype = getSpec(type);
9076 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9078 /* pointer to generic pointer */
9079 if (IS_GENPTR(ctype)) {
9083 p_type = DCL_TYPE(type);
9085 /* we have to go by the storage class */
9086 p_type = PTR_TYPE(SPEC_OCLS(etype));
9088 /* if (SPEC_OCLS(etype)->codesp ) */
9089 /* p_type = CPOINTER ; */
9091 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9092 /* p_type = FPOINTER ; */
9094 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9095 /* p_type = PPOINTER; */
9097 /* if (SPEC_OCLS(etype) == idata ) */
9098 /* p_type = IPOINTER ; */
9100 /* p_type = POINTER ; */
9103 /* the first two bytes are known */
9104 size = GPTRSIZE - 1;
9107 if(offset < AOP_SIZE(right))
9109 aopGet(AOP(right),offset,FALSE,FALSE),
9112 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9115 /* the last byte depending on type */
9119 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9122 pic14_emitcode(";BUG!? ","%d",__LINE__);
9126 pic14_emitcode(";BUG!? ","%d",__LINE__);
9130 pic14_emitcode(";BUG!? ","%d",__LINE__);
9135 /* this should never happen */
9136 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9137 "got unknown pointer type");
9140 //aopPut(AOP(result),l, GPTRSIZE - 1);
9144 /* just copy the pointers */
9145 size = AOP_SIZE(result);
9149 aopGet(AOP(right),offset,FALSE,FALSE),
9158 /* so we now know that the size of destination is greater
9159 than the size of the source.
9160 Now, if the next iCode is an operator then we might be
9161 able to optimize the operation without performing a cast.
9163 if(genMixedOperation(ic))
9166 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9168 /* we move to result for the size of source */
9169 size = AOP_SIZE(right);
9172 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9173 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9177 /* now depending on the sign of the destination */
9178 size = AOP_SIZE(result) - AOP_SIZE(right);
9179 /* if unsigned or not an integral type */
9180 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9182 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9184 /* we need to extend the sign :{ */
9187 /* Save one instruction of casting char to int */
9188 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9189 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9190 emitpcode(POC_DECF, popGet(AOP(result),offset));
9192 emitpcodeNULLop(POC_CLRW);
9195 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9197 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9199 emitpcode(POC_MOVLW, popGetLit(0xff));
9202 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9207 freeAsmop(right,NULL,ic,TRUE);
9208 freeAsmop(result,NULL,ic,TRUE);
9212 /*-----------------------------------------------------------------*/
9213 /* genDjnz - generate decrement & jump if not zero instrucion */
9214 /*-----------------------------------------------------------------*/
9215 static int genDjnz (iCode *ic, iCode *ifx)
9218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9223 /* if the if condition has a false label
9224 then we cannot save */
9228 /* if the minus is not of the form
9230 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9231 !IS_OP_LITERAL(IC_RIGHT(ic)))
9234 if (operandLitValue(IC_RIGHT(ic)) != 1)
9237 /* if the size of this greater than one then no
9239 if (getSize(operandType(IC_RESULT(ic))) > 1)
9242 /* otherwise we can save BIG */
9243 lbl = newiTempLabel(NULL);
9244 lbl1= newiTempLabel(NULL);
9246 aopOp(IC_RESULT(ic),ic,FALSE);
9248 if (IS_AOP_PREG(IC_RESULT(ic))) {
9249 pic14_emitcode("dec","%s",
9250 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9251 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9252 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9256 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9257 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9259 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9260 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9263 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9264 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9265 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9266 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9269 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9274 /*-----------------------------------------------------------------*/
9275 /* genReceive - generate code for a receive iCode */
9276 /*-----------------------------------------------------------------*/
9277 static void genReceive (iCode *ic)
9279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9281 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9282 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9283 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9285 int size = getSize(operandType(IC_RESULT(ic)));
9286 int offset = fReturnSizePic - size;
9288 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9289 fReturn[fReturnSizePic - offset - 1] : "acc"));
9292 aopOp(IC_RESULT(ic),ic,FALSE);
9293 size = AOP_SIZE(IC_RESULT(ic));
9296 pic14_emitcode ("pop","acc");
9297 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9302 aopOp(IC_RESULT(ic),ic,FALSE);
9304 assignResultValue(IC_RESULT(ic));
9307 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9310 /*-----------------------------------------------------------------*/
9311 /* genpic14Code - generate code for pic14 based controllers */
9312 /*-----------------------------------------------------------------*/
9314 * At this point, ralloc.c has gone through the iCode and attempted
9315 * to optimize in a way suitable for a PIC. Now we've got to generate
9316 * PIC instructions that correspond to the iCode.
9318 * Once the instructions are generated, we'll pass through both the
9319 * peep hole optimizer and the pCode optimizer.
9320 *-----------------------------------------------------------------*/
9322 void genpic14Code (iCode *lic)
9327 lineHead = lineCurr = NULL;
9329 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9332 /* if debug information required */
9333 if (options.debug && currFunc) {
9335 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9337 if (IS_STATIC(currFunc->etype)) {
9338 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9339 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9341 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9342 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9349 for (ic = lic ; ic ; ic = ic->next ) {
9351 DEBUGpic14_emitcode(";ic","");
9352 if ( cln != ic->lineno ) {
9353 if ( options.debug ) {
9355 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9356 FileBaseName(ic->filename),ic->lineno,
9357 ic->level,ic->block);
9360 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9363 /* if the result is marked as
9364 spilt and rematerializable or code for
9365 this has already been generated then
9367 if (resultRemat(ic) || ic->generated )
9370 /* depending on the operation */
9389 /* IPOP happens only when trying to restore a
9390 spilt live range, if there is an ifx statement
9391 following this pop then the if statement might
9392 be using some of the registers being popped which
9393 would destory the contents of the register so
9394 we need to check for this condition and handle it */
9396 ic->next->op == IFX &&
9397 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9398 genIfx (ic->next,ic);
9416 genEndFunction (ic);
9436 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9453 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9457 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9464 /* note these two are xlated by algebraic equivalence
9465 during parsing SDCC.y */
9466 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9467 "got '>=' or '<=' shouldn't have come here");
9471 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9483 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9487 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9491 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9518 case GET_VALUE_AT_ADDRESS:
9523 if (POINTER_SET(ic))
9550 addSet(&_G.sendSet,ic);
9559 /* now we are ready to call the
9560 peep hole optimizer */
9561 if (!options.nopeep) {
9562 peepHole (&lineHead);
9564 /* now do the actual printing */
9565 printLine (lineHead,codeOutFile);
9568 DFPRINTF((stderr,"printing pBlock\n\n"));
9569 printpBlock(stdout,pb);