1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic16
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)
8 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
41 #include "SDCCpeeph.h"
49 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
50 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
51 void pic16_genMult8X8_8 (operand *, operand *,operand *);
52 void pic16_genMult16X16_16(operand *, operand *, operand *);
53 void pic16_genMult32X32_32(operand *, operand *, operand *);
54 pCode *pic16_AssembleLine(char *line, int peeps);
55 extern void pic16_printpBlock(FILE *of, pBlock *pb);
56 static asmop *newAsmop (short type);
57 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
58 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
59 static void mov2w (asmop *aop, int offset);
60 static int aopIdx (asmop *aop, int offset);
62 static int labelOffset=0;
63 extern int pic16_debug_verbose;
64 static int optimized_for_speed = 0;
70 /* max_key keeps track of the largest label number used in
71 a function. This is then used to adjust the label offset
72 for the next function.
75 static int GpsuedoStkPtr=0;
77 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
78 unsigned int pic16aopLiteral (value *val, int offset);
79 const char *pic16_AopType(short type);
80 static iCode *ifxForOp ( operand *op, iCode *ic );
82 void pic16_pushpCodeOp(pCodeOp *pcop);
83 void pic16_poppCodeOp(pCodeOp *pcop);
85 static bool is_LitOp(operand *op);
88 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
90 /* this is the down and dirty file with all kinds of
91 kludgy & hacky stuff. This is what it is all about
92 CODE GENERATION for a specific MCU . some of the
93 routines may be reusable, will have to see */
95 static char *zero = "#0x00";
96 static char *one = "#0x01";
97 static char *spname = "sp";
101 * Function return value policy (MSB-->LSB):
103 * 16 bits -> PRODL:WREG
104 * 24 bits -> PRODH:PRODL:WREG
105 * 32 bits -> FSR0L:PRODH:PRODL:WREG
106 * >32 bits -> on stack, and FSR0 points to the beginning
111 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
112 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
113 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
114 static char **fReturn = fReturnpic16;
116 static char *accUse[] = {"WREG"};
118 //static short rbank = -1;
131 /* Resolved ifx structure. This structure stores information
132 about an iCode ifx that makes it easier to generate code.
134 typedef struct resolvedIfx {
135 symbol *lbl; /* pointer to a label */
136 int condition; /* true or false ifx */
137 int generated; /* set true when the code associated with the ifx
141 extern int pic16_ptrRegReq ;
142 extern int pic16_nRegs;
143 extern FILE *codeOutFile;
144 static void saverbank (int, iCode *,bool);
146 static lineNode *lineHead = NULL;
147 static lineNode *lineCurr = NULL;
149 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
150 0xE0, 0xC0, 0x80, 0x00};
151 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
152 0x07, 0x03, 0x01, 0x00};
156 /*-----------------------------------------------------------------*/
157 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
158 /* exponent of 2 is returned, otherwise -1 is */
160 /* note that this is similar to the function `powof2' in SDCCsymt */
164 /*-----------------------------------------------------------------*/
165 static int my_powof2 (unsigned long num)
168 if( (num & (num-1)) == 0) {
181 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
183 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
185 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
186 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
187 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
188 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
189 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
190 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
191 ((result) ? AOP_SIZE(result) : 0));
194 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
197 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
199 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
200 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
201 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
202 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
203 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
204 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
208 void pic16_emitpcomment (char *fmt, ...)
211 char lb[INITIAL_INLINEASM];
217 vsprintf(lb+1,fmt,ap);
219 while (isspace(*lbp)) lbp++;
222 lineCurr = (lineCurr ?
223 connectLine(lineCurr,newLineNode(lb)) :
224 (lineHead = newLineNode(lb)));
225 lineCurr->isInline = _G.inLine;
226 lineCurr->isDebug = _G.debugLine;
228 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
231 // fprintf(stderr, "%s\n", lb);
234 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
237 char lb[INITIAL_INLINEASM];
240 if(!pic16_debug_verbose)
247 sprintf(lb,"%s\t",inst);
249 sprintf(lb,"%s",inst);
250 vsprintf(lb+(strlen(lb)),fmt,ap);
254 while (isspace(*lbp)) lbp++;
257 lineCurr = (lineCurr ?
258 connectLine(lineCurr,newLineNode(lb)) :
259 (lineHead = newLineNode(lb)));
260 lineCurr->isInline = _G.inLine;
261 lineCurr->isDebug = _G.debugLine;
263 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
266 // fprintf(stderr, "%s\n", lb);
269 void pic16_emitpLabel(int key)
271 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
274 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
278 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
280 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
282 // fprintf(stderr, "%s\n", pcop->name);
285 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
288 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
294 #define pic16_emitcode DEBUGpic16_emitcode
296 /*-----------------------------------------------------------------*/
297 /* pic16_emitcode - writes the code into a file : for now it is simple */
298 /*-----------------------------------------------------------------*/
299 void pic16_emitcode (char *inst,char *fmt, ...)
302 char lb[INITIAL_INLINEASM];
309 sprintf(lb,"%s\t",inst);
311 sprintf(lb,"%s",inst);
312 vsprintf(lb+(strlen(lb)),fmt,ap);
316 while (isspace(*lbp)) lbp++;
319 lineCurr = (lineCurr ?
320 connectLine(lineCurr,newLineNode(lb)) :
321 (lineHead = newLineNode(lb)));
322 lineCurr->isInline = _G.inLine;
323 lineCurr->isDebug = _G.debugLine;
325 // VR fprintf(stderr, "lb = <%s>\n", lbp);
327 // if(pic16_debug_verbose)
328 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
335 /*-----------------------------------------------------------------*/
336 /* pic16_emitDebuggerSymbol - associate the current code location */
337 /* with a debugger symbol */
338 /*-----------------------------------------------------------------*/
340 pic16_emitDebuggerSymbol (char * debugSym)
343 pic16_emitcode (";", "%s ==.", debugSym);
348 /*-----------------------------------------------------------------*/
349 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
350 /*-----------------------------------------------------------------*/
351 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
353 bool r0iu = FALSE , r1iu = FALSE;
354 bool r0ou = FALSE , r1ou = FALSE;
356 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
358 /* the logic: if r0 & r1 used in the instruction
359 then we are in trouble otherwise */
361 /* first check if r0 & r1 are used by this
362 instruction, in which case we are in trouble */
363 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
364 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
369 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
370 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
372 /* if no usage of r0 then return it */
373 if (!r0iu && !r0ou) {
374 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
375 (*aopp)->type = AOP_R0;
377 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
380 /* if no usage of r1 then return it */
381 if (!r1iu && !r1ou) {
382 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
383 (*aopp)->type = AOP_R1;
385 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
388 /* now we know they both have usage */
389 /* if r0 not used in this instruction */
391 /* push it if not already pushed */
393 //pic16_emitcode ("push","%s",
394 // pic16_regWithIdx(R0_IDX)->dname);
398 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
399 (*aopp)->type = AOP_R0;
401 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
404 /* if r1 not used then */
407 /* push it if not already pushed */
409 //pic16_emitcode ("push","%s",
410 // pic16_regWithIdx(R1_IDX)->dname);
414 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
415 (*aopp)->type = AOP_R1;
416 return pic16_regWithIdx(R1_IDX);
420 /* I said end of world but not quite end of world yet */
421 /* if this is a result then we can push it on the stack*/
423 (*aopp)->type = AOP_STK;
427 /* other wise this is true end of the world */
428 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
429 "getFreePtr should never reach here");
433 /*-----------------------------------------------------------------*/
434 /* newAsmop - creates a new asmOp */
435 /*-----------------------------------------------------------------*/
436 static asmop *newAsmop (short type)
440 aop = Safe_calloc(1,sizeof(asmop));
445 static void genSetDPTR(int n)
449 pic16_emitcode(";", "Select standard DPTR");
450 pic16_emitcode("mov", "dps, #0x00");
454 pic16_emitcode(";", "Select alternate DPTR");
455 pic16_emitcode("mov", "dps, #0x01");
459 /*-----------------------------------------------------------------*/
460 /* resolveIfx - converts an iCode ifx into a form more useful for */
461 /* generating code */
462 /*-----------------------------------------------------------------*/
463 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
466 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
472 resIfx->condition = 1; /* assume that the ifx is true */
473 resIfx->generated = 0; /* indicate that the ifx has not been used */
476 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
479 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
480 __FUNCTION__,__LINE__,resIfx->lbl->key);
485 resIfx->lbl = IC_TRUE(ifx);
487 resIfx->lbl = IC_FALSE(ifx);
488 resIfx->condition = 0;
493 DEBUGpic16_emitcode("; ***","ifx true is non-null");
495 DEBUGpic16_emitcode("; ***","ifx false is non-null");
499 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
503 /*-----------------------------------------------------------------*/
504 /* pointerCode - returns the code for a pointer type */
505 /*-----------------------------------------------------------------*/
506 static int pointerCode (sym_link *etype)
509 return PTR_TYPE(SPEC_OCLS(etype));
513 /*-----------------------------------------------------------------*/
514 /* aopForSym - for a true symbol */
515 /*-----------------------------------------------------------------*/
516 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
519 memmap *space= SPEC_OCLS(sym->etype);
521 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
522 /* if already has one */
524 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
528 /* if symbol was initially placed onStack then we must re-place it
529 * to direct memory, since pic16 does not have a specific stack */
532 SPEC_OCLS( sym->etype ) = data;
538 /* assign depending on the storage class */
539 /* if it is on the stack or indirectly addressable */
540 /* space we need to assign either r0 or r1 to it */
541 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
543 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
544 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
546 sym->aop = aop = newAsmop(0);
547 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
548 aop->size = getSize(sym->type);
550 /* now assign the address of the variable to
551 the pointer register */
552 if (aop->type != AOP_STK) {
556 pic16_emitcode("push","acc");
558 pic16_emitcode("mov","a,_bp");
559 pic16_emitcode("add","a,#0x%02x",
561 ((char)(sym->stack - _G.nRegsSaved )) :
562 ((char)sym->stack)) & 0xff);
563 pic16_emitcode("mov","%s,a",
564 aop->aopu.aop_ptr->name);
567 pic16_emitcode("pop","acc");
569 pic16_emitcode("mov","%s,#%s",
570 aop->aopu.aop_ptr->name,
572 aop->paged = space->paged;
574 aop->aopu.aop_stk = sym->stack;
579 if (sym->onStack && options.stack10bit)
581 /* It's on the 10 bit stack, which is located in
585 //DEBUGpic16_emitcode(";","%d",__LINE__);
588 pic16_emitcode("push","acc");
590 pic16_emitcode("mov","a,_bp");
591 pic16_emitcode("add","a,#0x%02x",
593 ((char)(sym->stack - _G.nRegsSaved )) :
594 ((char)sym->stack)) & 0xff);
597 pic16_emitcode ("mov","dpx1,#0x40");
598 pic16_emitcode ("mov","dph1,#0x00");
599 pic16_emitcode ("mov","dpl1, a");
603 pic16_emitcode("pop","acc");
605 sym->aop = aop = newAsmop(AOP_DPTR2);
606 aop->size = getSize(sym->type);
610 //DEBUGpic16_emitcode(";","%d",__LINE__);
611 /* if in bit space */
612 if (IN_BITSPACE(space)) {
613 sym->aop = aop = newAsmop (AOP_CRY);
614 aop->aopu.aop_dir = sym->rname ;
615 aop->size = getSize(sym->type);
616 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
619 /* if it is in direct space */
620 if (IN_DIRSPACE(space)) {
621 sym->aop = aop = newAsmop (AOP_DIR);
622 aop->aopu.aop_dir = sym->rname ;
623 aop->size = getSize(sym->type);
624 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
625 pic16_allocDirReg( IC_LEFT(ic) );
630 /* special case for a function */
631 if (IS_FUNC(sym->type)) {
632 sym->aop = aop = newAsmop(AOP_IMMD);
633 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
634 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
635 strcpy(aop->aopu.aop_immd,sym->rname);
636 aop->size = FPTRSIZE;
637 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
643 /* only remaining is far space */
644 /* in which case DPTR gets the address */
645 sym->aop = aop = newAsmop(AOP_PCODE);
647 /* change the next if to 1 to revert to good old immediate code */
648 if(IN_CODESPACE(space)) {
649 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
650 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
651 PCOI(aop->aopu.pcop)->index = 0;
653 /* try to allocate via direct register */
654 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
655 // aop->size = getSize( sym->type );
658 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
659 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
662 if(!pic16_allocDirReg (IC_LEFT(ic)))
666 if(IN_DIRSPACE( space ))
668 else if(IN_CODESPACE( space ))
669 aop->size = FPTRSIZE;
670 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
671 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
676 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
678 /* if it is in code space */
679 if (IN_CODESPACE(space))
685 /*-----------------------------------------------------------------*/
686 /* aopForRemat - rematerialzes an object */
687 /*-----------------------------------------------------------------*/
688 static asmop *aopForRemat (operand *op) // x symbol *sym)
690 symbol *sym = OP_SYMBOL(op);
691 iCode *ic = NULL, *oldic;
692 asmop *aop = newAsmop(AOP_PCODE);
698 ic = sym->rematiCode;
700 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
702 if(IS_OP_POINTER(op)) {
703 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
709 // pic16_emitpcomment("ic: %s\n", printILine(ic));
712 val += (int) operandLitValue(IC_RIGHT(ic));
713 } else if (ic->op == '-') {
714 val -= (int) operandLitValue(IC_RIGHT(ic));
718 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
721 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
723 if(!op->isaddr)viaimmd++; else viaimmd=0;
725 /* set the following if to 1 to revert to good old immediate code */
726 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
729 DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__);
731 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
734 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
736 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
739 PCOI(aop->aopu.pcop)->index = val;
741 DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__);
743 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
744 // aop->size = AOP_SIZE( IC_LEFT(ic) );
748 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
749 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
751 val, IS_PTR_CONST(operandType(op)));
753 val, IS_CODEPTR(operandType(op)));
756 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
758 pic16_allocDirReg (IC_LEFT(ic));
760 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
766 static int aopIdx (asmop *aop, int offset)
771 if(aop->type != AOP_REG)
774 return aop->aopu.aop_reg[offset]->rIdx;
777 /*-----------------------------------------------------------------*/
778 /* regsInCommon - two operands have some registers in common */
779 /*-----------------------------------------------------------------*/
780 static bool regsInCommon (operand *op1, operand *op2)
785 /* if they have registers in common */
786 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
789 sym1 = OP_SYMBOL(op1);
790 sym2 = OP_SYMBOL(op2);
792 if (sym1->nRegs == 0 || sym2->nRegs == 0)
795 for (i = 0 ; i < sym1->nRegs ; i++) {
800 for (j = 0 ; j < sym2->nRegs ;j++ ) {
804 if (sym2->regs[j] == sym1->regs[i])
812 /*-----------------------------------------------------------------*/
813 /* operandsEqu - equivalent */
814 /*-----------------------------------------------------------------*/
815 static bool operandsEqu ( operand *op1, operand *op2)
819 /* if they not symbols */
820 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
823 sym1 = OP_SYMBOL(op1);
824 sym2 = OP_SYMBOL(op2);
826 /* if both are itemps & one is spilt
827 and the other is not then false */
828 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
829 sym1->isspilt != sym2->isspilt )
832 /* if they are the same */
836 if (strcmp(sym1->rname,sym2->rname) == 0)
840 /* if left is a tmp & right is not */
844 (sym1->usl.spillLoc == sym2))
851 (sym2->usl.spillLoc == sym1))
857 /*-----------------------------------------------------------------*/
858 /* pic16_sameRegs - two asmops have the same registers */
859 /*-----------------------------------------------------------------*/
860 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
867 if (aop1->type != AOP_REG ||
868 aop2->type != AOP_REG )
871 if (aop1->size != aop2->size )
874 for (i = 0 ; i < aop1->size ; i++ )
875 if (aop1->aopu.aop_reg[i] !=
876 aop2->aopu.aop_reg[i] )
882 /*-----------------------------------------------------------------*/
883 /* pic16_aopOp - allocates an asmop for an operand : */
884 /*-----------------------------------------------------------------*/
885 void pic16_aopOp (operand *op, iCode *ic, bool result)
894 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
896 /* if this a literal */
897 if (IS_OP_LITERAL(op)) {
898 op->aop = aop = newAsmop(AOP_LIT);
899 aop->aopu.aop_lit = op->operand.valOperand;
900 aop->size = getSize(operandType(op));
905 sym_link *type = operandType(op);
907 if(IS_PTR_CONST(type))
911 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
914 /* if already has a asmop then continue */
918 /* if the underlying symbol has a aop */
919 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
920 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
921 op->aop = OP_SYMBOL(op)->aop;
925 /* if this is a true symbol */
926 if (IS_TRUE_SYMOP(op)) {
927 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
928 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
932 /* this is a temporary : this has
938 e) can be a return use only */
942 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
943 /* if the type is a conditional */
944 if (sym->regType == REG_CND) {
945 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
950 /* if it is spilt then two situations
952 b) has a spill location */
953 if (sym->isspilt || sym->nRegs == 0) {
955 DEBUGpic16_emitcode(";","%d",__LINE__);
956 /* rematerialize it NOW */
959 sym->aop = op->aop = aop =
961 aop->size = getSize(sym->type);
962 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
969 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
970 aop->size = getSize(sym->type);
971 for ( i = 0 ; i < 1 ; i++ ) {
972 aop->aopu.aop_str[i] = accUse[i];
973 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
975 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
976 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
984 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
985 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
986 //pic16_allocDirReg (IC_LEFT(ic));
987 aop->size = getSize(sym->type);
992 aop = op->aop = sym->aop = newAsmop(AOP_STR);
993 aop->size = getSize(sym->type);
994 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
995 aop->aopu.aop_str[i] = fReturn[i];
997 DEBUGpic16_emitcode(";","%d",__LINE__);
1001 /* else spill location */
1002 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1003 /* force a new aop if sizes differ */
1004 sym->usl.spillLoc->aop = NULL;
1006 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1007 __FUNCTION__,__LINE__,
1008 sym->usl.spillLoc->rname,
1009 sym->rname, sym->usl.spillLoc->offset);
1011 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1012 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1013 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1015 sym->usl.spillLoc->offset);
1016 aop->size = getSize(sym->type);
1022 sym_link *type = operandType(op);
1024 if(IS_PTR_CONST(type))
1026 if(IS_CODEPTR(type))
1028 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1031 /* must be in a register */
1032 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1033 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1034 aop->size = sym->nRegs;
1035 for ( i = 0 ; i < sym->nRegs ;i++)
1036 aop->aopu.aop_reg[i] = sym->regs[i];
1039 /*-----------------------------------------------------------------*/
1040 /* pic16_freeAsmop - free up the asmop given to an operand */
1041 /*----------------------------------------------------------------*/
1042 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1059 /* depending on the asmop type only three cases need work AOP_RO
1060 , AOP_R1 && AOP_STK */
1062 switch (aop->type) {
1066 pic16_emitcode ("pop","ar0");
1070 bitVectUnSetBit(ic->rUsed,R0_IDX);
1076 pic16_emitcode ("pop","ar1");
1080 bitVectUnSetBit(ic->rUsed,R1_IDX);
1086 int stk = aop->aopu.aop_stk + aop->size;
1087 bitVectUnSetBit(ic->rUsed,R0_IDX);
1088 bitVectUnSetBit(ic->rUsed,R1_IDX);
1090 getFreePtr(ic,&aop,FALSE);
1092 if (options.stack10bit)
1094 /* I'm not sure what to do here yet... */
1097 "*** Warning: probably generating bad code for "
1098 "10 bit stack mode.\n");
1102 pic16_emitcode ("mov","a,_bp");
1103 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1104 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1106 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1110 pic16_emitcode("pop","acc");
1111 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1113 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1116 pic16_freeAsmop(op,NULL,ic,TRUE);
1118 pic16_emitcode("pop","ar0");
1123 pic16_emitcode("pop","ar1");
1131 /* all other cases just dealloc */
1135 OP_SYMBOL(op)->aop = NULL;
1136 /* if the symbol has a spill */
1138 SPIL_LOC(op)->aop = NULL;
1143 /*-----------------------------------------------------------------*/
1144 /* pic16_aopGet - for fetching value of the aop */
1145 /*-----------------------------------------------------------------*/
1146 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1151 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1153 /* offset is greater than size then zero */
1154 if (offset > (aop->size - 1) &&
1155 aop->type != AOP_LIT)
1158 /* depending on type */
1159 switch (aop->type) {
1163 DEBUGpic16_emitcode(";","%d",__LINE__);
1164 /* if we need to increment it */
1165 while (offset > aop->coff) {
1166 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1170 while (offset < aop->coff) {
1171 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1175 aop->coff = offset ;
1177 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1178 return (dname ? "acc" : "a");
1180 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1181 rs = Safe_calloc(1,strlen(s)+1);
1187 DEBUGpic16_emitcode(";","%d",__LINE__);
1188 if (aop->type == AOP_DPTR2)
1193 while (offset > aop->coff) {
1194 pic16_emitcode ("inc","dptr");
1198 while (offset < aop->coff) {
1199 pic16_emitcode("lcall","__decdptr");
1205 pic16_emitcode("clr","a");
1206 pic16_emitcode("movc","a,@a+dptr");
1209 pic16_emitcode("movx","a,@dptr");
1212 if (aop->type == AOP_DPTR2)
1217 return (dname ? "acc" : "a");
1222 sprintf (s,"%s",aop->aopu.aop_immd);
1225 sprintf(s,"(%s >> %d)",
1230 aop->aopu.aop_immd);
1231 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1232 rs = Safe_calloc(1,strlen(s)+1);
1238 sprintf(s,"(%s + %d)",
1241 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1243 sprintf(s,"%s",aop->aopu.aop_dir);
1244 rs = Safe_calloc(1,strlen(s)+1);
1250 // return aop->aopu.aop_reg[offset]->dname;
1252 return aop->aopu.aop_reg[offset]->name;
1255 //pic16_emitcode(";","%d",__LINE__);
1256 return aop->aopu.aop_dir;
1259 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1260 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1262 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1265 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1266 rs = Safe_calloc(1,strlen(s)+1);
1271 aop->coff = offset ;
1272 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1275 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1277 return aop->aopu.aop_str[offset];
1281 pCodeOp *pcop = aop->aopu.pcop;
1282 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1284 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1285 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1286 sprintf(s,"%s", pcop->name);
1288 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1291 rs = Safe_calloc(1,strlen(s)+1);
1297 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1298 "aopget got unsupported aop->type");
1303 /*-----------------------------------------------------------------*/
1304 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1305 /*-----------------------------------------------------------------*/
1306 pCodeOp *pic16_popGetTempReg(void)
1311 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1316 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1317 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1318 PCOR(pcop)->r->wasUsed=1;
1319 PCOR(pcop)->r->isFree=0;
1321 /* push value on stack */
1322 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1330 /*-----------------------------------------------------------------*/
1331 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1332 /*-----------------------------------------------------------------*/
1333 void pic16_popReleaseTempReg(pCodeOp *pcop)
1335 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1337 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1338 PCOR(pcop)->r->isFree = 1;
1340 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1343 /*-----------------------------------------------------------------*/
1344 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1345 /*-----------------------------------------------------------------*/
1346 pCodeOp *pic16_popGetLabel(unsigned int key)
1349 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1354 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1357 /*-----------------------------------------------------------------*/
1358 /* pic16_popCopyReg - copy a pcode operator */
1359 /*-----------------------------------------------------------------*/
1360 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1364 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1365 pcor->pcop.type = pc->pcop.type;
1367 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1368 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1370 pcor->pcop.name = NULL;
1373 pcor->rIdx = pc->rIdx;
1376 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1381 /*-----------------------------------------------------------------*/
1382 /* pic16_popGetLit - asm operator to pcode operator conversion */
1383 /*-----------------------------------------------------------------*/
1384 pCodeOp *pic16_popGetLit(unsigned int lit)
1386 return pic16_newpCodeOpLit(lit);
1389 /*-----------------------------------------------------------------*/
1390 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1391 /*-----------------------------------------------------------------*/
1392 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1394 return pic16_newpCodeOpLit2(lit, arg2);
1398 /*-----------------------------------------------------------------*/
1399 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1400 /*-----------------------------------------------------------------*/
1401 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1403 return pic16_newpCodeOpImmd(name, offset,index, 0);
1407 /*-----------------------------------------------------------------*/
1408 /* pic16_popGet - asm operator to pcode operator conversion */
1409 /*-----------------------------------------------------------------*/
1410 pCodeOp *pic16_popGetWithString(char *str)
1416 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1420 pcop = pic16_newpCodeOp(str,PO_STR);
1425 /*-----------------------------------------------------------------*/
1426 /* pic16_popRegFromString - */
1427 /*-----------------------------------------------------------------*/
1428 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1431 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1432 pcop->type = PO_DIR;
1434 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1435 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1440 pcop->name = Safe_calloc(1,strlen(str)+1);
1441 strcpy(pcop->name,str);
1443 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1445 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1446 if(PCOR(pcop)->r == NULL) {
1447 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1448 // __FUNCTION__, __LINE__, str, size, offset);
1449 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1451 //fprintf(stderr, "allocating new register -> %s\n", str);
1453 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1455 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1457 PCOR(pcop)->instance = offset;
1462 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1466 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1468 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1469 PCOR(pcop)->rIdx = rIdx;
1470 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1471 PCOR(pcop)->r->isFree = 0;
1472 PCOR(pcop)->r->wasUsed = 1;
1474 pcop->type = PCOR(pcop)->r->pc_type;
1479 /*---------------------------------------------------------------------------------*/
1480 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1482 /*---------------------------------------------------------------------------------*/
1483 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1488 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1490 /* comment the following check, so errors to throw up */
1491 // if(!pcop2)return NULL;
1493 temp = pic16_popGet(aop_dst, offset);
1494 pcop2->pcop2 = temp;
1501 /*--------------------------------------------------------------------------------.-*/
1502 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1503 /* VR 030601 , adapted by Hans Dorn */
1504 /*--------------------------------------------------------------------------------.-*/
1505 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1509 pcop2 = (pCodeOpReg2 *)src;
1517 /*---------------------------------------------------------------------------------*/
1518 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1519 /* movff instruction */
1520 /*---------------------------------------------------------------------------------*/
1521 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1526 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1527 pcop2->pcop2 = pic16_popCopyReg(dst);
1529 /* the pCodeOp may be already allocated */
1530 pcop2 = (pCodeOpReg2 *)(src);
1531 pcop2->pcop2 = (pCodeOp *)(dst);
1538 /*-----------------------------------------------------------------*/
1539 /* pic16_popGet - asm operator to pcode operator conversion */
1540 /*-----------------------------------------------------------------*/
1541 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1543 //char *s = buffer ;
1547 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1548 /* offset is greater than
1551 // if (offset > (aop->size - 1) &&
1552 // aop->type != AOP_LIT)
1553 // return NULL; //zero;
1555 /* depending on type */
1556 switch (aop->type) {
1562 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1563 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1570 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1571 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1575 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1577 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1579 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1581 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1582 PCOR(pcop)->rIdx = rIdx;
1583 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1584 PCOR(pcop)->r->wasUsed=1;
1585 PCOR(pcop)->r->isFree=0;
1587 PCOR(pcop)->instance = offset;
1588 pcop->type = PCOR(pcop)->r->pc_type;
1589 // rs = aop->aopu.aop_reg[offset]->name;
1590 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1594 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1595 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1601 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1602 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1606 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1608 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1610 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1611 PCOR(pcop)->rIdx = rIdx;
1612 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1613 PCOR(pcop)->r->wasUsed=1;
1614 PCOR(pcop)->r->isFree=0;
1616 PCOR(pcop)->instance = offset;
1617 pcop->type = PCOR(pcop)->r->pc_type;
1618 rs = aop->aopu.aop_reg[offset]->name;
1619 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1624 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1626 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1627 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1628 //if(PCOR(pcop)->r == NULL)
1629 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1633 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1634 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1637 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1638 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1641 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1642 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1643 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1644 pcop->type = PCOR(pcop)->r->pc_type;
1645 pcop->name = PCOR(pcop)->r->name;
1651 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1653 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1654 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1656 switch( aop->aopu.pcop->type ) {
1657 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1658 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1660 assert( 0 ); /* should never reach here */;
1663 PCOI(pcop)->offset = offset;
1668 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1669 "pic16_popGet got unsupported aop->type");
1672 /*-----------------------------------------------------------------*/
1673 /* pic16_aopPut - puts a string for a aop */
1674 /*-----------------------------------------------------------------*/
1675 void pic16_aopPut (asmop *aop, char *s, int offset)
1680 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1682 if (aop->size && offset > ( aop->size - 1)) {
1683 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1684 "pic16_aopPut got offset > aop->size");
1688 /* will assign value to value */
1689 /* depending on where it is ofcourse */
1690 switch (aop->type) {
1693 sprintf(d,"(%s + %d)",
1694 aop->aopu.aop_dir,offset);
1695 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1698 sprintf(d,"%s",aop->aopu.aop_dir);
1701 DEBUGpic16_emitcode(";","%d",__LINE__);
1703 pic16_emitcode("movf","%s,w",s);
1704 pic16_emitcode("movwf","%s",d);
1707 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1708 if(offset >= aop->size) {
1709 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1712 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1715 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1722 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1723 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1726 strcmp(s,"r0") == 0 ||
1727 strcmp(s,"r1") == 0 ||
1728 strcmp(s,"r2") == 0 ||
1729 strcmp(s,"r3") == 0 ||
1730 strcmp(s,"r4") == 0 ||
1731 strcmp(s,"r5") == 0 ||
1732 strcmp(s,"r6") == 0 ||
1733 strcmp(s,"r7") == 0 )
1734 pic16_emitcode("mov","%s,%s ; %d",
1735 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1739 if(strcmp(s,"W")==0 )
1740 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1742 pic16_emitcode("movwf","%s",
1743 aop->aopu.aop_reg[offset]->name);
1745 if(strcmp(s,zero)==0) {
1746 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1748 } else if(strcmp(s,"W")==0) {
1749 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1750 pcop->type = PO_GPR_REGISTER;
1752 PCOR(pcop)->rIdx = -1;
1753 PCOR(pcop)->r = NULL;
1755 DEBUGpic16_emitcode(";","%d",__LINE__);
1756 pcop->name = Safe_strdup(s);
1757 pic16_emitpcode(POC_MOVFW,pcop);
1758 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1759 } else if(strcmp(s,one)==0) {
1760 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1761 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1763 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1771 if (aop->type == AOP_DPTR2)
1777 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1778 "pic16_aopPut writting to code space");
1782 while (offset > aop->coff) {
1784 pic16_emitcode ("inc","dptr");
1787 while (offset < aop->coff) {
1789 pic16_emitcode("lcall","__decdptr");
1794 /* if not in accumulater */
1797 pic16_emitcode ("movx","@dptr,a");
1799 if (aop->type == AOP_DPTR2)
1807 while (offset > aop->coff) {
1809 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1811 while (offset < aop->coff) {
1813 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1819 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1824 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1826 if (strcmp(s,"r0") == 0 ||
1827 strcmp(s,"r1") == 0 ||
1828 strcmp(s,"r2") == 0 ||
1829 strcmp(s,"r3") == 0 ||
1830 strcmp(s,"r4") == 0 ||
1831 strcmp(s,"r5") == 0 ||
1832 strcmp(s,"r6") == 0 ||
1833 strcmp(s,"r7") == 0 ) {
1835 sprintf(buffer,"a%s",s);
1836 pic16_emitcode("mov","@%s,%s",
1837 aop->aopu.aop_ptr->name,buffer);
1839 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1844 if (strcmp(s,"a") == 0)
1845 pic16_emitcode("push","acc");
1847 pic16_emitcode("push","%s",s);
1852 /* if bit variable */
1853 if (!aop->aopu.aop_dir) {
1854 pic16_emitcode("clr","a");
1855 pic16_emitcode("rlc","a");
1858 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1861 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1864 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1866 lbl = newiTempLabel(NULL);
1868 if (strcmp(s,"a")) {
1871 pic16_emitcode("clr","c");
1872 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1873 pic16_emitcode("cpl","c");
1874 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1875 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1882 if (strcmp(aop->aopu.aop_str[offset],s))
1883 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1888 if (!offset && (strcmp(s,"acc") == 0))
1891 if (strcmp(aop->aopu.aop_str[offset],s))
1892 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1896 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1897 "pic16_aopPut got unsupported aop->type");
1903 /*-----------------------------------------------------------------*/
1904 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1905 /*-----------------------------------------------------------------*/
1906 static void mov2w (asmop *aop, int offset)
1912 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1914 if ( aop->type == AOP_PCODE ||
1915 aop->type == AOP_LIT )
1916 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1918 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1923 /* push pcop into stack */
1924 void pic16_pushpCodeOp(pCodeOp *pcop)
1926 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1927 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1930 /* pop pcop from stack */
1931 void pic16_poppCodeOp(pCodeOp *pcop)
1933 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1937 /*-----------------------------------------------------------------*/
1938 /* pushw - pushes wreg to stack */
1939 /*-----------------------------------------------------------------*/
1942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1943 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1947 /*-----------------------------------------------------------------*/
1948 /* pushaop - pushes aop to stack */
1949 /*-----------------------------------------------------------------*/
1950 void pushaop(asmop *aop, int offset)
1952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1953 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1956 /*-----------------------------------------------------------------*/
1957 /* popaop - pops aop from stack */
1958 /*-----------------------------------------------------------------*/
1959 void popaop(asmop *aop, int offset)
1961 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1962 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1965 void popaopidx(asmop *aop, int offset, int index)
1969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 if(STACK_MODEL_LARGE)ofs++;
1973 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1974 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1977 /*-----------------------------------------------------------------*/
1978 /* reAdjustPreg - points a register back to where it should */
1979 /*-----------------------------------------------------------------*/
1980 static void reAdjustPreg (asmop *aop)
1984 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1986 if ((size = aop->size) <= 1)
1989 switch (aop->type) {
1993 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1997 if (aop->type == AOP_DPTR2)
2003 pic16_emitcode("lcall","__decdptr");
2006 if (aop->type == AOP_DPTR2)
2018 /*-----------------------------------------------------------------*/
2019 /* opIsGptr: returns non-zero if the passed operand is */
2020 /* a generic pointer type. */
2021 /*-----------------------------------------------------------------*/
2022 static int opIsGptr(operand *op)
2024 sym_link *type = operandType(op);
2026 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2027 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2035 /*-----------------------------------------------------------------*/
2036 /* pic16_getDataSize - get the operand data size */
2037 /*-----------------------------------------------------------------*/
2038 int pic16_getDataSize(operand *op)
2040 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2043 return AOP_SIZE(op);
2045 // tsd- in the pic port, the genptr size is 1, so this code here
2046 // fails. ( in the 8051 port, the size was 4).
2049 size = AOP_SIZE(op);
2050 if (size == GPTRSIZE)
2052 sym_link *type = operandType(op);
2053 if (IS_GENPTR(type))
2055 /* generic pointer; arithmetic operations
2056 * should ignore the high byte (pointer type).
2059 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2066 /*-----------------------------------------------------------------*/
2067 /* pic16_outAcc - output Acc */
2068 /*-----------------------------------------------------------------*/
2069 void pic16_outAcc(operand *result)
2072 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2073 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2076 size = pic16_getDataSize(result);
2078 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2081 /* unsigned or positive */
2083 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2088 /*-----------------------------------------------------------------*/
2089 /* pic16_outBitC - output a bit C */
2090 /* Move to result the value of Carry flag -- VR */
2091 /*-----------------------------------------------------------------*/
2092 void pic16_outBitC(operand *result)
2096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2097 /* if the result is bit */
2098 if (AOP_TYPE(result) == AOP_CRY) {
2099 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2100 pic16_aopPut(AOP(result),"c",0);
2103 i = AOP_SIZE(result);
2105 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2107 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2110 pic16_emitcode("clr","a ; %d", __LINE__);
2111 pic16_emitcode("rlc","a");
2112 pic16_outAcc(result);
2117 /*-----------------------------------------------------------------*/
2118 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2119 /*-----------------------------------------------------------------*/
2120 void pic16_toBoolean(operand *oper)
2122 int size = AOP_SIZE(oper) - 1;
2125 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2127 if ( AOP_TYPE(oper) != AOP_ACC) {
2128 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2131 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2136 #if !defined(GEN_Not)
2137 /*-----------------------------------------------------------------*/
2138 /* genNot - generate code for ! operation */
2139 /*-----------------------------------------------------------------*/
2140 static void pic16_genNot (iCode *ic)
2145 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2146 /* assign asmOps to operand & result */
2147 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2148 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2150 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2151 /* if in bit space then a special case */
2152 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2153 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2154 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2155 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2157 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2158 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2159 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2164 size = AOP_SIZE(IC_LEFT(ic));
2166 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2167 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2168 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2171 pic16_toBoolean(IC_LEFT(ic));
2173 tlbl = newiTempLabel(NULL);
2174 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2175 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2176 pic16_outBitC(IC_RESULT(ic));
2179 /* release the aops */
2180 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2181 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2186 #if !defined(GEN_Cpl)
2187 /*-----------------------------------------------------------------*/
2188 /* genCpl - generate code for complement */
2189 /*-----------------------------------------------------------------*/
2190 static void pic16_genCpl (iCode *ic)
2196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2197 /* assign asmOps to operand & result */
2198 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2199 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2201 /* if both are in bit space then
2203 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2204 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2206 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2207 pic16_emitcode("cpl","c");
2208 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2212 size = AOP_SIZE(IC_RESULT(ic));
2215 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2217 pic16_emitcode("cpl","a");
2218 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2220 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2221 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2223 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2224 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2232 /* release the aops */
2233 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2234 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2238 /*-----------------------------------------------------------------*/
2239 /* genUminusFloat - unary minus for floating points */
2240 /*-----------------------------------------------------------------*/
2241 static void genUminusFloat(operand *op,operand *result)
2243 int size ,offset =0 ;
2246 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2247 /* for this we just need to flip the
2248 first it then copy the rest in place */
2249 size = AOP_SIZE(op) - 1;
2250 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2254 pic16_emitcode("cpl","acc.7");
2255 pic16_aopPut(AOP(result),"a",3);
2258 pic16_aopPut(AOP(result),
2259 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2265 /*-----------------------------------------------------------------*/
2266 /* genUminus - unary minus code generation */
2267 /*-----------------------------------------------------------------*/
2268 static void genUminus (iCode *ic)
2271 sym_link *optype, *rtype;
2273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2276 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2277 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2279 /* if both in bit space then special case */
2280 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2281 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2283 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2284 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2285 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2290 optype = operandType(IC_LEFT(ic));
2291 rtype = operandType(IC_RESULT(ic));
2293 /* if float then do float stuff */
2294 if (IS_FLOAT(optype)) {
2295 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2299 /* otherwise subtract from zero by taking the 2's complement */
2300 size = AOP_SIZE(IC_LEFT(ic));
2302 for(i=0; i<size; i++) {
2303 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2304 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2306 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2307 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2311 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2312 for(i=1; i<size; i++) {
2314 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2318 /* release the aops */
2319 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2320 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2323 /*-----------------------------------------------------------------*/
2324 /* saveRegisters - will look for a call and save the registers */
2325 /*-----------------------------------------------------------------*/
2326 static void saveRegisters(iCode *lic)
2333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2335 for (ic = lic ; ic ; ic = ic->next)
2336 if (ic->op == CALL || ic->op == PCALL)
2340 fprintf(stderr,"found parameter push with no function call\n");
2344 /* if the registers have been saved already then
2346 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2349 /* find the registers in use at this time
2350 and push them away to safety */
2351 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2355 if (options.useXstack) {
2356 if (bitVectBitValue(rsave,R0_IDX))
2357 pic16_emitcode("mov","b,r0");
2358 pic16_emitcode("mov","r0,%s",spname);
2359 for (i = 0 ; i < pic16_nRegs ; i++) {
2360 if (bitVectBitValue(rsave,i)) {
2362 pic16_emitcode("mov","a,b");
2364 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2365 pic16_emitcode("movx","@r0,a");
2366 pic16_emitcode("inc","r0");
2369 pic16_emitcode("mov","%s,r0",spname);
2370 if (bitVectBitValue(rsave,R0_IDX))
2371 pic16_emitcode("mov","r0,b");
2373 //for (i = 0 ; i < pic16_nRegs ; i++) {
2374 // if (bitVectBitValue(rsave,i))
2375 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2378 dtype = operandType(IC_LEFT(ic));
2379 if (currFunc && dtype &&
2380 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2381 IFFUNC_ISISR(currFunc->type) &&
2384 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2387 /*-----------------------------------------------------------------*/
2388 /* unsaveRegisters - pop the pushed registers */
2389 /*-----------------------------------------------------------------*/
2390 static void unsaveRegisters (iCode *ic)
2395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2396 /* find the registers in use at this time
2397 and push them away to safety */
2398 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2401 if (options.useXstack) {
2402 pic16_emitcode("mov","r0,%s",spname);
2403 for (i = pic16_nRegs ; i >= 0 ; i--) {
2404 if (bitVectBitValue(rsave,i)) {
2405 pic16_emitcode("dec","r0");
2406 pic16_emitcode("movx","a,@r0");
2408 pic16_emitcode("mov","b,a");
2410 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2414 pic16_emitcode("mov","%s,r0",spname);
2415 if (bitVectBitValue(rsave,R0_IDX))
2416 pic16_emitcode("mov","r0,b");
2418 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2419 // if (bitVectBitValue(rsave,i))
2420 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2426 /*-----------------------------------------------------------------*/
2428 /*-----------------------------------------------------------------*/
2429 static void pushSide(operand * oper, int size)
2432 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2434 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2435 if (AOP_TYPE(oper) != AOP_REG &&
2436 AOP_TYPE(oper) != AOP_DIR &&
2438 pic16_emitcode("mov","a,%s",l);
2439 pic16_emitcode("push","acc");
2441 pic16_emitcode("push","%s",l);
2446 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2448 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2450 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2451 pic16_emitpcode(POC_MOVFW, src);
2452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2454 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2455 src, pic16_popGet(AOP(op), offset)));
2460 /*-----------------------------------------------------------------*/
2461 /* assignResultValue - assign results to oper, rescall==1 is */
2462 /* called from genCall() or genPCall() */
2463 /*-----------------------------------------------------------------*/
2464 static void assignResultValue(operand * oper, int rescall)
2466 int size = AOP_SIZE(oper);
2468 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2469 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2472 /* assign result from a call/pcall function() */
2474 /* function results are stored in a special order,
2475 * see top of file with Function return policy, or manual */
2478 /* 8-bits, result in WREG */
2479 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2482 /* 16-bits, result in PRODL:WREG */
2483 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2487 /* 24-bits, result in PRODH:PRODL:WREG */
2488 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2492 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2493 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2496 /* >32-bits, result on stack, and FSR0 points to beginning.
2497 * Fix stack when done */
2500 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2501 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2503 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2508 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2509 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2510 if(STACK_MODEL_LARGE) {
2512 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2516 if(!GpsuedoStkPtr) {
2517 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2518 /* The last byte in the assignment is in W */
2520 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2525 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2526 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2528 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2534 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2536 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2546 /*-----------------------------------------------------------------*/
2547 /* genIpush - genrate code for pushing this gets a little complex */
2548 /*-----------------------------------------------------------------*/
2549 static void genIpush (iCode *ic)
2552 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2554 int size, offset = 0 ;
2558 /* if this is not a parm push : ie. it is spill push
2559 and spill push is always done on the local stack */
2560 if (!ic->parmPush) {
2562 /* and the item is spilt then do nothing */
2563 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2566 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2567 size = AOP_SIZE(IC_LEFT(ic));
2568 /* push it on the stack */
2570 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2575 pic16_emitcode("push","%s",l);
2580 /* this is a paramter push: in this case we call
2581 the routine to find the call and save those
2582 registers that need to be saved */
2585 /* then do the push */
2586 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2589 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2590 size = AOP_SIZE(IC_LEFT(ic));
2593 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2594 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2595 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2597 pic16_emitcode("mov","a,%s",l);
2598 pic16_emitcode("push","acc");
2600 pic16_emitcode("push","%s",l);
2603 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2607 /*-----------------------------------------------------------------*/
2608 /* genIpop - recover the registers: can happen only for spilling */
2609 /*-----------------------------------------------------------------*/
2610 static void genIpop (iCode *ic)
2612 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2617 /* if the temp was not pushed then */
2618 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2621 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2622 size = AOP_SIZE(IC_LEFT(ic));
2625 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2628 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2632 /*-----------------------------------------------------------------*/
2633 /* unsaverbank - restores the resgister bank from stack */
2634 /*-----------------------------------------------------------------*/
2635 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2637 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2645 if (options.useXstack) {
2647 r = getFreePtr(ic,&aop,FALSE);
2650 pic16_emitcode("mov","%s,_spx",r->name);
2651 pic16_emitcode("movx","a,@%s",r->name);
2652 pic16_emitcode("mov","psw,a");
2653 pic16_emitcode("dec","%s",r->name);
2656 pic16_emitcode ("pop","psw");
2659 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2660 if (options.useXstack) {
2661 pic16_emitcode("movx","a,@%s",r->name);
2662 //pic16_emitcode("mov","(%s+%d),a",
2663 // regspic16[i].base,8*bank+regspic16[i].offset);
2664 pic16_emitcode("dec","%s",r->name);
2667 pic16_emitcode("pop",""); //"(%s+%d)",
2668 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2671 if (options.useXstack) {
2673 pic16_emitcode("mov","_spx,%s",r->name);
2674 pic16_freeAsmop(NULL,aop,ic,TRUE);
2680 /*-----------------------------------------------------------------*/
2681 /* saverbank - saves an entire register bank on the stack */
2682 /*-----------------------------------------------------------------*/
2683 static void saverbank (int bank, iCode *ic, bool pushPsw)
2685 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2691 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2692 if (options.useXstack) {
2695 r = getFreePtr(ic,&aop,FALSE);
2696 pic16_emitcode("mov","%s,_spx",r->name);
2700 for (i = 0 ; i < pic16_nRegs ;i++) {
2701 if (options.useXstack) {
2702 pic16_emitcode("inc","%s",r->name);
2703 //pic16_emitcode("mov","a,(%s+%d)",
2704 // regspic16[i].base,8*bank+regspic16[i].offset);
2705 pic16_emitcode("movx","@%s,a",r->name);
2707 pic16_emitcode("push","");// "(%s+%d)",
2708 //regspic16[i].base,8*bank+regspic16[i].offset);
2712 if (options.useXstack) {
2713 pic16_emitcode("mov","a,psw");
2714 pic16_emitcode("movx","@%s,a",r->name);
2715 pic16_emitcode("inc","%s",r->name);
2716 pic16_emitcode("mov","_spx,%s",r->name);
2717 pic16_freeAsmop (NULL,aop,ic,TRUE);
2720 pic16_emitcode("push","psw");
2722 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2730 /*-----------------------------------------------------------------*/
2731 /* genCall - generates a call statement */
2732 /*-----------------------------------------------------------------*/
2733 static void genCall (iCode *ic)
2738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2740 /* if caller saves & we have not saved then */
2744 /* if we are calling a function that is not using
2745 * the same register bank then we need to save the
2746 * destination registers on the stack */
2747 dtype = operandType(IC_LEFT(ic));
2748 if (currFunc && dtype &&
2749 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2750 IFFUNC_ISISR(currFunc->type) &&
2753 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2755 /* if send set is not empty the assign */
2759 /* For the Pic port, there is no data stack.
2760 * So parameters passed to functions are stored
2761 * in registers. (The pCode optimizer will get
2762 * rid of most of these :). */
2764 int psuedoStkPtr=-1;
2765 int firstTimeThruLoop = 1;
2767 _G.sendSet = reverseSet(_G.sendSet);
2769 /* First figure how many parameters are getting passed */
2770 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2771 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2772 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2773 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2776 stackParms = psuedoStkPtr;
2778 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2779 int size, offset = 0;
2781 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2782 size = AOP_SIZE(IC_LEFT(sic));
2785 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2786 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2787 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2789 if(!firstTimeThruLoop) {
2790 /* If this is not the first time we've been through the loop
2791 * then we need to save the parameter in a temporary
2792 * register. The last byte of the last parameter is
2796 --psuedoStkPtr; // sanity check
2799 firstTimeThruLoop=0;
2801 mov2w (AOP(IC_LEFT(sic)), offset);
2804 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2810 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2811 OP_SYMBOL(IC_LEFT(ic))->rname :
2812 OP_SYMBOL(IC_LEFT(ic))->name));
2815 /* if we need assign a result value */
2816 if ((IS_ITEMP(IC_RESULT(ic)) &&
2817 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2818 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2819 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2822 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2825 assignResultValue(IC_RESULT(ic), 1);
2827 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2828 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2830 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2834 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2835 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2836 if(STACK_MODEL_LARGE) {
2838 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2842 /* adjust the stack for parameters if required */
2843 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2845 if (ic->parmBytes) {
2848 if (ic->parmBytes > 3) {
2849 pic16_emitcode("mov","a,%s",spname);
2850 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2851 pic16_emitcode("mov","%s,a",spname);
2853 for ( i = 0 ; i < ic->parmBytes ;i++)
2854 pic16_emitcode("dec","%s",spname);
2858 /* if register bank was saved then pop them */
2860 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2862 /* if we hade saved some registers then unsave them */
2863 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2864 unsaveRegisters (ic);
2870 /*-----------------------------------------------------------------*/ // patch 14
2871 /* genPcall - generates a call by pointer statement */
2872 /*-----------------------------------------------------------------*/
2874 // new version, created from genCall
2876 static void genPcall (iCode *ic)
2880 symbol *retlbl = newiTempLabel(NULL);
2881 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
2883 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2885 /* if caller saves & we have not saved then */
2889 /* if we are calling a function that is not using
2890 * the same register bank then we need to save the
2891 * destination registers on the stack */
2892 dtype = operandType(IC_LEFT(ic));
2893 if (currFunc && dtype &&
2894 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2895 IFFUNC_ISISR(currFunc->type) &&
2898 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2900 /* if send set is not empty the assign */
2904 /* For the Pic port, there is no data stack.
2905 * So parameters passed to functions are stored
2906 * in registers. (The pCode optimizer will get
2907 * rid of most of these :). */
2909 int psuedoStkPtr=-1;
2910 int firstTimeThruLoop = 1;
2912 _G.sendSet = reverseSet(_G.sendSet);
2914 /* First figure how many parameters are getting passed */
2915 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2916 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2917 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2918 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2921 stackParms = psuedoStkPtr;
2923 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2924 int size, offset = 0;
2926 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2927 size = AOP_SIZE(IC_LEFT(sic));
2930 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2931 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2932 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2934 if(!firstTimeThruLoop) {
2935 /* If this is not the first time we've been through the loop
2936 * then we need to save the parameter in a temporary
2937 * register. The last byte of the last parameter is
2941 --psuedoStkPtr; // sanity check
2944 firstTimeThruLoop=0;
2946 mov2w (AOP(IC_LEFT(sic)), offset);
2949 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2954 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2956 // push return address
2957 // push $ on return stack, then replace with retlbl
2959 // Note: retlbl is supplied as dummy operand to PUSH
2960 // This has the nice side effect of keeping the label from being optimized out :o)
2961 pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
2963 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
2964 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
2965 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
2966 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
2967 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
2968 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
2970 /* make the call by writing the pointer into pc */
2971 // FIXME Disabled writes to PCLATU because of gpsim problems
2973 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
2976 "WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
2977 Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
2980 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
2981 // note: MOVFF to PCL not allowed
2982 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
2983 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
2985 /* return address is here: (X) */
2986 pic16_emitpLabel(retlbl->key);
2988 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2991 /* if we need assign a result value */
2992 if ((IS_ITEMP(IC_RESULT(ic)) &&
2993 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2994 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2995 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2998 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3001 assignResultValue(IC_RESULT(ic), 1);
3003 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3004 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3006 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3010 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3011 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3012 if(STACK_MODEL_LARGE) {
3014 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3018 /* adjust the stack for parameters if required */
3019 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3021 if (ic->parmBytes) {
3024 if (ic->parmBytes > 3) {
3025 pic16_emitcode("mov","a,%s",spname);
3026 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3027 pic16_emitcode("mov","%s,a",spname);
3029 for ( i = 0 ; i < ic->parmBytes ;i++)
3030 pic16_emitcode("dec","%s",spname);
3033 /* if register bank was saved then pop them */
3035 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3037 /* if we hade saved some registers then unsave them */
3038 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3039 unsaveRegisters (ic);
3044 // old version, kept for reference
3046 /*-----------------------------------------------------------------*/
3047 /* genPcall - generates a call by pointer statement */
3048 /*-----------------------------------------------------------------*/
3049 static void genPcall (iCode *ic)
3052 symbol *rlbl = newiTempLabel(NULL);
3055 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3056 /* if caller saves & we have not saved then */
3060 /* if we are calling a function that is not using
3061 the same register bank then we need to save the
3062 destination registers on the stack */
3063 dtype = operandType(IC_LEFT(ic));
3064 if (currFunc && dtype &&
3065 IFFUNC_ISISR(currFunc->type) &&
3066 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3067 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3070 /* push the return address on to the stack */
3071 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3072 pic16_emitcode("push","acc");
3073 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3074 pic16_emitcode("push","acc");
3076 if (options.model == MODEL_FLAT24)
3078 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3079 pic16_emitcode("push","acc");
3082 /* now push the calling address */
3083 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3085 pushSide(IC_LEFT(ic), FPTRSIZE);
3087 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3089 /* if send set is not empty the assign */
3093 for (sic = setFirstItem(_G.sendSet) ; sic ;
3094 sic = setNextItem(_G.sendSet)) {
3095 int size, offset = 0;
3096 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3097 size = AOP_SIZE(IC_LEFT(sic));
3099 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3101 if (strcmp(l,fReturn[offset]))
3102 pic16_emitcode("mov","%s,%s",
3107 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3112 pic16_emitcode("ret","");
3113 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3116 /* if we need assign a result value */
3117 if ((IS_ITEMP(IC_RESULT(ic)) &&
3118 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3119 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3120 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3123 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3126 assignResultValue(IC_RESULT(ic), 1);
3128 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3131 /* adjust the stack for parameters if
3133 if (ic->parmBytes) {
3135 if (ic->parmBytes > 3) {
3136 pic16_emitcode("mov","a,%s",spname);
3137 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3138 pic16_emitcode("mov","%s,a",spname);
3140 for ( i = 0 ; i < ic->parmBytes ;i++)
3141 pic16_emitcode("dec","%s",spname);
3145 /* if register bank was saved then unsave them */
3146 if (currFunc && dtype &&
3147 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3148 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3150 /* if we hade saved some registers then
3153 unsaveRegisters (ic);
3159 /*-----------------------------------------------------------------*/
3160 /* resultRemat - result is rematerializable */
3161 /*-----------------------------------------------------------------*/
3162 static int resultRemat (iCode *ic)
3164 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3165 if (SKIP_IC(ic) || ic->op == IFX)
3168 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3169 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3170 if (sym->remat && !POINTER_SET(ic))
3177 #if defined(__BORLANDC__) || defined(_MSC_VER)
3178 #define STRCASECMP stricmp
3180 #define STRCASECMP strcasecmp
3184 /*-----------------------------------------------------------------*/
3185 /* inExcludeList - return 1 if the string is in exclude Reg list */
3186 /*-----------------------------------------------------------------*/
3187 static bool inExcludeList(char *s)
3189 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3193 if (options.excludeRegs[i] &&
3194 STRCASECMP(options.excludeRegs[i],"none") == 0)
3197 for ( i = 0 ; options.excludeRegs[i]; i++) {
3198 if (options.excludeRegs[i] &&
3199 STRCASECMP(s,options.excludeRegs[i]) == 0)
3206 /*-----------------------------------------------------------------*/
3207 /* genFunction - generated code for function entry */
3208 /*-----------------------------------------------------------------*/
3209 static void genFunction (iCode *ic)
3214 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
3216 labelOffset += (max_key+4);
3221 ftype = operandType(IC_LEFT(ic));
3222 sym = OP_SYMBOL(IC_LEFT(ic));
3224 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3225 /* create an absolute section at the interrupt vector:
3226 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3234 sym = OP_SYMBOL( IC_LEFT(ic));
3236 if(interrupts[i]->name
3237 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3244 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3245 __FILE__, __LINE__, sym->name);
3248 _G.interruptvector = found;
3251 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3252 asym = newSymbol(asymname, 0);
3254 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3255 pic16_addpBlock( apb );
3257 pic16_addpCode2pBlock(apb,
3258 pic16_newpCodeCharP(";-----------------------------------------"));
3261 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3263 pic16_addpCode2pBlock(apb,
3264 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3266 /* mark the end of this tiny function */
3267 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3272 abSym = Safe_calloc(1, sizeof(absSym));
3273 abSym->name = Safe_strdup( asymname );
3275 switch( _G.interruptvector ) {
3276 case 0: abSym->address = 0x000000; break;
3277 case 1: abSym->address = 0x000008; break;
3278 case 2: abSym->address = 0x000018; break;
3281 addSet(&absSymSet, abSym);
3286 /* create the function header */
3287 pic16_emitcode(";","-----------------------------------------");
3288 pic16_emitcode(";"," function %s",sym->name);
3289 pic16_emitcode(";","-----------------------------------------");
3291 pic16_emitcode("","%s:",sym->rname);
3292 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3298 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3299 if(!strcmp(ab->name, sym->name)) {
3300 pic16_pBlockConvert2Absolute(pb);
3307 if(IFFUNC_ISNAKED(ftype)) {
3308 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3312 /* if critical function then turn interrupts off */
3313 if (IFFUNC_ISCRITICAL(ftype))
3314 pic16_emitcode("clr","ea");
3316 /* if this is an interrupt service routine then
3317 * save acc, b, dpl, dph */
3318 if (IFFUNC_ISISR(sym->type)) {
3320 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3321 if(!(_G.interruptvector == 1)) {
3323 /* do not save WREG,STATUS,BSR for high priority interrupts
3324 * because they are stored in the hardware shadow registers already */
3326 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3327 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3328 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3331 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3332 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3333 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3334 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3336 // pic16_pBlockConvert2ISR(pb);
3338 /* if any registers used */
3339 if (sym->regsUsed) {
3340 /* save the registers used */
3341 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3342 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3343 if (bitVectBitValue(sym->regsUsed,i)) {
3344 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3345 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3346 // pic16_regWithIdx(i)->name);
3348 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3354 /* emit code to setup stack frame if user enabled,
3355 * and function is not main() */
3357 // fprintf(stderr, "function name: %s\n", sym->name);
3358 if(strcmp(sym->name, "main")) {
3359 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3360 /* setup the stack frame */
3361 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3362 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3363 if(STACK_MODEL_LARGE)
3364 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3368 /* if callee-save to be used for this function
3369 * then save the registers being used in this function */
3370 // if (IFFUNC_CALLEESAVES(sym->type))
3374 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3376 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3378 /* if any registers used */
3379 if (sym->regsUsed) {
3380 /* save the registers used */
3381 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3382 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3383 if (bitVectBitValue(sym->regsUsed,i)) {
3385 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3386 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3387 // pic16_regWithIdx(i)->name);
3389 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3391 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3392 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3393 // &pic16_pc_postdec1, 0));
3405 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3407 if (options.useXstack) {
3408 pic16_emitcode("mov","r0,%s",spname);
3409 pic16_emitcode("mov","a,_bp");
3410 pic16_emitcode("movx","@r0,a");
3411 pic16_emitcode("inc","%s",spname);
3413 /* set up the stack */
3414 pic16_emitcode ("push","_bp"); /* save the callers stack */
3416 pic16_emitcode ("mov","_bp,%s",spname);
3419 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3421 /* adjust the stack for the function */
3426 werror(W_STACK_OVERFLOW,sym->name);
3428 if (i > 3 && sym->recvSize < 4) {
3429 pic16_emitcode ("mov","a,sp");
3430 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3431 pic16_emitcode ("mov","sp,a");
3434 pic16_emitcode("inc","sp");
3438 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3440 pic16_emitcode ("mov","a,_spx");
3441 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3442 pic16_emitcode ("mov","_spx,a");
3447 /*-----------------------------------------------------------------*/
3448 /* genEndFunction - generates epilogue for functions */
3449 /*-----------------------------------------------------------------*/
3450 static void genEndFunction (iCode *ic)
3452 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3456 if(IFFUNC_ISNAKED(sym->type)) {
3457 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3462 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3464 pic16_emitcode ("mov","%s,_bp",spname);
3468 /* if use external stack but some variables were
3469 added to the local stack then decrement the
3471 if (options.useXstack && sym->stack) {
3472 pic16_emitcode("mov","a,sp");
3473 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3474 pic16_emitcode("mov","sp,a");
3479 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3480 if (options.useXstack) {
3481 pic16_emitcode("mov","r0,%s",spname);
3482 pic16_emitcode("movx","a,@r0");
3483 pic16_emitcode("mov","_bp,a");
3484 pic16_emitcode("dec","%s",spname);
3488 pic16_emitcode ("pop","_bp");
3493 if (IFFUNC_ISISR(sym->type)) {
3494 /* now we need to restore the registers */
3495 /* if any registers used */
3496 if (sym->regsUsed) {
3499 /* restore registers used */
3500 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3501 for ( i = sym->regsUsed->size; i >= 0; i--) {
3502 if (bitVectBitValue(sym->regsUsed,i)) {
3504 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3505 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3506 // pic16_regWithIdx(i)->name);
3508 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3510 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3511 // &pic16_pc_preinc1,
3512 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3518 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3519 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3520 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3521 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3523 if(!(_G.interruptvector == 1)) {
3524 /* do not restore interrupt vector for WREG,STATUS,BSR
3525 * for high priority interrupt, see genFunction */
3527 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3528 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3529 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3532 _G.interruptvector = 0; /* sanity check */
3534 // pic16_pBlockConvert2ISR(pb);
3537 /* if debug then send end of function */
3538 /* if (options.debug && currFunc) */
3540 debugFile->writeEndFunction (currFunc, ic, 1);
3543 pic16_emitpcodeNULLop(POC_RETFIE);
3545 if (IFFUNC_ISCRITICAL(sym->type))
3546 pic16_emitcode("setb","ea");
3549 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3551 /* if any registers used */
3552 if (sym->regsUsed) {
3554 /* save the registers used */
3555 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3556 for ( i = sym->regsUsed->size; i >= 0; i--) {
3557 if (bitVectBitValue(sym->regsUsed,i)) {
3559 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3560 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3561 // pic16_regWithIdx(i)->name);
3563 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3565 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3566 // &pic16_pc_preinc1,
3567 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3574 pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3575 /* if debug then send end of function */
3577 debugFile->writeEndFunction (currFunc, ic, 1);
3580 /* insert code to restore stack frame, if user enabled it
3581 * and function is not main() */
3584 if(strcmp(sym->name, "main")) {
3585 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3586 /* restore stack frame */
3587 if(STACK_MODEL_LARGE)
3588 pic16_emitpcode(POC_MOVFF,
3589 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3590 pic16_emitpcode(POC_MOVFF,
3591 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3595 pic16_emitcode ("return","");
3596 pic16_emitpcodeNULLop(POC_RETURN);
3598 /* Mark the end of a function */
3599 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3605 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3609 // if((AOP(op)->aopu.pcop->type == PO_IMMEDIATE)
3610 // || (AOP(op)->aopu.pcop->type == PO_LITERAL))
3612 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3614 if(dest->type != PO_WREG)
3615 pic16_emitpcode(POC_MOVWF, dest);
3617 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3618 pic16_popGet(AOP(op), offset), dest));
3622 /*-----------------------------------------------------------------*/
3623 /* genRet - generate code for return statement */
3624 /*-----------------------------------------------------------------*/
3625 static void genRet (iCode *ic)
3630 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3631 /* if we have no return value then
3632 * just generate the "ret" */
3637 /* we have something to return then
3638 * move the return value into place */
3639 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3640 size = AOP_SIZE(IC_LEFT(ic));
3644 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3645 // pic16_emitpcode(POC_MOVFF,
3646 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3649 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3650 // pic16_emitpcode(POC_MOVFF,
3651 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3654 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3655 // pic16_emitpcode(POC_MOVFF,
3656 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3659 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3661 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3662 // pic16_emitpcode(POC_MOVFF,
3663 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3666 /* >32-bits, setup stack and FSR0 */
3668 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3669 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3671 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3673 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3678 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3679 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3681 if(STACK_MODEL_LARGE) {
3682 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3683 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3685 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3690 /* old code, left here for reference -- VR */
3694 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3696 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3697 pic16_emitpcomment("push %s",l);
3700 DEBUGpic16_emitcode(";", "%d", __LINE__);
3701 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3702 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3704 if (strcmp(fReturn[offset],l)) {
3705 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3706 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3707 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3709 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3713 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3723 if (strcmp(fReturn[pushed],"a"))
3724 pic16_emitcode("pop",fReturn[pushed]);
3726 pic16_emitcode("pop","acc");
3732 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3735 /* generate a jump to the return label
3736 * if the next is not the return statement */
3737 if (!(ic->next && ic->next->op == LABEL
3738 && IC_LABEL(ic->next) == returnLabel)) {
3740 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3741 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3745 /*-----------------------------------------------------------------*/
3746 /* genLabel - generates a label */
3747 /*-----------------------------------------------------------------*/
3748 static void genLabel (iCode *ic)
3752 /* special case never generate */
3753 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3754 if (IC_LABEL(ic) == entryLabel)
3757 pic16_emitpLabel(IC_LABEL(ic)->key);
3758 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3761 /*-----------------------------------------------------------------*/
3762 /* genGoto - generates a goto */
3763 /*-----------------------------------------------------------------*/
3765 static void genGoto (iCode *ic)
3767 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3768 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3772 /*-----------------------------------------------------------------*/
3773 /* genMultbits :- multiplication of bits */
3774 /*-----------------------------------------------------------------*/
3775 static void genMultbits (operand *left,
3779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3781 if(!pic16_sameRegs(AOP(result),AOP(right)))
3782 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3784 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3785 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3786 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3791 /*-----------------------------------------------------------------*/
3792 /* genMultOneByte : 8 bit multiplication & division */
3793 /*-----------------------------------------------------------------*/
3794 static void genMultOneByte (operand *left,
3799 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3800 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3801 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3803 /* (if two literals, the value is computed before) */
3804 /* if one literal, literal on the right */
3805 if (AOP_TYPE(left) == AOP_LIT){
3811 /* size is already checked in genMult == 1 */
3812 // size = AOP_SIZE(result);
3814 if (AOP_TYPE(right) == AOP_LIT){
3815 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3816 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3817 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3818 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3820 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3821 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3822 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3823 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3826 pic16_genMult8X8_8 (left, right,result);
3829 /*-----------------------------------------------------------------*/
3830 /* genMultOneWord : 16 bit multiplication */
3831 /*-----------------------------------------------------------------*/
3832 static void genMultOneWord (operand *left,
3837 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3838 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3839 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3841 /* (if two literals, the value is computed before)
3842 * if one literal, literal on the right */
3843 if (AOP_TYPE(left) == AOP_LIT){
3849 /* size is checked already == 2 */
3850 // size = AOP_SIZE(result);
3852 if (AOP_TYPE(right) == AOP_LIT) {
3853 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3854 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3855 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3856 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3858 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3859 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3860 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3861 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3864 pic16_genMult16X16_16(left, right,result);
3867 /*-----------------------------------------------------------------*/
3868 /* genMultOneLong : 32 bit multiplication */
3869 /*-----------------------------------------------------------------*/
3870 static void genMultOneLong (operand *left,
3875 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3876 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3877 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3879 /* (if two literals, the value is computed before)
3880 * if one literal, literal on the right */
3881 if (AOP_TYPE(left) == AOP_LIT){
3887 /* size is checked already == 4 */
3888 // size = AOP_SIZE(result);
3890 if (AOP_TYPE(right) == AOP_LIT) {
3891 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3892 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3893 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3894 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3896 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3897 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3898 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3899 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3902 pic16_genMult32X32_32(left, right,result);
3907 /*-----------------------------------------------------------------*/
3908 /* genMult - generates code for multiplication */
3909 /*-----------------------------------------------------------------*/
3910 static void genMult (iCode *ic)
3912 operand *left = IC_LEFT(ic);
3913 operand *right = IC_RIGHT(ic);
3914 operand *result= IC_RESULT(ic);
3916 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3917 /* assign the amsops */
3918 pic16_aopOp (left,ic,FALSE);
3919 pic16_aopOp (right,ic,FALSE);
3920 pic16_aopOp (result,ic,TRUE);
3922 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3924 /* special cases first *
3926 if (AOP_TYPE(left) == AOP_CRY
3927 && AOP_TYPE(right)== AOP_CRY) {
3928 genMultbits(left,right,result);
3932 /* if both are of size == 1 */
3933 if(AOP_SIZE(left) == 1
3934 && AOP_SIZE(right) == 1) {
3935 genMultOneByte(left,right,result);
3939 /* if both are of size == 2 */
3940 if(AOP_SIZE(left) == 2
3941 && AOP_SIZE(right) == 2) {
3942 genMultOneWord(left, right, result);
3946 /* if both are of size == 4 */
3947 if(AOP_SIZE(left) == 4
3948 && AOP_SIZE(right) == 4) {
3949 genMultOneLong(left, right, result);
3953 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
3956 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
3957 /* should have been converted to function call */
3961 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3962 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3963 pic16_freeAsmop(result,NULL,ic,TRUE);
3966 /*-----------------------------------------------------------------*/
3967 /* genDivbits :- division of bits */
3968 /*-----------------------------------------------------------------*/
3969 static void genDivbits (operand *left,
3976 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3977 /* the result must be bit */
3978 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3979 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3983 pic16_emitcode("div","ab");
3984 pic16_emitcode("rrc","a");
3985 pic16_aopPut(AOP(result),"c",0);
3988 /*-----------------------------------------------------------------*/
3989 /* genDivOneByte : 8 bit division */
3990 /*-----------------------------------------------------------------*/
3991 static void genDivOneByte (operand *left,
3995 sym_link *opetype = operandType(result);
4000 /* result = divident / divisor
4001 * - divident may be a register or a literal,
4002 * - divisor may be a register or a literal,
4003 * so there are 3 cases (literal / literal is optimized
4004 * by the front-end) to handle.
4005 * In addition we must handle signed and unsigned, which
4006 * result in 6 final different cases -- VR */
4008 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4009 size = AOP_SIZE(result) - 1;
4011 /* signed or unsigned */
4012 if (SPEC_USIGN(opetype)) {
4013 pCodeOp *pct1, /* count */
4016 symbol *label1, *label2, *label3;;
4019 /* unsigned is easy */
4021 pct1 = pic16_popGetTempReg();
4022 pct2 = pic16_popGetTempReg();
4023 pct3 = pic16_popGetTempReg();
4025 label1 = newiTempLabel(NULL);
4026 label2 = newiTempLabel(NULL);
4027 label3 = newiTempLabel(NULL);
4029 /* the following algorithm is extracted from divuint.c */
4031 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4032 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4034 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4036 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4038 pic16_emitpLabel(label1->key);
4041 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4045 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4049 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4051 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4052 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4054 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4055 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4056 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4058 pic16_emitpLabel( label3->key );
4059 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4060 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4064 pic16_emitpLabel(label2->key);
4065 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4066 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4067 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4069 /* result is in wreg */
4070 if(AOP_TYPE(result) != AOP_ACC)
4071 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4073 pic16_popReleaseTempReg( pct3 );
4074 pic16_popReleaseTempReg( pct2 );
4075 pic16_popReleaseTempReg( pct1 );
4080 /* signed is a little bit more difficult */
4082 /* save the signs of the operands */
4083 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4085 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4086 pic16_emitcode("push","acc"); /* save it on the stack */
4088 /* now sign adjust for both left & right */
4089 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4091 lbl = newiTempLabel(NULL);
4092 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4093 pic16_emitcode("cpl","a");
4094 pic16_emitcode("inc","a");
4095 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4096 pic16_emitcode("mov","b,a");
4098 /* sign adjust left side */
4099 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4102 lbl = newiTempLabel(NULL);
4103 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4104 pic16_emitcode("cpl","a");
4105 pic16_emitcode("inc","a");
4106 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4108 /* now the division */
4109 pic16_emitcode("div","ab");
4110 /* we are interested in the lower order
4112 pic16_emitcode("mov","b,a");
4113 lbl = newiTempLabel(NULL);
4114 pic16_emitcode("pop","acc");
4115 /* if there was an over flow we don't
4116 adjust the sign of the result */
4117 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4118 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4120 pic16_emitcode("clr","a");
4121 pic16_emitcode("subb","a,b");
4122 pic16_emitcode("mov","b,a");
4123 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4125 /* now we are done */
4126 pic16_aopPut(AOP(result),"b",0);
4128 pic16_emitcode("mov","c,b.7");
4129 pic16_emitcode("subb","a,acc");
4132 pic16_aopPut(AOP(result),"a",offset++);
4136 /*-----------------------------------------------------------------*/
4137 /* genDiv - generates code for division */
4138 /*-----------------------------------------------------------------*/
4139 static void genDiv (iCode *ic)
4141 operand *left = IC_LEFT(ic);
4142 operand *right = IC_RIGHT(ic);
4143 operand *result= IC_RESULT(ic);
4146 /* Division is a very lengthy algorithm, so it is better
4147 * to call support routines than inlining algorithm.
4148 * Division functions written here just in case someone
4149 * wants to inline and not use the support libraries -- VR */
4151 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4152 /* assign the amsops */
4153 pic16_aopOp (left,ic,FALSE);
4154 pic16_aopOp (right,ic,FALSE);
4155 pic16_aopOp (result,ic,TRUE);
4157 /* special cases first */
4159 if (AOP_TYPE(left) == AOP_CRY &&
4160 AOP_TYPE(right)== AOP_CRY) {
4161 genDivbits(left,right,result);
4165 /* if both are of size == 1 */
4166 if (AOP_SIZE(left) == 1 &&
4167 AOP_SIZE(right) == 1 ) {
4168 genDivOneByte(left,right,result);
4172 /* should have been converted to function call */
4175 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4176 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4177 pic16_freeAsmop(result,NULL,ic,TRUE);
4180 /*-----------------------------------------------------------------*/
4181 /* genModbits :- modulus of bits */
4182 /*-----------------------------------------------------------------*/
4183 static void genModbits (operand *left,
4190 /* the result must be bit */
4191 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4192 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4196 pic16_emitcode("div","ab");
4197 pic16_emitcode("mov","a,b");
4198 pic16_emitcode("rrc","a");
4199 pic16_aopPut(AOP(result),"c",0);
4202 /*-----------------------------------------------------------------*/
4203 /* genModOneByte : 8 bit modulus */
4204 /*-----------------------------------------------------------------*/
4205 static void genModOneByte (operand *left,
4209 sym_link *opetype = operandType(result);
4213 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4214 /* signed or unsigned */
4215 if (SPEC_USIGN(opetype)) {
4216 /* unsigned is easy */
4217 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4218 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4220 pic16_emitcode("div","ab");
4221 pic16_aopPut(AOP(result),"b",0);
4225 /* signed is a little bit more difficult */
4227 /* save the signs of the operands */
4228 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4231 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4232 pic16_emitcode("push","acc"); /* save it on the stack */
4234 /* now sign adjust for both left & right */
4235 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4238 lbl = newiTempLabel(NULL);
4239 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4240 pic16_emitcode("cpl","a");
4241 pic16_emitcode("inc","a");
4242 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4243 pic16_emitcode("mov","b,a");
4245 /* sign adjust left side */
4246 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4249 lbl = newiTempLabel(NULL);
4250 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4251 pic16_emitcode("cpl","a");
4252 pic16_emitcode("inc","a");
4253 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4255 /* now the multiplication */
4256 pic16_emitcode("div","ab");
4257 /* we are interested in the lower order
4259 lbl = newiTempLabel(NULL);
4260 pic16_emitcode("pop","acc");
4261 /* if there was an over flow we don't
4262 adjust the sign of the result */
4263 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4264 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4266 pic16_emitcode("clr","a");
4267 pic16_emitcode("subb","a,b");
4268 pic16_emitcode("mov","b,a");
4269 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4271 /* now we are done */
4272 pic16_aopPut(AOP(result),"b",0);
4276 /*-----------------------------------------------------------------*/
4277 /* genMod - generates code for division */
4278 /*-----------------------------------------------------------------*/
4279 static void genMod (iCode *ic)
4281 operand *left = IC_LEFT(ic);
4282 operand *right = IC_RIGHT(ic);
4283 operand *result= IC_RESULT(ic);
4285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4286 /* assign the amsops */
4287 pic16_aopOp (left,ic,FALSE);
4288 pic16_aopOp (right,ic,FALSE);
4289 pic16_aopOp (result,ic,TRUE);
4291 /* special cases first */
4293 if (AOP_TYPE(left) == AOP_CRY &&
4294 AOP_TYPE(right)== AOP_CRY) {
4295 genModbits(left,right,result);
4299 /* if both are of size == 1 */
4300 if (AOP_SIZE(left) == 1 &&
4301 AOP_SIZE(right) == 1 ) {
4302 genModOneByte(left,right,result);
4306 /* should have been converted to function call */
4310 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4311 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4312 pic16_freeAsmop(result,NULL,ic,TRUE);
4315 /*-----------------------------------------------------------------*/
4316 /* genIfxJump :- will create a jump depending on the ifx */
4317 /*-----------------------------------------------------------------*/
4319 note: May need to add parameter to indicate when a variable is in bit space.
4321 static void genIfxJump (iCode *ic, char *jval)
4324 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4325 /* if true label then we jump if condition
4327 if ( IC_TRUE(ic) ) {
4329 if(strcmp(jval,"a") == 0)
4331 else if (strcmp(jval,"c") == 0)
4334 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4335 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
4338 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4339 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4343 /* false label is present */
4344 if(strcmp(jval,"a") == 0)
4346 else if (strcmp(jval,"c") == 0)
4349 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4350 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
4353 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4354 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4359 /* mark the icode as generated */
4366 /*-----------------------------------------------------------------*/
4368 /*-----------------------------------------------------------------*/
4369 static void genSkip(iCode *ifx,int status_bit)
4371 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4375 if ( IC_TRUE(ifx) ) {
4376 switch(status_bit) {
4391 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4392 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4396 switch(status_bit) {
4410 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4411 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4418 /*-----------------------------------------------------------------*/
4420 /*-----------------------------------------------------------------*/
4421 static void genSkipc(resolvedIfx *rifx)
4423 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4433 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4434 rifx->generated = 1;
4437 /*-----------------------------------------------------------------*/
4439 /*-----------------------------------------------------------------*/
4440 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4442 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4447 if( (rifx->condition ^ invert_condition) & 1)
4452 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4453 rifx->generated = 1;
4457 /*-----------------------------------------------------------------*/
4459 /*-----------------------------------------------------------------*/
4460 static void genSkipz(iCode *ifx, int condition)
4471 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4473 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4476 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4478 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4483 /*-----------------------------------------------------------------*/
4485 /*-----------------------------------------------------------------*/
4486 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4492 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4494 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4497 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4498 rifx->generated = 1;
4502 /*-----------------------------------------------------------------*/
4503 /* genChkZeroes :- greater or less than comparison */
4504 /* For each byte in a literal that is zero, inclusive or the */
4505 /* the corresponding byte in the operand with W */
4506 /* returns true if any of the bytes are zero */
4507 /*-----------------------------------------------------------------*/
4508 static int genChkZeroes(operand *op, int lit, int size)
4515 i = (lit >> (size*8)) & 0xff;
4519 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4521 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4530 /*-----------------------------------------------------------------*/
4531 /* genCmp :- greater or less than comparison */
4532 /*-----------------------------------------------------------------*/
4533 static void genCmp (operand *left,operand *right,
4534 operand *result, iCode *ifx, int sign)
4536 int size; //, offset = 0 ;
4537 unsigned long lit = 0L,i = 0;
4538 resolvedIfx rFalseIfx;
4539 // resolvedIfx rTrueIfx;
4541 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4544 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4545 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4549 resolveIfx(&rFalseIfx,ifx);
4550 truelbl = newiTempLabel(NULL);
4551 size = max(AOP_SIZE(left),AOP_SIZE(right));
4553 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4557 /* if literal is on the right then swap with left */
4558 if ((AOP_TYPE(right) == AOP_LIT)) {
4559 operand *tmp = right ;
4560 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4561 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4564 lit = (lit - 1) & mask;
4567 rFalseIfx.condition ^= 1;
4570 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4571 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4575 //if(IC_TRUE(ifx) == NULL)
4576 /* if left & right are bit variables */
4577 if (AOP_TYPE(left) == AOP_CRY &&
4578 AOP_TYPE(right) == AOP_CRY ) {
4579 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4580 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4582 /* subtract right from left if at the
4583 end the carry flag is set then we know that
4584 left is greater than right */
4586 symbol *lbl = newiTempLabel(NULL);
4589 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4590 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
4594 if(AOP_TYPE(right) == AOP_LIT) {
4596 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4598 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4605 genSkipCond(&rFalseIfx,left,size-1,7);
4607 /* no need to compare to 0...*/
4608 /* NOTE: this is a de-generate compare that most certainly
4609 * creates some dead code. */
4610 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4612 if(ifx) ifx->generated = 1;
4619 //i = (lit >> (size*8)) & 0xff;
4620 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4622 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4624 i = ((0-lit) & 0xff);
4627 /* lit is 0x7f, all signed chars are less than
4628 * this except for 0x7f itself */
4629 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4630 genSkipz2(&rFalseIfx,0);
4632 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4633 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4634 genSkipc(&rFalseIfx);
4639 genSkipz2(&rFalseIfx,1);
4641 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4642 genSkipc(&rFalseIfx);
4646 if(ifx) ifx->generated = 1;
4650 /* chars are out of the way. now do ints and longs */
4653 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4660 genSkipCond(&rFalseIfx,left,size,7);
4661 if(ifx) ifx->generated = 1;
4666 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4668 //rFalseIfx.condition ^= 1;
4669 //genSkipCond(&rFalseIfx,left,size,7);
4670 //rFalseIfx.condition ^= 1;
4672 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4673 if(rFalseIfx.condition)
4674 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4676 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4678 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4679 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4680 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4683 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4685 if(rFalseIfx.condition) {
4687 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4693 genSkipc(&rFalseIfx);
4694 pic16_emitpLabel(truelbl->key);
4695 if(ifx) ifx->generated = 1;
4702 if( (lit & 0xff) == 0) {
4703 /* lower byte is zero */
4704 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4705 i = ((lit >> 8) & 0xff) ^0x80;
4706 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4707 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4708 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4709 genSkipc(&rFalseIfx);
4712 if(ifx) ifx->generated = 1;
4717 /* Special cases for signed longs */
4718 if( (lit & 0xffffff) == 0) {
4719 /* lower byte is zero */
4720 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4721 i = ((lit >> 8*3) & 0xff) ^0x80;
4722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4723 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4724 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4725 genSkipc(&rFalseIfx);
4728 if(ifx) ifx->generated = 1;
4736 if(lit & (0x80 << (size*8))) {
4737 /* lit is negative */
4738 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4740 //genSkipCond(&rFalseIfx,left,size,7);
4742 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4744 if(rFalseIfx.condition)
4745 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4747 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4751 /* lit is positive */
4752 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4753 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4754 if(rFalseIfx.condition)
4755 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4757 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4762 This works, but is only good for ints.
4763 It also requires a "known zero" register.
4764 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4765 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4766 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4767 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4768 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4769 genSkipc(&rFalseIfx);
4771 pic16_emitpLabel(truelbl->key);
4772 if(ifx) ifx->generated = 1;
4776 /* There are no more special cases, so perform a general compare */
4778 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4779 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4783 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4785 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4787 //rFalseIfx.condition ^= 1;
4788 genSkipc(&rFalseIfx);
4790 pic16_emitpLabel(truelbl->key);
4792 if(ifx) ifx->generated = 1;
4799 /* sign is out of the way. So now do an unsigned compare */
4800 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4803 /* General case - compare to an unsigned literal on the right.*/
4805 i = (lit >> (size*8)) & 0xff;
4806 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4807 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4809 i = (lit >> (size*8)) & 0xff;
4812 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4814 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4816 /* this byte of the lit is zero,
4817 *if it's not the last then OR in the variable */
4819 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4824 pic16_emitpLabel(lbl->key);
4825 // pic16_emitpLabel(truelbl->key);
4826 //if(emitFinalCheck)
4827 genSkipc(&rFalseIfx);
4829 pic16_emitpLabel(truelbl->key);
4831 if(ifx) ifx->generated = 1;
4838 if(AOP_TYPE(left) == AOP_LIT) {
4839 //symbol *lbl = newiTempLabel(NULL);
4841 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4844 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4847 if((lit == 0) && (sign == 0)){
4850 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4852 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4854 genSkipz2(&rFalseIfx,0);
4855 if(ifx) ifx->generated = 1;
4862 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4863 /* degenerate compare can never be true */
4864 if(rFalseIfx.condition == 0)
4865 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4867 if(ifx) ifx->generated = 1;
4872 /* signed comparisons to a literal byte */
4874 int lp1 = (lit+1) & 0xff;
4876 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4879 rFalseIfx.condition ^= 1;
4880 genSkipCond(&rFalseIfx,right,0,7);
4883 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4884 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4885 genSkipz2(&rFalseIfx,1);
4888 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4889 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4890 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4891 rFalseIfx.condition ^= 1;
4892 genSkipc(&rFalseIfx);
4896 /* unsigned comparisons to a literal byte */
4898 switch(lit & 0xff ) {
4900 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4901 genSkipz2(&rFalseIfx,0);
4904 rFalseIfx.condition ^= 1;
4905 genSkipCond(&rFalseIfx,right,0,7);
4909 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4910 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4911 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4912 rFalseIfx.condition ^= 1;
4913 if (AOP_TYPE(result) == AOP_CRY)
4914 genSkipc(&rFalseIfx);
4916 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4917 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4923 if(ifx) ifx->generated = 1;
4929 /* Size is greater than 1 */
4937 /* this means lit = 0xffffffff, or -1 */
4940 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4941 rFalseIfx.condition ^= 1;
4942 genSkipCond(&rFalseIfx,right,size,7);
4943 if(ifx) ifx->generated = 1;
4950 if(rFalseIfx.condition) {
4951 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4952 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4955 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4957 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4961 if(rFalseIfx.condition) {
4962 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4963 pic16_emitpLabel(truelbl->key);
4965 rFalseIfx.condition ^= 1;
4966 genSkipCond(&rFalseIfx,right,s,7);
4969 if(ifx) ifx->generated = 1;
4973 if((size == 1) && (0 == (lp1&0xff))) {
4974 /* lower byte of signed word is zero */
4975 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4976 i = ((lp1 >> 8) & 0xff) ^0x80;
4977 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4978 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4979 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4980 rFalseIfx.condition ^= 1;
4981 genSkipc(&rFalseIfx);
4984 if(ifx) ifx->generated = 1;
4988 if(lit & (0x80 << (size*8))) {
4989 /* Lit is less than zero */
4990 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4991 //rFalseIfx.condition ^= 1;
4992 //genSkipCond(&rFalseIfx,left,size,7);
4993 //rFalseIfx.condition ^= 1;
4994 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4995 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4997 if(rFalseIfx.condition)
4998 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5000 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5004 /* Lit is greater than or equal to zero */
5005 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5006 //rFalseIfx.condition ^= 1;
5007 //genSkipCond(&rFalseIfx,right,size,7);
5008 //rFalseIfx.condition ^= 1;
5010 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5011 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5013 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5014 if(rFalseIfx.condition)
5015 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5017 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5022 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5023 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5027 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5029 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5031 rFalseIfx.condition ^= 1;
5032 //rFalseIfx.condition = 1;
5033 genSkipc(&rFalseIfx);
5035 pic16_emitpLabel(truelbl->key);
5037 if(ifx) ifx->generated = 1;
5042 /* compare word or long to an unsigned literal on the right.*/
5047 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5050 break; /* handled above */
5053 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5055 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5056 genSkipz2(&rFalseIfx,0);
5060 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5062 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5065 if(rFalseIfx.condition)
5066 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5068 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5071 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5072 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5074 rFalseIfx.condition ^= 1;
5075 genSkipc(&rFalseIfx);
5078 pic16_emitpLabel(truelbl->key);
5080 if(ifx) ifx->generated = 1;
5086 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5087 i = (lit >> (size*8)) & 0xff;
5089 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5090 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5093 i = (lit >> (size*8)) & 0xff;
5096 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5098 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5100 /* this byte of the lit is zero,
5101 * if it's not the last then OR in the variable */
5103 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5108 pic16_emitpLabel(lbl->key);
5110 rFalseIfx.condition ^= 1;
5112 genSkipc(&rFalseIfx);
5116 pic16_emitpLabel(truelbl->key);
5117 if(ifx) ifx->generated = 1;
5121 /* Compare two variables */
5123 DEBUGpic16_emitcode(";sign","%d",sign);
5127 /* Sigh. thus sucks... */
5129 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5130 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5131 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5132 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5133 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5134 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5136 /* Signed char comparison */
5137 /* Special thanks to Nikolai Golovchenko for this snippet */
5138 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5139 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5140 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5141 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5142 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5143 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5145 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5146 genSkipc(&rFalseIfx);
5148 if(ifx) ifx->generated = 1;
5154 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5155 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5159 /* The rest of the bytes of a multi-byte compare */
5163 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5166 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5167 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5172 pic16_emitpLabel(lbl->key);
5174 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5175 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5176 (AOP_TYPE(result) == AOP_REG)) {
5177 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5178 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5180 genSkipc(&rFalseIfx);
5182 //genSkipc(&rFalseIfx);
5183 if(ifx) ifx->generated = 1;
5190 if ((AOP_TYPE(result) != AOP_CRY)
5191 && AOP_SIZE(result)) {
5192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5193 // pic16_emitpLabel( rFalseIfx.lbl->key );
5195 pic16_outBitC(result);
5197 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5198 /* if the result is used in the next
5199 ifx conditional branch then generate
5200 code a little differently */
5202 genIfxJump (ifx,"c");
5204 pic16_outBitC(result);
5205 /* leave the result in acc */
5210 /*-----------------------------------------------------------------*/
5211 /* genCmpGt :- greater than comparison */
5212 /*-----------------------------------------------------------------*/
5213 static void genCmpGt (iCode *ic, iCode *ifx)
5215 operand *left, *right, *result;
5216 sym_link *letype , *retype;
5219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5221 right= IC_RIGHT(ic);
5222 result = IC_RESULT(ic);
5224 letype = getSpec(operandType(left));
5225 retype =getSpec(operandType(right));
5226 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5227 /* assign the amsops */
5228 pic16_aopOp (left,ic,FALSE);
5229 pic16_aopOp (right,ic,FALSE);
5230 pic16_aopOp (result,ic,TRUE);
5232 genCmp(right, left, result, ifx, sign);
5234 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5235 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5236 pic16_freeAsmop(result,NULL,ic,TRUE);
5239 /*-----------------------------------------------------------------*/
5240 /* genCmpLt - less than comparisons */
5241 /*-----------------------------------------------------------------*/
5242 static void genCmpLt (iCode *ic, iCode *ifx)
5244 operand *left, *right, *result;
5245 sym_link *letype , *retype;
5248 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5250 right= IC_RIGHT(ic);
5251 result = IC_RESULT(ic);
5253 letype = getSpec(operandType(left));
5254 retype =getSpec(operandType(right));
5255 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5257 /* assign the amsops */
5258 pic16_aopOp (left,ic,FALSE);
5259 pic16_aopOp (right,ic,FALSE);
5260 pic16_aopOp (result,ic,TRUE);
5262 genCmp(left, right, result, ifx, sign);
5264 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5265 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5266 pic16_freeAsmop(result,NULL,ic,TRUE);
5271 // FIXME reenable literal optimisation when the pic16 port is stable
5273 /*-----------------------------------------------------------------*/
5274 /* genc16bit2lit - compare a 16 bit value to a literal */
5275 /*-----------------------------------------------------------------*/
5276 static void genc16bit2lit(operand *op, int lit, int offset)
5280 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5281 if( (lit&0xff) == 0)
5286 switch( BYTEofLONG(lit,i)) {
5288 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5291 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5294 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5297 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5298 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5303 switch( BYTEofLONG(lit,i)) {
5305 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5309 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5313 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5316 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5318 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5327 /*-----------------------------------------------------------------*/
5328 /* gencjneshort - compare and jump if not equal */
5329 /*-----------------------------------------------------------------*/
5330 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5332 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5334 int res_offset = 0; /* the result may be a different size then left or right */
5335 int res_size = AOP_SIZE(result);
5337 symbol *lbl, *lbl_done;
5339 unsigned long lit = 0L;
5340 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5343 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5345 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5346 resolveIfx(&rIfx,ifx);
5347 lbl = newiTempLabel(NULL);
5348 lbl_done = newiTempLabel(NULL);
5351 /* if the left side is a literal or
5352 if the right is in a pointer register and left
5354 if ((AOP_TYPE(left) == AOP_LIT) ||
5355 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5360 if(AOP_TYPE(right) == AOP_LIT)
5361 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5363 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5364 preserve_result = 1;
5366 if(result && !preserve_result)
5369 for(i = 0; i < AOP_SIZE(result); i++)
5370 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5374 /* if the right side is a literal then anything goes */
5375 if (AOP_TYPE(right) == AOP_LIT &&
5376 AOP_TYPE(left) != AOP_DIR ) {
5379 genc16bit2lit(left, lit, 0);
5381 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5384 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5387 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5388 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5390 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5394 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5396 if(res_offset < res_size-1)
5404 /* if the right side is in a register or in direct space or
5405 if the left is a pointer register & right is not */
5406 else if (AOP_TYPE(right) == AOP_REG ||
5407 AOP_TYPE(right) == AOP_DIR ||
5408 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5409 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5410 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5411 int lbl_key = lbl->key;
5414 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5415 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5417 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5418 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5419 __FUNCTION__,__LINE__);
5423 /* switch(size) { */
5425 /* genc16bit2lit(left, lit, 0); */
5427 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5432 if((AOP_TYPE(left) == AOP_DIR) &&
5433 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5435 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5436 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5438 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5440 switch (lit & 0xff) {
5442 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5445 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5446 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5447 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5451 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5452 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5453 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5454 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5458 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5459 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5464 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5467 if(AOP_TYPE(result) == AOP_CRY) {
5468 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5473 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5475 /* fix me. probably need to check result size too */
5476 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5481 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5482 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5489 if(res_offset < res_size-1)
5494 } else if(AOP_TYPE(right) == AOP_REG &&
5495 AOP_TYPE(left) != AOP_DIR){
5498 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5499 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5500 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5505 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5507 if(res_offset < res_size-1)
5512 /* right is a pointer reg need both a & b */
5514 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5516 pic16_emitcode("mov","b,%s",l);
5517 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5518 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5523 if(result && preserve_result)
5526 for(i = 0; i < AOP_SIZE(result); i++)
5527 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5530 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5532 if(result && preserve_result)
5533 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5536 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5538 pic16_emitpLabel(lbl->key);
5540 if(result && preserve_result)
5543 for(i = 0; i < AOP_SIZE(result); i++)
5544 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5546 pic16_emitpLabel(lbl_done->key);
5549 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5557 /*-----------------------------------------------------------------*/
5558 /* gencjne - compare and jump if not equal */
5559 /*-----------------------------------------------------------------*/
5560 static void gencjne(operand *left, operand *right, iCode *ifx)
5562 symbol *tlbl = newiTempLabel(NULL);
5564 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5565 gencjneshort(left, right, lbl);
5567 pic16_emitcode("mov","a,%s",one);
5568 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5569 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5570 pic16_emitcode("clr","a");
5571 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5573 pic16_emitpLabel(lbl->key);
5574 pic16_emitpLabel(tlbl->key);
5580 /*-----------------------------------------------------------------*/
5581 /* is_LitOp - check if operand has to be treated as literal */
5582 /*-----------------------------------------------------------------*/
5583 static bool is_LitOp(operand *op)
5585 return (AOP_TYPE(op) == AOP_LIT)
5586 || ( (AOP_TYPE(op) == AOP_PCODE)
5587 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
5588 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
5592 /*-----------------------------------------------------------------*/
5593 /* genCmpEq - generates code for equal to */
5594 /*-----------------------------------------------------------------*/
5595 static void genCmpEq (iCode *ic, iCode *ifx)
5597 operand *left, *right, *result;
5598 symbol *falselbl = newiTempLabel(NULL);
5599 symbol *donelbl = newiTempLabel(NULL);
5601 int preserve_result = 0;
5602 int generate_result = 0;
5605 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5606 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5607 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5609 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5610 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5612 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
5614 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5615 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
5619 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
5621 operand *tmp = right ;
5626 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5627 preserve_result = 1;
5629 if(result && AOP_SIZE(result))
5630 generate_result = 1;
5632 if(generate_result && !preserve_result)
5634 for(i = 0; i < AOP_SIZE(result); i++)
5635 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5638 for(i=0; i < AOP_SIZE(left); i++)
5640 if(AOP_TYPE(left) != AOP_ACC)
5643 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
5645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
5648 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
5650 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
5652 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
5657 if(generate_result && preserve_result)
5659 for(i = 0; i < AOP_SIZE(result); i++)
5660 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5664 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
5666 if(generate_result && preserve_result)
5667 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5669 if(ifx && IC_TRUE(ifx))
5670 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5672 if(ifx && IC_FALSE(ifx))
5673 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5675 pic16_emitpLabel(falselbl->key);
5679 if(ifx && IC_FALSE(ifx))
5680 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5682 if(generate_result && preserve_result)
5684 for(i = 0; i < AOP_SIZE(result); i++)
5685 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5688 pic16_emitpLabel(donelbl->key);
5694 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5695 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5696 pic16_freeAsmop(result,NULL,ic,TRUE);
5702 // old version kept for reference
5704 /*-----------------------------------------------------------------*/
5705 /* genCmpEq - generates code for equal to */
5706 /*-----------------------------------------------------------------*/
5707 static void genCmpEq (iCode *ic, iCode *ifx)
5709 operand *left, *right, *result;
5710 unsigned long lit = 0L;
5712 symbol *falselbl = newiTempLabel(NULL);
5715 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5718 DEBUGpic16_emitcode ("; ifx is non-null","");
5720 DEBUGpic16_emitcode ("; ifx is null","");
5722 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5723 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5724 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5726 size = max(AOP_SIZE(left),AOP_SIZE(right));
5728 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5730 /* if literal, literal on the right or
5731 if the right is in a pointer register and left
5733 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5734 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5735 operand *tmp = right ;
5741 if(ifx && !AOP_SIZE(result)){
5743 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5744 /* if they are both bit variables */
5745 if (AOP_TYPE(left) == AOP_CRY &&
5746 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5747 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5748 if(AOP_TYPE(right) == AOP_LIT){
5749 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5751 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5752 pic16_emitcode("cpl","c");
5753 } else if(lit == 1L) {
5754 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5756 pic16_emitcode("clr","c");
5758 /* AOP_TYPE(right) == AOP_CRY */
5760 symbol *lbl = newiTempLabel(NULL);
5761 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5762 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5763 pic16_emitcode("cpl","c");
5764 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5766 /* if true label then we jump if condition
5768 tlbl = newiTempLabel(NULL);
5769 if ( IC_TRUE(ifx) ) {
5770 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5771 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5773 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5774 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5776 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5779 /* left and right are both bit variables, result is carry */
5782 resolveIfx(&rIfx,ifx);
5784 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5785 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5786 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5787 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5792 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5794 /* They're not both bit variables. Is the right a literal? */
5795 if(AOP_TYPE(right) == AOP_LIT) {
5796 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5801 switch(lit & 0xff) {
5803 if ( IC_TRUE(ifx) ) {
5804 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5806 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5808 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5809 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5813 if ( IC_TRUE(ifx) ) {
5814 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5816 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5818 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5819 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5823 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5825 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5830 /* end of size == 1 */
5834 genc16bit2lit(left,lit,offset);
5837 /* end of size == 2 */
5842 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5843 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5844 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5845 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5848 /* search for patterns that can be optimized */
5850 genc16bit2lit(left,lit,0);
5854 emitSKPZ; // if hi word unequal
5856 emitSKPNZ; // if hi word equal
5858 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5859 genc16bit2lit(left,lit,2);
5862 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5863 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5867 pic16_emitpLabel(falselbl->key);
5876 } else if(AOP_TYPE(right) == AOP_CRY ) {
5877 /* we know the left is not a bit, but that the right is */
5878 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5879 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5880 pic16_popGet(AOP(right),offset));
5881 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5883 /* if the two are equal, then W will be 0 and the Z bit is set
5884 * we could test Z now, or go ahead and check the high order bytes if
5885 * the variable we're comparing is larger than a byte. */
5888 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5890 if ( IC_TRUE(ifx) ) {
5892 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5893 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5896 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5897 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5901 /* They're both variables that are larger than bits */
5904 tlbl = newiTempLabel(NULL);
5907 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5908 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5910 if ( IC_TRUE(ifx) ) {
5914 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5916 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5917 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5921 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5924 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5925 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5930 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5932 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5933 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5937 if(s>1 && IC_TRUE(ifx)) {
5938 pic16_emitpLabel(tlbl->key);
5939 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5943 /* mark the icode as generated */
5948 /* if they are both bit variables */
5949 if (AOP_TYPE(left) == AOP_CRY &&
5950 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5951 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5952 if(AOP_TYPE(right) == AOP_LIT){
5953 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5955 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5956 pic16_emitcode("cpl","c");
5957 } else if(lit == 1L) {
5958 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5960 pic16_emitcode("clr","c");
5962 /* AOP_TYPE(right) == AOP_CRY */
5964 symbol *lbl = newiTempLabel(NULL);
5965 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5966 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5967 pic16_emitcode("cpl","c");
5968 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5971 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5972 pic16_outBitC(result);
5976 genIfxJump (ifx,"c");
5979 /* if the result is used in an arithmetic operation
5980 then put the result in place */
5981 pic16_outBitC(result);
5984 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5985 gencjne(left,right,result,ifx);
5988 gencjne(left,right,newiTempLabel(NULL));
5990 if(IC_TRUE(ifx)->key)
5991 gencjne(left,right,IC_TRUE(ifx)->key);
5993 gencjne(left,right,IC_FALSE(ifx)->key);
5997 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5998 pic16_aopPut(AOP(result),"a",0);
6003 genIfxJump (ifx,"a");
6007 /* if the result is used in an arithmetic operation
6008 then put the result in place */
6010 if (AOP_TYPE(result) != AOP_CRY)
6011 pic16_outAcc(result);
6013 /* leave the result in acc */
6017 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6018 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6019 pic16_freeAsmop(result,NULL,ic,TRUE);
6023 /*-----------------------------------------------------------------*/
6024 /* ifxForOp - returns the icode containing the ifx for operand */
6025 /*-----------------------------------------------------------------*/
6026 static iCode *ifxForOp ( operand *op, iCode *ic )
6028 /* if true symbol then needs to be assigned */
6029 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6030 if (IS_TRUE_SYMOP(op))
6033 /* if this has register type condition and
6034 the next instruction is ifx with the same operand
6035 and live to of the operand is upto the ifx only then */
6037 && ic->next->op == IFX
6038 && IC_COND(ic->next)->key == op->key
6039 && OP_SYMBOL(op)->liveTo <= ic->next->seq
6041 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
6046 ic->next->op == IFX &&
6047 IC_COND(ic->next)->key == op->key) {
6048 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6052 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6054 ic->next->op == IFX)
6055 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6058 ic->next->op == IFX &&
6059 IC_COND(ic->next)->key == op->key) {
6060 DEBUGpic16_emitcode ("; "," key is okay");
6061 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6062 OP_SYMBOL(op)->liveTo,
6067 /* the code below is completely untested
6068 * it just allows ulong2fs.c compile -- VR */
6071 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6072 __FILE__, __FUNCTION__, __LINE__);
6074 /* if this has register type condition and
6075 the next instruction is ifx with the same operand
6076 and live to of the operand is upto the ifx only then */
6078 ic->next->op == IFX &&
6079 IC_COND(ic->next)->key == op->key &&
6080 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6084 ic->next->op == IFX &&
6085 IC_COND(ic->next)->key == op->key) {
6086 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6090 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6091 __FILE__, __FUNCTION__, __LINE__);
6093 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6098 /*-----------------------------------------------------------------*/
6099 /* genAndOp - for && operation */
6100 /*-----------------------------------------------------------------*/
6101 static void genAndOp (iCode *ic)
6103 operand *left,*right, *result;
6106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6107 /* note here that && operations that are in an
6108 if statement are taken away by backPatchLabels
6109 only those used in arthmetic operations remain */
6110 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6111 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6112 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6114 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6116 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6117 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6118 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6120 /* if both are bit variables */
6121 /* if (AOP_TYPE(left) == AOP_CRY && */
6122 /* AOP_TYPE(right) == AOP_CRY ) { */
6123 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6124 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6125 /* pic16_outBitC(result); */
6127 /* tlbl = newiTempLabel(NULL); */
6128 /* pic16_toBoolean(left); */
6129 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6130 /* pic16_toBoolean(right); */
6131 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6132 /* pic16_outBitAcc(result); */
6135 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6136 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6137 pic16_freeAsmop(result,NULL,ic,TRUE);
6141 /*-----------------------------------------------------------------*/
6142 /* genOrOp - for || operation */
6143 /*-----------------------------------------------------------------*/
6146 modified this code, but it doesn't appear to ever get called
6149 static void genOrOp (iCode *ic)
6151 operand *left,*right, *result;
6154 /* note here that || operations that are in an
6155 if statement are taken away by backPatchLabels
6156 only those used in arthmetic operations remain */
6157 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6158 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6159 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6160 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6162 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6164 /* if both are bit variables */
6165 if (AOP_TYPE(left) == AOP_CRY &&
6166 AOP_TYPE(right) == AOP_CRY ) {
6167 pic16_emitcode("clrc","");
6168 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6169 AOP(left)->aopu.aop_dir,
6170 AOP(left)->aopu.aop_dir);
6171 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6172 AOP(right)->aopu.aop_dir,
6173 AOP(right)->aopu.aop_dir);
6174 pic16_emitcode("setc","");
6177 tlbl = newiTempLabel(NULL);
6178 pic16_toBoolean(left);
6180 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
6181 pic16_toBoolean(right);
6182 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
6184 pic16_outBitAcc(result);
6187 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6188 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6189 pic16_freeAsmop(result,NULL,ic,TRUE);
6192 /*-----------------------------------------------------------------*/
6193 /* isLiteralBit - test if lit == 2^n */
6194 /*-----------------------------------------------------------------*/
6195 static int isLiteralBit(unsigned long lit)
6197 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6198 0x100L,0x200L,0x400L,0x800L,
6199 0x1000L,0x2000L,0x4000L,0x8000L,
6200 0x10000L,0x20000L,0x40000L,0x80000L,
6201 0x100000L,0x200000L,0x400000L,0x800000L,
6202 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6203 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6207 for(idx = 0; idx < 32; idx++)
6213 /*-----------------------------------------------------------------*/
6214 /* continueIfTrue - */
6215 /*-----------------------------------------------------------------*/
6216 static void continueIfTrue (iCode *ic)
6218 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6220 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6224 /*-----------------------------------------------------------------*/
6226 /*-----------------------------------------------------------------*/
6227 static void jumpIfTrue (iCode *ic)
6229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6231 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6235 /*-----------------------------------------------------------------*/
6236 /* jmpTrueOrFalse - */
6237 /*-----------------------------------------------------------------*/
6238 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6240 // ugly but optimized by peephole
6241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6243 symbol *nlbl = newiTempLabel(NULL);
6244 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6245 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6246 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6247 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6250 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6251 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6256 /*-----------------------------------------------------------------*/
6257 /* genAnd - code for and */
6258 /*-----------------------------------------------------------------*/
6259 static void genAnd (iCode *ic, iCode *ifx)
6261 operand *left, *right, *result;
6263 unsigned long lit = 0L;
6268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6269 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6270 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6271 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6273 resolveIfx(&rIfx,ifx);
6275 /* if left is a literal & right is not then exchange them */
6276 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6277 AOP_NEEDSACC(left)) {
6278 operand *tmp = right ;
6283 /* if result = right then exchange them */
6284 if(pic16_sameRegs(AOP(result),AOP(right))){
6285 operand *tmp = right ;
6290 /* if right is bit then exchange them */
6291 if (AOP_TYPE(right) == AOP_CRY &&
6292 AOP_TYPE(left) != AOP_CRY){
6293 operand *tmp = right ;
6297 if(AOP_TYPE(right) == AOP_LIT)
6298 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6300 size = AOP_SIZE(result);
6302 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6305 // result = bit & yy;
6306 if (AOP_TYPE(left) == AOP_CRY){
6307 // c = bit & literal;
6308 if(AOP_TYPE(right) == AOP_LIT){
6310 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6313 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6316 if(size && (AOP_TYPE(result) == AOP_CRY)){
6317 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6320 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6324 pic16_emitcode("clr","c");
6327 if (AOP_TYPE(right) == AOP_CRY){
6329 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6330 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6333 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6335 pic16_emitcode("rrc","a");
6336 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6342 pic16_outBitC(result);
6344 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6345 genIfxJump(ifx, "c");
6349 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6350 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6351 if((AOP_TYPE(right) == AOP_LIT) &&
6352 (AOP_TYPE(result) == AOP_CRY) &&
6353 (AOP_TYPE(left) != AOP_CRY)){
6354 int posbit = isLiteralBit(lit);
6358 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6361 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6367 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6368 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6370 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6371 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6374 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
6375 size = AOP_SIZE(left);
6378 int bp = posbit, ofs=0;
6385 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6386 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0));
6390 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6391 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6393 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6400 symbol *tlbl = newiTempLabel(NULL);
6401 int sizel = AOP_SIZE(left);
6403 pic16_emitcode("setb","c");
6405 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
6406 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6408 if((posbit = isLiteralBit(bytelit)) != 0)
6409 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6411 if(bytelit != 0x0FFL)
6412 pic16_emitcode("anl","a,%s",
6413 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6414 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6419 // bit = left & literal
6421 pic16_emitcode("clr","c");
6422 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6424 // if(left & literal)
6427 jmpTrueOrFalse(ifx, tlbl);
6431 pic16_outBitC(result);
6435 /* if left is same as result */
6436 if(pic16_sameRegs(AOP(result),AOP(left))){
6438 for(;size--; offset++,lit>>=8) {
6439 if(AOP_TYPE(right) == AOP_LIT){
6440 switch(lit & 0xff) {
6442 /* and'ing with 0 has clears the result */
6443 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6444 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6447 /* and'ing with 0xff is a nop when the result and left are the same */
6452 int p = my_powof2( (~lit) & 0xff );
6454 /* only one bit is set in the literal, so use a bcf instruction */
6455 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6456 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6459 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6460 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6461 if(know_W != (lit&0xff))
6462 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6464 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6469 if (AOP_TYPE(left) == AOP_ACC) {
6470 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6472 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6473 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6480 // left & result in different registers
6481 if(AOP_TYPE(result) == AOP_CRY){
6483 // if(size), result in bit
6484 // if(!size && ifx), conditional oper: if(left & right)
6485 symbol *tlbl = newiTempLabel(NULL);
6486 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6488 pic16_emitcode("setb","c");
6490 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6491 pic16_emitcode("anl","a,%s",
6492 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6493 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6498 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6499 pic16_outBitC(result);
6501 jmpTrueOrFalse(ifx, tlbl);
6503 for(;(size--);offset++) {
6505 // result = left & right
6506 if(AOP_TYPE(right) == AOP_LIT){
6507 int t = (lit >> (offset*8)) & 0x0FFL;
6510 pic16_emitcode("clrf","%s",
6511 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6512 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6515 pic16_emitcode("movf","%s,w",
6516 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6517 pic16_emitcode("movwf","%s",
6518 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6519 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6520 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6523 pic16_emitcode("movlw","0x%x",t);
6524 pic16_emitcode("andwf","%s,w",
6525 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6526 pic16_emitcode("movwf","%s",
6527 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6529 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6530 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6531 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6536 if (AOP_TYPE(left) == AOP_ACC) {
6537 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6538 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6540 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6541 pic16_emitcode("andwf","%s,w",
6542 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6543 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6544 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6546 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6547 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6553 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6554 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6555 pic16_freeAsmop(result,NULL,ic,TRUE);
6558 /*-----------------------------------------------------------------*/
6559 /* genOr - code for or */
6560 /*-----------------------------------------------------------------*/
6561 static void genOr (iCode *ic, iCode *ifx)
6563 operand *left, *right, *result;
6565 unsigned long lit = 0L;
6567 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6569 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6570 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6571 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6573 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6575 /* if left is a literal & right is not then exchange them */
6576 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6577 AOP_NEEDSACC(left)) {
6578 operand *tmp = right ;
6583 /* if result = right then exchange them */
6584 if(pic16_sameRegs(AOP(result),AOP(right))){
6585 operand *tmp = right ;
6590 /* if right is bit then exchange them */
6591 if (AOP_TYPE(right) == AOP_CRY &&
6592 AOP_TYPE(left) != AOP_CRY){
6593 operand *tmp = right ;
6598 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6600 if(AOP_TYPE(right) == AOP_LIT)
6601 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6603 size = AOP_SIZE(result);
6607 if (AOP_TYPE(left) == AOP_CRY){
6608 if(AOP_TYPE(right) == AOP_LIT){
6609 // c = bit & literal;
6611 // lit != 0 => result = 1
6612 if(AOP_TYPE(result) == AOP_CRY){
6614 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6615 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6616 // AOP(result)->aopu.aop_dir,
6617 // AOP(result)->aopu.aop_dir);
6619 continueIfTrue(ifx);
6623 // lit == 0 => result = left
6624 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6626 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6629 if (AOP_TYPE(right) == AOP_CRY){
6630 if(pic16_sameRegs(AOP(result),AOP(left))){
6632 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6633 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6634 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6636 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6637 AOP(result)->aopu.aop_dir,
6638 AOP(result)->aopu.aop_dir);
6639 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6640 AOP(right)->aopu.aop_dir,
6641 AOP(right)->aopu.aop_dir);
6642 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6643 AOP(result)->aopu.aop_dir,
6644 AOP(result)->aopu.aop_dir);
6646 if( AOP_TYPE(result) == AOP_ACC) {
6647 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6648 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6649 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6650 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6654 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6655 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6656 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6657 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6659 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6660 AOP(result)->aopu.aop_dir,
6661 AOP(result)->aopu.aop_dir);
6662 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6663 AOP(right)->aopu.aop_dir,
6664 AOP(right)->aopu.aop_dir);
6665 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6666 AOP(left)->aopu.aop_dir,
6667 AOP(left)->aopu.aop_dir);
6668 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6669 AOP(result)->aopu.aop_dir,
6670 AOP(result)->aopu.aop_dir);
6675 symbol *tlbl = newiTempLabel(NULL);
6676 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6679 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6680 if( AOP_TYPE(right) == AOP_ACC) {
6681 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6683 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6684 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6689 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6690 pic16_emitcode(";XXX setb","c");
6691 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6692 AOP(left)->aopu.aop_dir,tlbl->key+100);
6693 pic16_toBoolean(right);
6694 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6695 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6696 jmpTrueOrFalse(ifx, tlbl);
6700 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6707 pic16_outBitC(result);
6709 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6710 genIfxJump(ifx, "c");
6714 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6715 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6716 if((AOP_TYPE(right) == AOP_LIT) &&
6717 (AOP_TYPE(result) == AOP_CRY) &&
6718 (AOP_TYPE(left) != AOP_CRY)){
6720 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6723 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6725 continueIfTrue(ifx);
6728 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6729 // lit = 0, result = boolean(left)
6731 pic16_emitcode(";XXX setb","c");
6732 pic16_toBoolean(right);
6734 symbol *tlbl = newiTempLabel(NULL);
6735 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6737 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6739 genIfxJump (ifx,"a");
6743 pic16_outBitC(result);
6747 /* if left is same as result */
6748 if(pic16_sameRegs(AOP(result),AOP(left))){
6750 for(;size--; offset++,lit>>=8) {
6751 if(AOP_TYPE(right) == AOP_LIT){
6752 if((lit & 0xff) == 0)
6753 /* or'ing with 0 has no effect */
6756 int p = my_powof2(lit & 0xff);
6758 /* only one bit is set in the literal, so use a bsf instruction */
6759 pic16_emitpcode(POC_BSF,
6760 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6762 if(know_W != (lit & 0xff))
6763 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6764 know_W = lit & 0xff;
6765 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6770 if (AOP_TYPE(left) == AOP_ACC) {
6771 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6772 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6774 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6775 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6777 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6778 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6784 // left & result in different registers
6785 if(AOP_TYPE(result) == AOP_CRY){
6787 // if(size), result in bit
6788 // if(!size && ifx), conditional oper: if(left | right)
6789 symbol *tlbl = newiTempLabel(NULL);
6790 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6791 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6795 pic16_emitcode(";XXX setb","c");
6797 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6798 pic16_emitcode(";XXX orl","a,%s",
6799 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6800 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6805 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6806 pic16_outBitC(result);
6808 jmpTrueOrFalse(ifx, tlbl);
6809 } else for(;(size--);offset++){
6811 // result = left & right
6812 if(AOP_TYPE(right) == AOP_LIT){
6813 int t = (lit >> (offset*8)) & 0x0FFL;
6816 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6817 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6819 pic16_emitcode("movf","%s,w",
6820 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6821 pic16_emitcode("movwf","%s",
6822 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6825 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6826 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6827 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6829 pic16_emitcode("movlw","0x%x",t);
6830 pic16_emitcode("iorwf","%s,w",
6831 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6832 pic16_emitcode("movwf","%s",
6833 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6839 // faster than result <- left, anl result,right
6840 // and better if result is SFR
6841 if (AOP_TYPE(left) == AOP_ACC) {
6842 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6843 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6845 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6846 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6848 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6849 pic16_emitcode("iorwf","%s,w",
6850 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6852 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6853 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6858 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6859 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6860 pic16_freeAsmop(result,NULL,ic,TRUE);
6863 /*-----------------------------------------------------------------*/
6864 /* genXor - code for xclusive or */
6865 /*-----------------------------------------------------------------*/
6866 static void genXor (iCode *ic, iCode *ifx)
6868 operand *left, *right, *result;
6870 unsigned long lit = 0L;
6872 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6874 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6875 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6876 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6878 /* if left is a literal & right is not ||
6879 if left needs acc & right does not */
6880 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6881 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6882 operand *tmp = right ;
6887 /* if result = right then exchange them */
6888 if(pic16_sameRegs(AOP(result),AOP(right))){
6889 operand *tmp = right ;
6894 /* if right is bit then exchange them */
6895 if (AOP_TYPE(right) == AOP_CRY &&
6896 AOP_TYPE(left) != AOP_CRY){
6897 operand *tmp = right ;
6901 if(AOP_TYPE(right) == AOP_LIT)
6902 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6904 size = AOP_SIZE(result);
6908 if (AOP_TYPE(left) == AOP_CRY){
6909 if(AOP_TYPE(right) == AOP_LIT){
6910 // c = bit & literal;
6912 // lit>>1 != 0 => result = 1
6913 if(AOP_TYPE(result) == AOP_CRY){
6915 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6916 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6918 continueIfTrue(ifx);
6921 pic16_emitcode("setb","c");
6925 // lit == 0, result = left
6926 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6928 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6930 // lit == 1, result = not(left)
6931 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6932 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6933 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6934 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6937 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6938 pic16_emitcode("cpl","c");
6945 symbol *tlbl = newiTempLabel(NULL);
6946 if (AOP_TYPE(right) == AOP_CRY){
6948 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6951 int sizer = AOP_SIZE(right);
6953 // if val>>1 != 0, result = 1
6954 pic16_emitcode("setb","c");
6956 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6958 // test the msb of the lsb
6959 pic16_emitcode("anl","a,#0xfe");
6960 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6964 pic16_emitcode("rrc","a");
6966 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6967 pic16_emitcode("cpl","c");
6968 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6973 pic16_outBitC(result);
6975 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6976 genIfxJump(ifx, "c");
6980 if(pic16_sameRegs(AOP(result),AOP(left))){
6981 /* if left is same as result */
6982 for(;size--; offset++) {
6983 if(AOP_TYPE(right) == AOP_LIT){
6984 int t = (lit >> (offset*8)) & 0x0FFL;
6988 if (IS_AOP_PREG(left)) {
6989 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6990 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6991 pic16_aopPut(AOP(result),"a",offset);
6993 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6994 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6995 pic16_emitcode("xrl","%s,%s",
6996 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6997 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7000 if (AOP_TYPE(left) == AOP_ACC)
7001 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7003 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7004 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7006 if (IS_AOP_PREG(left)) {
7007 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7008 pic16_aopPut(AOP(result),"a",offset);
7010 pic16_emitcode("xrl","%s,a",
7011 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7017 // left & result in different registers
7018 if(AOP_TYPE(result) == AOP_CRY){
7020 // if(size), result in bit
7021 // if(!size && ifx), conditional oper: if(left ^ right)
7022 symbol *tlbl = newiTempLabel(NULL);
7023 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7025 pic16_emitcode("setb","c");
7027 if((AOP_TYPE(right) == AOP_LIT) &&
7028 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
7029 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7031 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7032 pic16_emitcode("xrl","a,%s",
7033 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7035 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7040 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7041 pic16_outBitC(result);
7043 jmpTrueOrFalse(ifx, tlbl);
7044 } else for(;(size--);offset++){
7046 // result = left & right
7047 if(AOP_TYPE(right) == AOP_LIT){
7048 int t = (lit >> (offset*8)) & 0x0FFL;
7051 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7052 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7053 pic16_emitcode("movf","%s,w",
7054 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7055 pic16_emitcode("movwf","%s",
7056 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7059 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7060 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7061 pic16_emitcode("comf","%s,w",
7062 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7063 pic16_emitcode("movwf","%s",
7064 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7067 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7068 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7069 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7070 pic16_emitcode("movlw","0x%x",t);
7071 pic16_emitcode("xorwf","%s,w",
7072 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7073 pic16_emitcode("movwf","%s",
7074 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7080 // faster than result <- left, anl result,right
7081 // and better if result is SFR
7082 if (AOP_TYPE(left) == AOP_ACC) {
7083 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7084 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7086 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7087 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7088 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7089 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7091 if ( AOP_TYPE(result) != AOP_ACC){
7092 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7093 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7099 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7100 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7101 pic16_freeAsmop(result,NULL,ic,TRUE);
7104 /*-----------------------------------------------------------------*/
7105 /* genInline - write the inline code out */
7106 /*-----------------------------------------------------------------*/
7107 static void genInline (iCode *ic)
7109 char *buffer, *bp, *bp1;
7111 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7113 _G.inLine += (!options.asmpeep);
7115 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7116 strcpy(buffer,IC_INLINE(ic));
7118 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7120 /* emit each line as a code */
7126 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7134 /* print label, use this special format with NULL directive
7135 * to denote that the argument should not be indented with tab */
7136 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7143 if ((bp1 != bp) && *bp1)
7144 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7149 _G.inLine -= (!options.asmpeep);
7152 /*-----------------------------------------------------------------*/
7153 /* genRRC - rotate right with carry */
7154 /*-----------------------------------------------------------------*/
7155 static void genRRC (iCode *ic)
7157 operand *left , *result ;
7158 int size, offset = 0, same;
7160 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7162 /* rotate right with carry */
7164 result=IC_RESULT(ic);
7165 pic16_aopOp (left,ic,FALSE);
7166 pic16_aopOp (result,ic,FALSE);
7168 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7170 same = pic16_sameRegs(AOP(result),AOP(left));
7172 size = AOP_SIZE(result);
7174 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7176 /* get the lsb and put it into the carry */
7177 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7184 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7186 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7187 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7193 pic16_freeAsmop(left,NULL,ic,TRUE);
7194 pic16_freeAsmop(result,NULL,ic,TRUE);
7197 /*-----------------------------------------------------------------*/
7198 /* genRLC - generate code for rotate left with carry */
7199 /*-----------------------------------------------------------------*/
7200 static void genRLC (iCode *ic)
7202 operand *left , *result ;
7203 int size, offset = 0;
7206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7207 /* rotate right with carry */
7209 result=IC_RESULT(ic);
7210 pic16_aopOp (left,ic,FALSE);
7211 pic16_aopOp (result,ic,FALSE);
7213 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7215 same = pic16_sameRegs(AOP(result),AOP(left));
7217 /* move it to the result */
7218 size = AOP_SIZE(result);
7220 /* get the msb and put it into the carry */
7221 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7228 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7230 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7231 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7238 pic16_freeAsmop(left,NULL,ic,TRUE);
7239 pic16_freeAsmop(result,NULL,ic,TRUE);
7243 /* gpasm can get the highest order bit with HIGH/UPPER
7244 * so the following probably is not needed -- VR */
7246 /*-----------------------------------------------------------------*/
7247 /* genGetHbit - generates code get highest order bit */
7248 /*-----------------------------------------------------------------*/
7249 static void genGetHbit (iCode *ic)
7251 operand *left, *result;
7253 result=IC_RESULT(ic);
7254 pic16_aopOp (left,ic,FALSE);
7255 pic16_aopOp (result,ic,FALSE);
7257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7258 /* get the highest order byte into a */
7259 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7260 if(AOP_TYPE(result) == AOP_CRY){
7261 pic16_emitcode("rlc","a");
7262 pic16_outBitC(result);
7265 pic16_emitcode("rl","a");
7266 pic16_emitcode("anl","a,#0x01");
7267 pic16_outAcc(result);
7271 pic16_freeAsmop(left,NULL,ic,TRUE);
7272 pic16_freeAsmop(result,NULL,ic,TRUE);
7276 /*-----------------------------------------------------------------*/
7277 /* AccRol - rotate left accumulator by known count */
7278 /*-----------------------------------------------------------------*/
7279 static void AccRol (int shCount)
7281 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7282 shCount &= 0x0007; // shCount : 0..7
7287 pic16_emitcode("rl","a");
7290 pic16_emitcode("rl","a");
7291 pic16_emitcode("rl","a");
7294 pic16_emitcode("swap","a");
7295 pic16_emitcode("rr","a");
7298 pic16_emitcode("swap","a");
7301 pic16_emitcode("swap","a");
7302 pic16_emitcode("rl","a");
7305 pic16_emitcode("rr","a");
7306 pic16_emitcode("rr","a");
7309 pic16_emitcode("rr","a");
7315 /*-----------------------------------------------------------------*/
7316 /* AccLsh - left shift accumulator by known count */
7317 /*-----------------------------------------------------------------*/
7318 static void AccLsh (int shCount)
7320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7326 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7329 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7330 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7333 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7334 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7337 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7340 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7341 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7344 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7345 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7348 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7352 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7355 /*-----------------------------------------------------------------*/
7356 /* AccRsh - right shift accumulator by known count */
7357 /*-----------------------------------------------------------------*/
7358 static void AccRsh (int shCount, int andmask)
7360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7365 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7366 // andmask = 0; /* no need */
7369 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7370 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7371 // andmask = 0; /* no need */
7374 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7375 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7378 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7381 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7382 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7385 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7386 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7389 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7394 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7396 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7400 /*-----------------------------------------------------------------*/
7401 /* AccSRsh - signed right shift accumulator by known count */
7402 /*-----------------------------------------------------------------*/
7403 static void AccSRsh (int shCount)
7406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7409 pic16_emitcode("mov","c,acc.7");
7410 pic16_emitcode("rrc","a");
7411 } else if(shCount == 2){
7412 pic16_emitcode("mov","c,acc.7");
7413 pic16_emitcode("rrc","a");
7414 pic16_emitcode("mov","c,acc.7");
7415 pic16_emitcode("rrc","a");
7417 tlbl = newiTempLabel(NULL);
7418 /* rotate right accumulator */
7419 AccRol(8 - shCount);
7420 /* and kill the higher order bits */
7421 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7422 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7423 pic16_emitcode("orl","a,#0x%02x",
7424 (unsigned char)~SRMask[shCount]);
7425 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7430 /*-----------------------------------------------------------------*/
7431 /* shiftR1Left2Result - shift right one byte from left to result */
7432 /*-----------------------------------------------------------------*/
7433 static void shiftR1Left2ResultSigned (operand *left, int offl,
7434 operand *result, int offr,
7439 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7441 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7445 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7447 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7449 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7450 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7456 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7458 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7460 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7461 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7463 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7464 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7470 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7472 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7473 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7476 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7477 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7478 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7480 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7481 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7483 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7487 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7488 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7489 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7490 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7491 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7495 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7497 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7498 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7500 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7501 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7502 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7503 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7504 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7509 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7510 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7511 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7512 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7513 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7514 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7516 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7517 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7518 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7519 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7520 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
7526 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7527 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7528 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7529 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7531 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7532 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7533 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7541 /*-----------------------------------------------------------------*/
7542 /* shiftR1Left2Result - shift right one byte from left to result */
7543 /*-----------------------------------------------------------------*/
7544 static void shiftR1Left2Result (operand *left, int offl,
7545 operand *result, int offr,
7546 int shCount, int sign)
7550 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7552 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7554 /* Copy the msb into the carry if signed. */
7556 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7566 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7568 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7569 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7575 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7577 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7578 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7581 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7586 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7588 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7589 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7592 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7593 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7594 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7595 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7599 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7600 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7601 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7605 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7606 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7607 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7609 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7614 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7615 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7616 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7617 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7618 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7623 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7624 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7625 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7634 /*-----------------------------------------------------------------*/
7635 /* shiftL1Left2Result - shift left one byte from left to result */
7636 /*-----------------------------------------------------------------*/
7637 static void shiftL1Left2Result (operand *left, int offl,
7638 operand *result, int offr, int shCount)
7643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7645 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7646 DEBUGpic16_emitcode ("; ***","same = %d",same);
7647 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7649 /* shift left accumulator */
7650 //AccLsh(shCount); // don't comment out just yet...
7651 // pic16_aopPut(AOP(result),"a",offr);
7655 /* Shift left 1 bit position */
7656 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7658 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7660 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7661 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7665 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7666 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7667 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7668 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7671 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7672 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7673 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7674 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7675 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7678 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7679 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7680 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7683 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7684 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7685 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7686 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7689 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7690 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7691 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7692 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7693 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7696 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7697 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7698 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7702 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7707 /*-----------------------------------------------------------------*/
7708 /* movLeft2Result - move byte from left to result */
7709 /*-----------------------------------------------------------------*/
7710 static void movLeft2Result (operand *left, int offl,
7711 operand *result, int offr)
7714 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7715 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7716 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7718 if (*l == '@' && (IS_AOP_PREG(result))) {
7719 pic16_emitcode("mov","a,%s",l);
7720 pic16_aopPut(AOP(result),"a",offr);
7722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7723 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7728 /*-----------------------------------------------------------------*/
7729 /* shiftL2Left2Result - shift left two bytes from left to result */
7730 /*-----------------------------------------------------------------*/
7731 static void shiftL2Left2Result (operand *left, int offl,
7732 operand *result, int offr, int shCount)
7734 int same = pic16_sameRegs(AOP(result), AOP(left));
7737 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7739 if (same && (offl != offr)) { // shift bytes
7742 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7743 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7745 } else { // just treat as different later on
7758 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7759 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7760 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7764 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7765 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7771 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7772 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7773 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7774 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7775 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7776 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7777 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7779 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7780 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7784 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7785 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7786 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7787 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7788 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7789 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7790 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7791 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7792 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7793 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7796 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7797 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7798 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7799 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7800 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7810 /* note, use a mov/add for the shift since the mov has a
7811 chance of getting optimized out */
7812 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7813 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7814 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7815 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7816 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7820 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7821 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7827 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7828 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7830 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7831 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7832 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7833 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7834 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7838 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7839 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7843 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7844 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7845 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7846 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7848 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7849 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7850 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7851 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7852 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7853 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7854 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7855 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7858 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7859 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7860 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7861 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7862 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7867 /*-----------------------------------------------------------------*/
7868 /* shiftR2Left2Result - shift right two bytes from left to result */
7869 /*-----------------------------------------------------------------*/
7870 static void shiftR2Left2Result (operand *left, int offl,
7871 operand *result, int offr,
7872 int shCount, int sign)
7874 int same = pic16_sameRegs(AOP(result), AOP(left));
7876 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7878 if (same && (offl != offr)) { // shift right bytes
7881 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7882 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7884 } else { // just treat as different later on
7896 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7901 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7902 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7904 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7905 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7906 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7907 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7912 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7915 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7916 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7923 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7924 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7925 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7927 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7928 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7929 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7930 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7932 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7933 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7934 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7936 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7937 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7938 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7939 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7940 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7944 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7945 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7949 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7950 pic16_emitpcode(POC_BTFSC,
7951 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7952 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7960 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7961 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7963 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7964 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7965 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7966 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7968 pic16_emitpcode(POC_BTFSC,
7969 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7970 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7972 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7973 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7974 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7975 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7977 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7978 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7979 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7980 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7981 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7982 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7983 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7984 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7986 pic16_emitpcode(POC_BTFSC,
7987 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7988 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7990 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7991 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7998 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7999 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8000 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8001 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
8004 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
8006 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8011 /*-----------------------------------------------------------------*/
8012 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
8013 /*-----------------------------------------------------------------*/
8014 static void shiftLLeftOrResult (operand *left, int offl,
8015 operand *result, int offr, int shCount)
8017 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8020 /* shift left accumulator */
8022 /* or with result */
8023 /* back to result */
8024 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8027 /*-----------------------------------------------------------------*/
8028 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
8029 /*-----------------------------------------------------------------*/
8030 static void shiftRLeftOrResult (operand *left, int offl,
8031 operand *result, int offr, int shCount)
8033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8036 /* shift right accumulator */
8038 /* or with result */
8039 /* back to result */
8040 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8043 /*-----------------------------------------------------------------*/
8044 /* genlshOne - left shift a one byte quantity by known count */
8045 /*-----------------------------------------------------------------*/
8046 static void genlshOne (operand *result, operand *left, int shCount)
8048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8049 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8052 /*-----------------------------------------------------------------*/
8053 /* genlshTwo - left shift two bytes by known amount != 0 */
8054 /*-----------------------------------------------------------------*/
8055 static void genlshTwo (operand *result,operand *left, int shCount)
8059 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8060 size = pic16_getDataSize(result);
8062 /* if shCount >= 8 */
8068 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8070 movLeft2Result(left, LSB, result, MSB16);
8072 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8075 /* 1 <= shCount <= 7 */
8078 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8080 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8084 /*-----------------------------------------------------------------*/
8085 /* shiftLLong - shift left one long from left to result */
8086 /* offr = LSB or MSB16 */
8087 /*-----------------------------------------------------------------*/
8088 static void shiftLLong (operand *left, operand *result, int offr )
8090 int size = AOP_SIZE(result);
8091 int same = pic16_sameRegs(AOP(left),AOP(result));
8094 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8096 if (same && (offr == MSB16)) { //shift one byte
8097 for(i=size-1;i>=MSB16;i--) {
8098 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8099 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8102 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8105 if (size >= LSB+offr ){
8107 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8109 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8110 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8114 if(size >= MSB16+offr){
8116 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8118 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8119 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8123 if(size >= MSB24+offr){
8125 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8127 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8128 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8132 if(size > MSB32+offr){
8134 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8136 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8137 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8141 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8145 /*-----------------------------------------------------------------*/
8146 /* genlshFour - shift four byte by a known amount != 0 */
8147 /*-----------------------------------------------------------------*/
8148 static void genlshFour (operand *result, operand *left, int shCount)
8152 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8153 size = AOP_SIZE(result);
8155 /* if shifting more that 3 bytes */
8156 if (shCount >= 24 ) {
8159 /* lowest order of left goes to the highest
8160 order of the destination */
8161 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8163 movLeft2Result(left, LSB, result, MSB32);
8165 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8166 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8167 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8172 /* more than two bytes */
8173 else if ( shCount >= 16 ) {
8174 /* lower order two bytes goes to higher order two bytes */
8176 /* if some more remaining */
8178 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8180 movLeft2Result(left, MSB16, result, MSB32);
8181 movLeft2Result(left, LSB, result, MSB24);
8183 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8184 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8188 /* if more than 1 byte */
8189 else if ( shCount >= 8 ) {
8190 /* lower order three bytes goes to higher order three bytes */
8194 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8196 movLeft2Result(left, LSB, result, MSB16);
8198 else{ /* size = 4 */
8200 movLeft2Result(left, MSB24, result, MSB32);
8201 movLeft2Result(left, MSB16, result, MSB24);
8202 movLeft2Result(left, LSB, result, MSB16);
8203 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8205 else if(shCount == 1)
8206 shiftLLong(left, result, MSB16);
8208 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8209 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8210 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8211 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8216 /* 1 <= shCount <= 7 */
8217 else if(shCount <= 3)
8219 shiftLLong(left, result, LSB);
8220 while(--shCount >= 1)
8221 shiftLLong(result, result, LSB);
8223 /* 3 <= shCount <= 7, optimize */
8225 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8226 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8227 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8231 /*-----------------------------------------------------------------*/
8232 /* genLeftShiftLiteral - left shifting by known count */
8233 /*-----------------------------------------------------------------*/
8234 static void genLeftShiftLiteral (operand *left,
8239 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8242 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8243 pic16_freeAsmop(right,NULL,ic,TRUE);
8245 pic16_aopOp(left,ic,FALSE);
8246 pic16_aopOp(result,ic,FALSE);
8248 size = getSize(operandType(result));
8251 pic16_emitcode("; shift left ","result %d, left %d",size,
8255 /* I suppose that the left size >= result size */
8258 movLeft2Result(left, size, result, size);
8262 else if(shCount >= (size * 8))
8264 pic16_aopPut(AOP(result),zero,size);
8268 genlshOne (result,left,shCount);
8273 genlshTwo (result,left,shCount);
8277 genlshFour (result,left,shCount);
8281 pic16_freeAsmop(left,NULL,ic,TRUE);
8282 pic16_freeAsmop(result,NULL,ic,TRUE);
8285 /*-----------------------------------------------------------------*
8286 * genMultiAsm - repeat assembly instruction for size of register.
8287 * if endian == 1, then the high byte (i.e base address + size of
8288 * register) is used first else the low byte is used first;
8289 *-----------------------------------------------------------------*/
8290 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8308 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8313 /*-----------------------------------------------------------------*/
8314 /* genLeftShift - generates code for left shifting */
8315 /*-----------------------------------------------------------------*/
8316 static void genLeftShift (iCode *ic)
8318 operand *left,*right, *result;
8321 symbol *tlbl , *tlbl1;
8324 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8326 right = IC_RIGHT(ic);
8328 result = IC_RESULT(ic);
8330 pic16_aopOp(right,ic,FALSE);
8332 /* if the shift count is known then do it
8333 as efficiently as possible */
8334 if (AOP_TYPE(right) == AOP_LIT) {
8335 genLeftShiftLiteral (left,right,result,ic);
8339 /* shift count is unknown then we have to form
8340 a loop get the loop count in B : Note: we take
8341 only the lower order byte since shifting
8342 more that 32 bits make no sense anyway, ( the
8343 largest size of an object can be only 32 bits ) */
8346 pic16_aopOp(left,ic,FALSE);
8347 pic16_aopOp(result,ic,FALSE);
8349 /* now move the left to the result if they are not the
8351 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8352 AOP_SIZE(result) > 1) {
8354 size = AOP_SIZE(result);
8357 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8358 if (*l == '@' && (IS_AOP_PREG(result))) {
8360 pic16_emitcode("mov","a,%s",l);
8361 pic16_aopPut(AOP(result),"a",offset);
8363 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8364 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8365 //pic16_aopPut(AOP(result),l,offset);
8371 size = AOP_SIZE(result);
8373 /* if it is only one byte then */
8375 if(optimized_for_speed) {
8376 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8377 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8378 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
8379 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8380 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8381 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
8382 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8383 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8384 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8385 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8386 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
8387 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8390 tlbl = newiTempLabel(NULL);
8391 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8392 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8393 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8396 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8397 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8398 pic16_emitpLabel(tlbl->key);
8399 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8400 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8402 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8407 if (pic16_sameRegs(AOP(left),AOP(result))) {
8409 tlbl = newiTempLabel(NULL);
8410 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8411 genMultiAsm(POC_RRCF, result, size,1);
8412 pic16_emitpLabel(tlbl->key);
8413 genMultiAsm(POC_RLCF, result, size,0);
8414 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8416 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8420 //tlbl = newiTempLabel(NULL);
8422 //tlbl1 = newiTempLabel(NULL);
8424 //reAdjustPreg(AOP(result));
8426 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8427 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8428 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8430 //pic16_emitcode("add","a,acc");
8431 //pic16_aopPut(AOP(result),"a",offset++);
8433 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8435 // pic16_emitcode("rlc","a");
8436 // pic16_aopPut(AOP(result),"a",offset++);
8438 //reAdjustPreg(AOP(result));
8440 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8441 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8444 tlbl = newiTempLabel(NULL);
8445 tlbl1= newiTempLabel(NULL);
8447 size = AOP_SIZE(result);
8450 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8452 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8454 /* offset should be 0, 1 or 3 */
8456 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8458 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8460 pic16_emitpcode(POC_MOVWF, pctemp);
8463 pic16_emitpLabel(tlbl->key);
8466 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8468 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8470 pic16_emitpcode(POC_DECFSZ, pctemp);
8471 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8472 pic16_emitpLabel(tlbl1->key);
8474 pic16_popReleaseTempReg(pctemp);
8478 pic16_freeAsmop (right,NULL,ic,TRUE);
8479 pic16_freeAsmop(left,NULL,ic,TRUE);
8480 pic16_freeAsmop(result,NULL,ic,TRUE);
8483 /*-----------------------------------------------------------------*/
8484 /* genrshOne - right shift a one byte quantity by known count */
8485 /*-----------------------------------------------------------------*/
8486 static void genrshOne (operand *result, operand *left,
8487 int shCount, int sign)
8489 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8490 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8493 /*-----------------------------------------------------------------*/
8494 /* genrshTwo - right shift two bytes by known amount != 0 */
8495 /*-----------------------------------------------------------------*/
8496 static void genrshTwo (operand *result,operand *left,
8497 int shCount, int sign)
8499 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8500 /* if shCount >= 8 */
8504 shiftR1Left2Result(left, MSB16, result, LSB,
8507 movLeft2Result(left, MSB16, result, LSB);
8509 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8512 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
8513 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8517 /* 1 <= shCount <= 7 */
8519 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8522 /*-----------------------------------------------------------------*/
8523 /* shiftRLong - shift right one long from left to result */
8524 /* offl = LSB or MSB16 */
8525 /*-----------------------------------------------------------------*/
8526 static void shiftRLong (operand *left, int offl,
8527 operand *result, int sign)
8529 int size = AOP_SIZE(result);
8530 int same = pic16_sameRegs(AOP(left),AOP(result));
8532 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8534 if (same && (offl == MSB16)) { //shift one byte right
8535 for(i=MSB16;i<size;i++) {
8536 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8537 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8542 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8548 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8550 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8551 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
8555 /* add sign of "a" */
8556 pic16_addSign(result, MSB32, sign);
8560 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
8562 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
8563 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
8567 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
8569 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
8570 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
8574 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
8577 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
8578 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
8583 /*-----------------------------------------------------------------*/
8584 /* genrshFour - shift four byte by a known amount != 0 */
8585 /*-----------------------------------------------------------------*/
8586 static void genrshFour (operand *result, operand *left,
8587 int shCount, int sign)
8589 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8590 /* if shifting more that 3 bytes */
8591 if(shCount >= 24 ) {
8594 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8596 movLeft2Result(left, MSB32, result, LSB);
8598 pic16_addSign(result, MSB16, sign);
8600 else if(shCount >= 16){
8603 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8605 movLeft2Result(left, MSB24, result, LSB);
8606 movLeft2Result(left, MSB32, result, MSB16);
8608 pic16_addSign(result, MSB24, sign);
8610 else if(shCount >= 8){
8613 shiftRLong(left, MSB16, result, sign);
8614 else if(shCount == 0){
8615 movLeft2Result(left, MSB16, result, LSB);
8616 movLeft2Result(left, MSB24, result, MSB16);
8617 movLeft2Result(left, MSB32, result, MSB24);
8618 pic16_addSign(result, MSB32, sign);
8620 else{ //shcount >= 2
8621 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8622 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8623 /* the last shift is signed */
8624 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8625 pic16_addSign(result, MSB32, sign);
8628 else{ /* 1 <= shCount <= 7 */
8630 shiftRLong(left, LSB, result, sign);
8632 shiftRLong(result, LSB, result, sign);
8635 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8636 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8637 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8642 /*-----------------------------------------------------------------*/
8643 /* genRightShiftLiteral - right shifting by known count */
8644 /*-----------------------------------------------------------------*/
8645 static void genRightShiftLiteral (operand *left,
8651 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8654 pic16_freeAsmop(right,NULL,ic,TRUE);
8656 pic16_aopOp(left,ic,FALSE);
8657 pic16_aopOp(result,ic,FALSE);
8659 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8662 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8666 lsize = pic16_getDataSize(left);
8667 res_size = pic16_getDataSize(result);
8668 /* test the LEFT size !!! */
8670 /* I suppose that the left size >= result size */
8673 movLeft2Result(left, lsize, result, res_size);
8676 else if(shCount >= (lsize * 8)){
8679 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8681 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8682 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8687 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8688 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8689 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8691 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8696 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8703 genrshOne (result,left,shCount,sign);
8707 genrshTwo (result,left,shCount,sign);
8711 genrshFour (result,left,shCount,sign);
8719 pic16_freeAsmop(left,NULL,ic,TRUE);
8720 pic16_freeAsmop(result,NULL,ic,TRUE);
8723 /*-----------------------------------------------------------------*/
8724 /* genSignedRightShift - right shift of signed number */
8725 /*-----------------------------------------------------------------*/
8726 static void genSignedRightShift (iCode *ic)
8728 operand *right, *left, *result;
8731 symbol *tlbl, *tlbl1 ;
8734 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8736 /* we do it the hard way put the shift count in b
8737 and loop thru preserving the sign */
8738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8740 right = IC_RIGHT(ic);
8742 result = IC_RESULT(ic);
8744 pic16_aopOp(right,ic,FALSE);
8745 pic16_aopOp(left,ic,FALSE);
8746 pic16_aopOp(result,ic,FALSE);
8749 if ( AOP_TYPE(right) == AOP_LIT) {
8750 genRightShiftLiteral (left,right,result,ic,1);
8753 /* shift count is unknown then we have to form
8754 a loop get the loop count in B : Note: we take
8755 only the lower order byte since shifting
8756 more that 32 bits make no sense anyway, ( the
8757 largest size of an object can be only 32 bits ) */
8759 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8760 //pic16_emitcode("inc","b");
8761 //pic16_freeAsmop (right,NULL,ic,TRUE);
8762 //pic16_aopOp(left,ic,FALSE);
8763 //pic16_aopOp(result,ic,FALSE);
8765 /* now move the left to the result if they are not the
8767 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8768 AOP_SIZE(result) > 1) {
8770 size = AOP_SIZE(result);
8774 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8775 if (*l == '@' && IS_AOP_PREG(result)) {
8777 pic16_emitcode("mov","a,%s",l);
8778 pic16_aopPut(AOP(result),"a",offset);
8780 pic16_aopPut(AOP(result),l,offset);
8782 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8789 /* mov the highest order bit to OVR */
8790 tlbl = newiTempLabel(NULL);
8791 tlbl1= newiTempLabel(NULL);
8793 size = AOP_SIZE(result);
8796 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8798 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8800 /* offset should be 0, 1 or 3 */
8801 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8803 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8805 pic16_emitpcode(POC_MOVWF, pctemp);
8808 pic16_emitpLabel(tlbl->key);
8810 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8811 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8814 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8817 pic16_emitpcode(POC_DECFSZ, pctemp);
8818 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8819 pic16_emitpLabel(tlbl1->key);
8821 pic16_popReleaseTempReg(pctemp);
8823 size = AOP_SIZE(result);
8825 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8826 pic16_emitcode("rlc","a");
8827 pic16_emitcode("mov","ov,c");
8828 /* if it is only one byte then */
8830 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8832 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8833 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8834 pic16_emitcode("mov","c,ov");
8835 pic16_emitcode("rrc","a");
8836 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8837 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8838 pic16_aopPut(AOP(result),"a",0);
8842 reAdjustPreg(AOP(result));
8843 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8844 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8845 pic16_emitcode("mov","c,ov");
8847 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8849 pic16_emitcode("rrc","a");
8850 pic16_aopPut(AOP(result),"a",offset--);
8852 reAdjustPreg(AOP(result));
8853 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8854 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8859 pic16_freeAsmop(left,NULL,ic,TRUE);
8860 pic16_freeAsmop(result,NULL,ic,TRUE);
8861 pic16_freeAsmop(right,NULL,ic,TRUE);
8864 /*-----------------------------------------------------------------*/
8865 /* genRightShift - generate code for right shifting */
8866 /*-----------------------------------------------------------------*/
8867 static void genRightShift (iCode *ic)
8869 operand *right, *left, *result;
8873 symbol *tlbl, *tlbl1 ;
8875 /* if signed then we do it the hard way preserve the
8876 sign bit moving it inwards */
8877 letype = getSpec(operandType(IC_LEFT(ic)));
8878 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8880 if (!SPEC_USIGN(letype)) {
8881 genSignedRightShift (ic);
8885 /* signed & unsigned types are treated the same : i.e. the
8886 signed is NOT propagated inwards : quoting from the
8887 ANSI - standard : "for E1 >> E2, is equivalent to division
8888 by 2**E2 if unsigned or if it has a non-negative value,
8889 otherwise the result is implementation defined ", MY definition
8890 is that the sign does not get propagated */
8892 right = IC_RIGHT(ic);
8894 result = IC_RESULT(ic);
8896 pic16_aopOp(right,ic,FALSE);
8898 /* if the shift count is known then do it
8899 as efficiently as possible */
8900 if (AOP_TYPE(right) == AOP_LIT) {
8901 genRightShiftLiteral (left,right,result,ic, 0);
8905 /* shift count is unknown then we have to form
8906 a loop get the loop count in B : Note: we take
8907 only the lower order byte since shifting
8908 more that 32 bits make no sense anyway, ( the
8909 largest size of an object can be only 32 bits ) */
8911 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8912 pic16_emitcode("inc","b");
8913 pic16_aopOp(left,ic,FALSE);
8914 pic16_aopOp(result,ic,FALSE);
8916 /* now move the left to the result if they are not the
8918 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8919 AOP_SIZE(result) > 1) {
8921 size = AOP_SIZE(result);
8924 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8925 if (*l == '@' && IS_AOP_PREG(result)) {
8927 pic16_emitcode("mov","a,%s",l);
8928 pic16_aopPut(AOP(result),"a",offset);
8930 pic16_aopPut(AOP(result),l,offset);
8935 tlbl = newiTempLabel(NULL);
8936 tlbl1= newiTempLabel(NULL);
8937 size = AOP_SIZE(result);
8940 /* if it is only one byte then */
8943 tlbl = newiTempLabel(NULL);
8944 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8945 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8946 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8949 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8950 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8951 pic16_emitpLabel(tlbl->key);
8952 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8953 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8955 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8960 reAdjustPreg(AOP(result));
8961 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8962 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8965 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8967 pic16_emitcode("rrc","a");
8968 pic16_aopPut(AOP(result),"a",offset--);
8970 reAdjustPreg(AOP(result));
8972 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8973 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8976 pic16_freeAsmop(left,NULL,ic,TRUE);
8977 pic16_freeAsmop (right,NULL,ic,TRUE);
8978 pic16_freeAsmop(result,NULL,ic,TRUE);
8981 /*-----------------------------------------------------------------*/
8982 /* genUnpackBits - generates code for unpacking bits */
8983 /*-----------------------------------------------------------------*/
8984 static void genUnpackBits (operand *result, char *rname, int ptype)
8991 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8992 etype = getSpec(operandType(result));
8994 /* read the first byte */
9001 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9004 pic16_emitcode("clr","a");
9005 pic16_emitcode("movc","a","@a+dptr");
9010 /* if we have bitdisplacement then it fits */
9011 /* into this byte completely or if length is */
9012 /* less than a byte */
9013 if ((shCnt = SPEC_BSTR(etype)) ||
9014 (SPEC_BLEN(etype) <= 8)) {
9016 /* shift right acc */
9019 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9020 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
9022 /* VR -- normally I would use the following, but since we use the hack,
9023 * to avoid the masking from AccRsh, why not mask it right now? */
9026 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
9029 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9035 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9036 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9039 /* bit field did not fit in a byte */
9040 rlen = SPEC_BLEN(etype) - 8;
9041 pic16_aopPut(AOP(result),"a",offset++);
9048 pic16_emitcode("inc","%s",rname);
9049 pic16_emitcode("mov","a,@%s",rname);
9053 pic16_emitcode("inc","%s",rname);
9054 pic16_emitcode("movx","a,@%s",rname);
9058 pic16_emitcode("inc","dptr");
9059 pic16_emitcode("movx","a,@dptr");
9063 pic16_emitcode("clr","a");
9064 pic16_emitcode("inc","dptr");
9065 pic16_emitcode("movc","a","@a+dptr");
9069 pic16_emitcode("inc","dptr");
9070 pic16_emitcode("lcall","__gptrget");
9075 /* if we are done */
9079 pic16_aopPut(AOP(result),"a",offset++);
9084 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9085 pic16_aopPut(AOP(result),"a",offset);
9092 static void genDataPointerGet(operand *left,
9096 int size, offset = 0, leoffset=0 ;
9098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9099 pic16_aopOp(result, ic, FALSE);
9101 size = AOP_SIZE(result);
9102 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9106 /* The following tests may save a redudant movff instruction when
9107 * accessing unions */
9109 /* if they are the same */
9110 if (operandsEqu (left, result)) {
9111 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9117 /* if they are the same registers */
9118 if (pic16_sameRegs(AOP(left),AOP(result))) {
9119 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9125 if ( AOP_TYPE(left) == AOP_PCODE) {
9126 fprintf(stderr,"genDataPointerGet %s, %d\n",
9127 AOP(left)->aopu.pcop->name,
9128 (AOP(left)->aopu.pcop->type == PO_DIR)?
9129 PCOR(AOP(left)->aopu.pcop)->instance:
9130 PCOI(AOP(left)->aopu.pcop)->offset);
9134 if(AOP(left)->aopu.pcop->type == PO_DIR)
9135 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
9137 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9140 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
9142 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
9143 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
9144 mov2w(AOP(left), offset); // patch 8
9145 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
9147 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
9148 pic16_popGet(AOP(left), offset), //patch 8
9149 pic16_popGet(AOP(result), offset)));
9157 pic16_freeAsmop(result,NULL,ic,TRUE);
9160 void pic16_loadFSR0(operand *op)
9162 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9166 /*-----------------------------------------------------------------*/
9167 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
9168 /*-----------------------------------------------------------------*/
9169 static void genNearPointerGet (operand *left,
9174 //regs *preg = NULL ;
9175 sym_link *rtype, *retype;
9176 sym_link *ltype = operandType(left);
9178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9179 rtype = operandType(result);
9180 retype= getSpec(rtype);
9182 pic16_aopOp(left,ic,FALSE);
9184 pic16_DumpOp("(left)",left);
9185 pic16_DumpOp("(result)",result);
9187 /* if left is rematerialisable and
9188 * result is not bit variable type and
9189 * the left is pointer to data space i.e
9190 * lower 128 bytes of space */
9191 if (AOP_TYPE(left) == AOP_PCODE
9192 && !IS_BITFIELD(retype)
9193 && DCL_TYPE(ltype) == POINTER) {
9195 genDataPointerGet (left,result,ic);
9196 pic16_freeAsmop(left, NULL, ic, TRUE);
9200 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9202 /* if the value is already in a pointer register
9203 * then don't need anything more */
9204 if (!AOP_INPREG(AOP(left))) {
9205 /* otherwise get a free pointer register */
9206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9208 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9209 if( (AOP_TYPE(left) == AOP_PCODE)
9210 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9211 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9213 pic16_loadFSR0( left ); // patch 10
9215 // set up FSR0 with address from left
9216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9217 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9221 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9223 pic16_aopOp (result,ic,FALSE);
9225 /* if bitfield then unpack the bits */
9226 if (IS_BITFIELD(retype))
9227 genUnpackBits (result, NULL, POINTER);
9229 /* we have can just get the values */
9230 int size = AOP_SIZE(result);
9233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9236 /* fsr0 is loaded already -- VR */
9237 // pic16_loadFSR0( left );
9239 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9240 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9244 pic16_emitpcode(POC_MOVFF,
9245 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9246 pic16_popGet(AOP(result), offset++)));
9248 pic16_emitpcode(POC_MOVFF,
9249 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9250 pic16_popGet(AOP(result), offset++)));
9254 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9255 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9257 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9261 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9263 pic16_emitcode("mov","a,@%s",rname);
9264 pic16_aopPut(AOP(result),"a",offset);
9266 sprintf(buffer,"@%s",rname);
9267 pic16_aopPut(AOP(result),buffer,offset);
9271 pic16_emitcode("inc","%s",rname);
9276 /* now some housekeeping stuff */
9278 /* we had to allocate for this iCode */
9279 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9280 pic16_freeAsmop(NULL,aop,ic,TRUE);
9282 /* we did not allocate which means left
9283 already in a pointer register, then
9284 if size > 0 && this could be used again
9285 we have to point it back to where it
9287 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9288 if (AOP_SIZE(result) > 1 &&
9289 !OP_SYMBOL(left)->remat &&
9290 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9292 // int size = AOP_SIZE(result) - 1;
9294 // pic16_emitcode("dec","%s",rname);
9299 pic16_freeAsmop(left,NULL,ic,TRUE);
9300 pic16_freeAsmop(result,NULL,ic,TRUE);
9304 /*-----------------------------------------------------------------*/
9305 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9306 /*-----------------------------------------------------------------*/
9307 static void genPagedPointerGet (operand *left,
9314 sym_link *rtype, *retype;
9316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9318 rtype = operandType(result);
9319 retype= getSpec(rtype);
9321 pic16_aopOp(left,ic,FALSE);
9323 /* if the value is already in a pointer register
9324 then don't need anything more */
9325 if (!AOP_INPREG(AOP(left))) {
9326 /* otherwise get a free pointer register */
9328 preg = getFreePtr(ic,&aop,FALSE);
9329 pic16_emitcode("mov","%s,%s",
9331 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9332 rname = preg->name ;
9334 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9336 pic16_freeAsmop(left,NULL,ic,TRUE);
9337 pic16_aopOp (result,ic,FALSE);
9339 /* if bitfield then unpack the bits */
9340 if (IS_BITFIELD(retype))
9341 genUnpackBits (result,rname,PPOINTER);
9343 /* we have can just get the values */
9344 int size = AOP_SIZE(result);
9349 pic16_emitcode("movx","a,@%s",rname);
9350 pic16_aopPut(AOP(result),"a",offset);
9355 pic16_emitcode("inc","%s",rname);
9359 /* now some housekeeping stuff */
9361 /* we had to allocate for this iCode */
9362 pic16_freeAsmop(NULL,aop,ic,TRUE);
9364 /* we did not allocate which means left
9365 already in a pointer register, then
9366 if size > 0 && this could be used again
9367 we have to point it back to where it
9369 if (AOP_SIZE(result) > 1 &&
9370 !OP_SYMBOL(left)->remat &&
9371 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9373 int size = AOP_SIZE(result) - 1;
9375 pic16_emitcode("dec","%s",rname);
9380 pic16_freeAsmop(result,NULL,ic,TRUE);
9385 /*-----------------------------------------------------------------*/
9386 /* genFarPointerGet - gget value from far space */
9387 /*-----------------------------------------------------------------*/
9388 static void genFarPointerGet (operand *left,
9389 operand *result, iCode *ic)
9392 sym_link *retype = getSpec(operandType(result));
9394 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9396 pic16_aopOp(left,ic,FALSE);
9398 /* if the operand is already in dptr
9399 then we do nothing else we move the value to dptr */
9400 if (AOP_TYPE(left) != AOP_STR) {
9401 /* if this is remateriazable */
9402 if (AOP_TYPE(left) == AOP_IMMD)
9403 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9404 else { /* we need to get it byte by byte */
9405 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9406 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9407 if (options.model == MODEL_FLAT24)
9409 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9413 /* so dptr know contains the address */
9414 pic16_freeAsmop(left,NULL,ic,TRUE);
9415 pic16_aopOp(result,ic,FALSE);
9417 /* if bit then unpack */
9418 if (IS_BITFIELD(retype))
9419 genUnpackBits(result,"dptr",FPOINTER);
9421 size = AOP_SIZE(result);
9425 pic16_emitcode("movx","a,@dptr");
9426 pic16_aopPut(AOP(result),"a",offset++);
9428 pic16_emitcode("inc","dptr");
9432 pic16_freeAsmop(result,NULL,ic,TRUE);
9435 /*-----------------------------------------------------------------*/
9436 /* genCodePointerGet - get value from code space */
9437 /*-----------------------------------------------------------------*/
9438 static void genCodePointerGet (operand *left,
9439 operand *result, iCode *ic)
9442 sym_link *retype = getSpec(operandType(result));
9444 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9446 pic16_aopOp(left,ic,FALSE);
9448 /* if the operand is already in dptr
9449 then we do nothing else we move the value to dptr */
9450 if (AOP_TYPE(left) != AOP_STR) {
9451 /* if this is remateriazable */
9452 if (AOP_TYPE(left) == AOP_IMMD)
9453 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9454 else { /* we need to get it byte by byte */
9455 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9456 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9457 if (options.model == MODEL_FLAT24)
9459 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9463 /* so dptr know contains the address */
9464 pic16_freeAsmop(left,NULL,ic,TRUE);
9465 pic16_aopOp(result,ic,FALSE);
9467 /* if bit then unpack */
9468 if (IS_BITFIELD(retype))
9469 genUnpackBits(result,"dptr",CPOINTER);
9471 size = AOP_SIZE(result);
9475 pic16_emitcode("clr","a");
9476 pic16_emitcode("movc","a,@a+dptr");
9477 pic16_aopPut(AOP(result),"a",offset++);
9479 pic16_emitcode("inc","dptr");
9483 pic16_freeAsmop(result,NULL,ic,TRUE);
9486 /*-----------------------------------------------------------------*/
9487 /* genGenPointerGet - gget value from generic pointer space */
9488 /*-----------------------------------------------------------------*/
9489 static void genGenPointerGet (operand *left,
9490 operand *result, iCode *ic)
9492 int size, offset, lit;
9493 sym_link *retype = getSpec(operandType(result));
9495 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9496 pic16_aopOp(left,ic,FALSE);
9497 pic16_aopOp(result,ic,FALSE);
9498 size = AOP_SIZE(result);
9500 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9502 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9504 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9505 // load FSR0 from immediate
9506 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9508 // pic16_loadFSR0( left );
9513 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9515 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9522 else { /* we need to get it byte by byte */
9523 // set up FSR0 with address from left
9524 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9525 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9531 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9533 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9540 /* if bit then unpack */
9541 if (IS_BITFIELD(retype))
9542 genUnpackBits(result,"BAD",GPOINTER);
9545 pic16_freeAsmop(left,NULL,ic,TRUE);
9546 pic16_freeAsmop(result,NULL,ic,TRUE);
9550 /*-----------------------------------------------------------------*/
9551 /* genConstPointerGet - get value from const generic pointer space */
9552 /*-----------------------------------------------------------------*/
9553 static void genConstPointerGet (operand *left,
9554 operand *result, iCode *ic)
9556 //sym_link *retype = getSpec(operandType(result));
9557 // symbol *albl = newiTempLabel(NULL); // patch 15
9558 // symbol *blbl = newiTempLabel(NULL); //
9559 // PIC_OPCODE poc; // patch 15
9563 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9564 pic16_aopOp(left,ic,FALSE);
9565 pic16_aopOp(result,ic,TRUE);
9566 size = AOP_SIZE(result);
9568 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9570 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
9572 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
9573 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
9574 pic16_emitpLabel(albl->key);
9576 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
9578 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
9579 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
9580 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
9581 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
9582 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
9584 pic16_emitpLabel(blbl->key);
9586 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
9590 // set up table pointer
9591 if( (AOP_TYPE(left) == AOP_PCODE)
9592 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9593 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
9595 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
9596 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
9597 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
9598 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
9599 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
9600 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
9604 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
9605 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
9606 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
9612 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
9613 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
9617 pic16_freeAsmop(left,NULL,ic,TRUE);
9618 pic16_freeAsmop(result,NULL,ic,TRUE);
9621 /*-----------------------------------------------------------------*/
9622 /* genPointerGet - generate code for pointer get */
9623 /*-----------------------------------------------------------------*/
9624 static void genPointerGet (iCode *ic)
9626 operand *left, *result ;
9627 sym_link *type, *etype;
9630 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9633 result = IC_RESULT(ic) ;
9635 /* depending on the type of pointer we need to
9636 move it to the correct pointer register */
9637 type = operandType(left);
9638 etype = getSpec(type);
9641 if (IS_PTR_CONST(type))
9643 if (IS_CODEPTR(type))
9645 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9647 /* if left is of type of pointer then it is simple */
9648 if (IS_PTR(type) && !IS_FUNC(type->next))
9649 p_type = DCL_TYPE(type);
9651 /* we have to go by the storage class */
9652 p_type = PTR_TYPE(SPEC_OCLS(etype));
9654 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9656 if (SPEC_OCLS(etype)->codesp ) {
9657 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9658 //p_type = CPOINTER ;
9661 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9662 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9663 /*p_type = FPOINTER ;*/
9665 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9666 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9667 /* p_type = PPOINTER; */
9669 if (SPEC_OCLS(etype) == idata )
9670 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9671 /* p_type = IPOINTER; */
9673 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9674 /* p_type = POINTER ; */
9677 /* now that we have the pointer type we assign
9678 the pointer values */
9683 genNearPointerGet (left,result,ic);
9687 genPagedPointerGet(left,result,ic);
9691 genFarPointerGet (left,result,ic);
9695 genConstPointerGet (left,result,ic);
9696 //pic16_emitcodePointerGet (left,result,ic);
9701 if (IS_PTR_CONST(type))
9702 genConstPointerGet (left,result,ic);
9705 genGenPointerGet (left,result,ic);
9711 /*-----------------------------------------------------------------*/
9712 /* genPackBits - generates code for packed bit storage */
9713 /*-----------------------------------------------------------------*/
9714 static void genPackBits (sym_link *etype ,
9716 char *rname, int p_type)
9724 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9725 blen = SPEC_BLEN(etype);
9726 bstr = SPEC_BSTR(etype);
9728 if(AOP_TYPE(right) == AOP_LIT) {
9729 if((blen == 1) && (bstr < 8)) {
9731 /* it is a single bit, so use the appropriate bit instructions */
9733 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
9735 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9736 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9738 pic16_emitpcode(POC_BSF,
9739 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
9741 pic16_emitpcode(POC_BCF,
9742 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
9748 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9751 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9753 /* if the bit lenth is less than or */
9754 /* it exactly fits a byte then */
9755 if((shCnt=SPEC_BSTR(etype))
9756 || SPEC_BLEN(etype) <= 8 ) {
9758 /* shift left acc */
9761 /* using PRODL as a temporary register here */
9762 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9768 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9769 // pic16_emitcode ("mov","b,a");
9770 // pic16_emitcode("mov","a,@%s",rname);
9774 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9775 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9776 (unsigned char)(0xff >> (8-bstr))) ));
9777 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9778 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9785 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9786 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9791 if ( SPEC_BLEN(etype) <= 8 )
9794 pic16_emitcode("inc","%s",rname);
9795 rLen = SPEC_BLEN(etype) ;
9799 /* now generate for lengths greater than one byte */
9802 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9812 pic16_emitcode("mov","@%s,a",rname);
9814 pic16_emitcode("mov","@%s,%s",rname,l);
9819 pic16_emitcode("movx","@dptr,a");
9824 DEBUGpic16_emitcode(";lcall","__gptrput");
9827 pic16_emitcode ("inc","%s",rname);
9832 /* last last was not complete */
9834 /* save the byte & read byte */
9837 pic16_emitcode ("mov","b,a");
9838 pic16_emitcode("mov","a,@%s",rname);
9842 pic16_emitcode ("mov","b,a");
9843 pic16_emitcode("movx","a,@dptr");
9847 pic16_emitcode ("push","b");
9848 pic16_emitcode ("push","acc");
9849 pic16_emitcode ("lcall","__gptrget");
9850 pic16_emitcode ("pop","b");
9854 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9855 pic16_emitcode ("orl","a,b");
9858 if (p_type == GPOINTER)
9859 pic16_emitcode("pop","b");
9864 pic16_emitcode("mov","@%s,a",rname);
9868 pic16_emitcode("movx","@dptr,a");
9872 DEBUGpic16_emitcode(";lcall","__gptrput");
9876 /*-----------------------------------------------------------------*/
9877 /* genDataPointerSet - remat pointer to data space */
9878 /*-----------------------------------------------------------------*/
9879 static void genDataPointerSet(operand *right,
9883 int size, offset = 0, resoffset=0 ;
9885 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9886 pic16_aopOp(right,ic,FALSE);
9888 size = AOP_SIZE(right);
9890 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9893 if ( AOP_TYPE(result) == AOP_PCODE) {
9894 fprintf(stderr,"genDataPointerSet %s, %d\n",
9895 AOP(result)->aopu.pcop->name,
9896 (AOP(result)->aopu.pcop->type == PO_DIR)?
9897 PCOR(AOP(result)->aopu.pcop)->instance:
9898 PCOI(AOP(result)->aopu.pcop)->offset);
9902 if(AOP(result)->aopu.pcop->type == PO_DIR)
9903 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9906 if (AOP_TYPE(right) == AOP_LIT) {
9907 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9909 lit = lit >> (8*offset);
9911 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9912 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
9914 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
9917 mov2w(AOP(right), offset);
9918 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
9924 pic16_freeAsmop(right,NULL,ic,TRUE);
9929 /*-----------------------------------------------------------------*/
9930 /* genNearPointerSet - pic16_emitcode for near pointer put */
9931 /*-----------------------------------------------------------------*/
9932 static void genNearPointerSet (operand *right,
9939 sym_link *ptype = operandType(result);
9942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9943 retype= getSpec(operandType(right));
9944 resetype = getSpec(operandType(result));
9946 pic16_aopOp(result,ic,FALSE);
9948 /* if the result is rematerializable &
9949 * in data space & not a bit variable */
9951 /* and result is not a bit variable */
9952 if (AOP_TYPE(result) == AOP_PCODE
9953 // && AOP_TYPE(result) == AOP_IMMD
9954 && DCL_TYPE(ptype) == POINTER
9955 && !IS_BITFIELD(retype)
9956 && !IS_BITFIELD(resetype)) {
9958 genDataPointerSet (right,result,ic);
9959 pic16_freeAsmop(result,NULL,ic,TRUE);
9963 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9964 pic16_aopOp(right,ic,FALSE);
9965 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9967 /* if the value is already in a pointer register
9968 * then don't need anything more */
9969 if (!AOP_INPREG(AOP(result))) {
9970 /* otherwise get a free pointer register */
9971 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9973 if( (AOP_TYPE(result) == AOP_PCODE)
9974 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
9975 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
9977 pic16_loadFSR0( result ); // patch 10
9979 // set up FSR0 with address of result
9980 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9981 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9986 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9990 /* if bitfield then unpack the bits */
9991 if (IS_BITFIELD(resetype)) {
9992 genPackBits (resetype, right, NULL, POINTER);
9994 /* we have can just get the values */
9995 int size = AOP_SIZE(right);
9998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10000 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10003 //pic16_emitcode("mov","@%s,a",rname);
10004 pic16_emitcode("movf","indf0,w ;1");
10007 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
10008 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
10010 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
10012 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
10014 } else { // no literal //
10016 pic16_emitpcode(POC_MOVFF, //
10017 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10018 pic16_popCopyReg(&pic16_pc_postinc0))); //
10020 pic16_emitpcode(POC_MOVFF, //
10021 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10022 pic16_popCopyReg(&pic16_pc_indf0))); //
10030 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10031 /* now some housekeeping stuff */
10033 /* we had to allocate for this iCode */
10034 pic16_freeAsmop(NULL,aop,ic,TRUE);
10036 /* we did not allocate which means left
10037 * already in a pointer register, then
10038 * if size > 0 && this could be used again
10039 * we have to point it back to where it
10041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10042 if (AOP_SIZE(right) > 1
10043 && !OP_SYMBOL(result)->remat
10044 && ( OP_SYMBOL(result)->liveTo > ic->seq
10047 int size = AOP_SIZE(right) - 1;
10050 pic16_emitcode("decf","fsr0,f");
10051 //pic16_emitcode("dec","%s",rname);
10055 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10058 pic16_freeAsmop(right,NULL,ic,TRUE);
10059 pic16_freeAsmop(result,NULL,ic,TRUE);
10062 /*-----------------------------------------------------------------*/
10063 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
10064 /*-----------------------------------------------------------------*/
10065 static void genPagedPointerSet (operand *right,
10070 regs *preg = NULL ;
10074 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10076 retype= getSpec(operandType(right));
10078 pic16_aopOp(result,ic,FALSE);
10080 /* if the value is already in a pointer register
10081 then don't need anything more */
10082 if (!AOP_INPREG(AOP(result))) {
10083 /* otherwise get a free pointer register */
10085 preg = getFreePtr(ic,&aop,FALSE);
10086 pic16_emitcode("mov","%s,%s",
10088 pic16_aopGet(AOP(result),0,FALSE,TRUE));
10089 rname = preg->name ;
10091 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10093 pic16_freeAsmop(result,NULL,ic,TRUE);
10094 pic16_aopOp (right,ic,FALSE);
10096 /* if bitfield then unpack the bits */
10097 if (IS_BITFIELD(retype))
10098 genPackBits (retype,right,rname,PPOINTER);
10100 /* we have can just get the values */
10101 int size = AOP_SIZE(right);
10105 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10108 pic16_emitcode("movx","@%s,a",rname);
10111 pic16_emitcode("inc","%s",rname);
10117 /* now some housekeeping stuff */
10119 /* we had to allocate for this iCode */
10120 pic16_freeAsmop(NULL,aop,ic,TRUE);
10122 /* we did not allocate which means left
10123 already in a pointer register, then
10124 if size > 0 && this could be used again
10125 we have to point it back to where it
10127 if (AOP_SIZE(right) > 1 &&
10128 !OP_SYMBOL(result)->remat &&
10129 ( OP_SYMBOL(result)->liveTo > ic->seq ||
10131 int size = AOP_SIZE(right) - 1;
10133 pic16_emitcode("dec","%s",rname);
10138 pic16_freeAsmop(right,NULL,ic,TRUE);
10143 /*-----------------------------------------------------------------*/
10144 /* genFarPointerSet - set value from far space */
10145 /*-----------------------------------------------------------------*/
10146 static void genFarPointerSet (operand *right,
10147 operand *result, iCode *ic)
10150 sym_link *retype = getSpec(operandType(right));
10152 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10153 pic16_aopOp(result,ic,FALSE);
10155 /* if the operand is already in dptr
10156 then we do nothing else we move the value to dptr */
10157 if (AOP_TYPE(result) != AOP_STR) {
10158 /* if this is remateriazable */
10159 if (AOP_TYPE(result) == AOP_IMMD)
10160 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
10161 else { /* we need to get it byte by byte */
10162 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
10163 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
10164 if (options.model == MODEL_FLAT24)
10166 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
10170 /* so dptr know contains the address */
10171 pic16_freeAsmop(result,NULL,ic,TRUE);
10172 pic16_aopOp(right,ic,FALSE);
10174 /* if bit then unpack */
10175 if (IS_BITFIELD(retype))
10176 genPackBits(retype,right,"dptr",FPOINTER);
10178 size = AOP_SIZE(right);
10182 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10184 pic16_emitcode("movx","@dptr,a");
10186 pic16_emitcode("inc","dptr");
10190 pic16_freeAsmop(right,NULL,ic,TRUE);
10193 /*-----------------------------------------------------------------*/
10194 /* genGenPointerSet - set value from generic pointer space */
10195 /*-----------------------------------------------------------------*/
10196 static void genGenPointerSet (operand *right,
10197 operand *result, iCode *ic)
10199 int i, size, offset, lit;
10200 sym_link *retype = getSpec(operandType(right));
10202 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10204 pic16_aopOp(result,ic,FALSE);
10205 pic16_aopOp(right,ic,FALSE);
10206 size = AOP_SIZE(right);
10209 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10211 /* if the operand is already in dptr
10212 then we do nothing else we move the value to dptr */
10213 if (AOP_TYPE(result) != AOP_STR) {
10214 /* if this is remateriazable */
10215 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10216 // WARNING: anythig until "else" is untested!
10217 if (AOP_TYPE(result) == AOP_IMMD) {
10218 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10219 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10220 // load FSR0 from immediate
10221 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10225 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10227 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10233 else { /* we need to get it byte by byte */
10234 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10235 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10237 // set up FSR0 with address of result
10238 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10239 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10241 /* hack hack! see if this the FSR. If so don't load W */
10242 if(AOP_TYPE(right) != AOP_ACC) {
10244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10246 if(AOP_TYPE(right) == AOP_LIT)
10249 // note: pic16_popGet handles sign extension
10250 for(i=0;i<size;i++) {
10251 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10253 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10255 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10260 for(i=0;i<size;i++) {
10262 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10263 pic16_popCopyReg(&pic16_pc_postinc0)));
10265 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10266 pic16_popCopyReg(&pic16_pc_indf0)));
10272 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10273 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10275 } // if (AOP_TYPE(result) != AOP_IMMD)
10277 } // if (AOP_TYPE(result) != AOP_STR)
10278 /* so dptr know contains the address */
10281 /* if bit then unpack */
10282 if (IS_BITFIELD(retype))
10283 genPackBits(retype,right,"dptr",GPOINTER);
10285 size = AOP_SIZE(right);
10288 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10290 // set up FSR0 with address of result
10291 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10292 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10295 if (AOP_TYPE(right) == AOP_LIT) {
10296 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10298 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10300 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10302 } else { // no literal
10304 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10306 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10314 pic16_freeAsmop(right,NULL,ic,TRUE);
10315 pic16_freeAsmop(result,NULL,ic,TRUE);
10318 /*-----------------------------------------------------------------*/
10319 /* genPointerSet - stores the value into a pointer location */
10320 /*-----------------------------------------------------------------*/
10321 static void genPointerSet (iCode *ic)
10323 operand *right, *result ;
10324 sym_link *type, *etype;
10327 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10329 right = IC_RIGHT(ic);
10330 result = IC_RESULT(ic) ;
10332 /* depending on the type of pointer we need to
10333 move it to the correct pointer register */
10334 type = operandType(result);
10335 etype = getSpec(type);
10336 /* if left is of type of pointer then it is simple */
10337 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10338 p_type = DCL_TYPE(type);
10341 /* we have to go by the storage class */
10342 p_type = PTR_TYPE(SPEC_OCLS(etype));
10344 /* if (SPEC_OCLS(etype)->codesp ) { */
10345 /* p_type = CPOINTER ; */
10348 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10349 /* p_type = FPOINTER ; */
10351 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10352 /* p_type = PPOINTER ; */
10354 /* if (SPEC_OCLS(etype) == idata ) */
10355 /* p_type = IPOINTER ; */
10357 /* p_type = POINTER ; */
10360 /* now that we have the pointer type we assign
10361 the pointer values */
10366 genNearPointerSet (right,result,ic);
10370 genPagedPointerSet (right,result,ic);
10374 genFarPointerSet (right,result,ic);
10378 genGenPointerSet (right,result,ic);
10382 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10383 "genPointerSet: illegal pointer type");
10387 /*-----------------------------------------------------------------*/
10388 /* genIfx - generate code for Ifx statement */
10389 /*-----------------------------------------------------------------*/
10390 static void genIfx (iCode *ic, iCode *popIc)
10392 operand *cond = IC_COND(ic);
10395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10397 pic16_aopOp(cond,ic,FALSE);
10399 /* get the value into acc */
10400 if (AOP_TYPE(cond) != AOP_CRY)
10401 pic16_toBoolean(cond);
10404 /* the result is now in the accumulator */
10405 pic16_freeAsmop(cond,NULL,ic,TRUE);
10407 /* if there was something to be popped then do it */
10411 /* if the condition is a bit variable */
10412 if (isbit && IS_ITEMP(cond) &&
10414 genIfxJump(ic,SPIL_LOC(cond)->rname);
10415 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10418 if (isbit && !IS_ITEMP(cond))
10419 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10421 genIfxJump(ic,"a");
10427 /*-----------------------------------------------------------------*/
10428 /* genAddrOf - generates code for address of */
10429 /*-----------------------------------------------------------------*/
10430 static void genAddrOf (iCode *ic)
10432 operand *result, *left;
10434 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10435 pCodeOp *pcop0, *pcop1, *pcop2;
10437 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10439 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10440 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10442 sym = OP_SYMBOL( left );
10444 size = AOP_SIZE(IC_RESULT(ic));
10446 // if(pic16_debug_verbose) {
10447 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10448 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10451 /* Assume that what we want the address of is in data space
10452 * since there is no stack on the PIC, yet! -- VR */
10454 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10457 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10460 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10464 pic16_emitpcode(POC_MOVLW, pcop0);
10465 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10466 pic16_emitpcode(POC_MOVLW, pcop1);
10467 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10468 pic16_emitpcode(POC_MOVLW, pcop2);
10469 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10472 pic16_emitpcode(POC_MOVLW, pcop0);
10473 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10474 pic16_emitpcode(POC_MOVLW, pcop1);
10475 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10477 pic16_emitpcode(POC_MOVLW, pcop0);
10478 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10481 pic16_freeAsmop(result,NULL,ic,TRUE);
10482 pic16_freeAsmop(left, NULL, ic, FALSE);
10487 /*-----------------------------------------------------------------*/
10488 /* genFarFarAssign - assignment when both are in far space */
10489 /*-----------------------------------------------------------------*/
10490 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10492 int size = AOP_SIZE(right);
10495 /* first push the right side on to the stack */
10497 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10499 pic16_emitcode ("push","acc");
10502 pic16_freeAsmop(right,NULL,ic,FALSE);
10503 /* now assign DPTR to result */
10504 pic16_aopOp(result,ic,FALSE);
10505 size = AOP_SIZE(result);
10507 pic16_emitcode ("pop","acc");
10508 pic16_aopPut(AOP(result),"a",--offset);
10510 pic16_freeAsmop(result,NULL,ic,FALSE);
10515 /*-----------------------------------------------------------------*/
10516 /* genAssign - generate code for assignment */
10517 /*-----------------------------------------------------------------*/
10518 static void genAssign (iCode *ic)
10520 operand *result, *right;
10521 int size, offset,know_W;
10522 unsigned long lit = 0L;
10524 result = IC_RESULT(ic);
10525 right = IC_RIGHT(ic) ;
10527 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10529 /* if they are the same */
10530 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
10533 pic16_aopOp(right,ic,FALSE);
10534 pic16_aopOp(result,ic,TRUE);
10536 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10538 /* if they are the same registers */
10539 if (pic16_sameRegs(AOP(right),AOP(result)))
10542 /* if the result is a bit */
10543 if (AOP_TYPE(result) == AOP_CRY) {
10544 /* if the right size is a literal then
10545 we know what the value is */
10546 if (AOP_TYPE(right) == AOP_LIT) {
10548 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10549 pic16_popGet(AOP(result),0));
10551 if (((int) operandLitValue(right)))
10552 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10553 AOP(result)->aopu.aop_dir,
10554 AOP(result)->aopu.aop_dir);
10556 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10557 AOP(result)->aopu.aop_dir,
10558 AOP(result)->aopu.aop_dir);
10562 /* the right is also a bit variable */
10563 if (AOP_TYPE(right) == AOP_CRY) {
10564 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10565 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10566 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10568 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10569 AOP(result)->aopu.aop_dir,
10570 AOP(result)->aopu.aop_dir);
10571 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
10572 AOP(right)->aopu.aop_dir,
10573 AOP(right)->aopu.aop_dir);
10574 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10575 AOP(result)->aopu.aop_dir,
10576 AOP(result)->aopu.aop_dir);
10580 /* we need to or */
10581 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10582 pic16_toBoolean(right);
10584 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10585 //pic16_aopPut(AOP(result),"a",0);
10589 /* bit variables done */
10591 size = AOP_SIZE(result);
10594 if(AOP_TYPE(right) == AOP_LIT) {
10595 if(!IS_FLOAT(operandType( right )))
10596 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10599 unsigned long lit_int;
10603 /* take care if literal is a float */
10604 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
10605 lit = info.lit_int;
10609 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
10610 // sizeof(unsigned long int), sizeof(float));
10612 /* VR - What is this?! */
10613 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
10614 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10615 if(aopIdx(AOP(result),0) == 4) {
10616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10617 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10618 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10621 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
10626 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10627 if(AOP_TYPE(right) == AOP_LIT) {
10629 if(know_W != (lit&0xff))
10630 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
10632 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10634 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10638 } else if (AOP_TYPE(right) == AOP_CRY) {
10639 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10641 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
10642 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10644 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
10645 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10646 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10648 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10651 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
10652 normally should work, but mind that the W register live range
10653 is not checked, so if the code generator assumes that the W
10654 is already loaded after such a pair, wrong code will be generated.
10656 Checking the live range is the next step.
10657 This is experimental code yet and has not been fully tested yet.
10658 USE WITH CARE. Revert to old code by setting 0 to the condition above.
10659 Vangelis Rokas 030603 (vrokas@otenet.gr) */
10661 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
10663 /* This is the old code, which is assumed(?!) that works fine(!?) */
10665 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10666 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10675 pic16_freeAsmop (right,NULL,ic,FALSE);
10676 pic16_freeAsmop (result,NULL,ic,TRUE);
10679 /*-----------------------------------------------------------------*/
10680 /* genJumpTab - generates code for jump table */
10681 /*-----------------------------------------------------------------*/
10682 static void genJumpTab (iCode *ic)
10687 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10689 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10690 /* get the condition into accumulator */
10691 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10693 /* multiply by three */
10694 pic16_emitcode("add","a,acc");
10695 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10697 jtab = newiTempLabel(NULL);
10698 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10699 pic16_emitcode("jmp","@a+dptr");
10700 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10702 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10703 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10705 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10706 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10707 pic16_emitpLabel(jtab->key);
10709 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10711 /* now generate the jump labels */
10712 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10713 jtab = setNextItem(IC_JTLABELS(ic))) {
10714 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10715 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10721 /*-----------------------------------------------------------------*/
10722 /* genMixedOperation - gen code for operators between mixed types */
10723 /*-----------------------------------------------------------------*/
10725 TSD - Written for the PIC port - but this unfortunately is buggy.
10726 This routine is good in that it is able to efficiently promote
10727 types to different (larger) sizes. Unfortunately, the temporary
10728 variables that are optimized out by this routine are sometimes
10729 used in other places. So until I know how to really parse the
10730 iCode tree, I'm going to not be using this routine :(.
10732 static int genMixedOperation (iCode *ic)
10735 operand *result = IC_RESULT(ic);
10736 sym_link *ctype = operandType(IC_LEFT(ic));
10737 operand *right = IC_RIGHT(ic);
10743 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10745 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10751 nextright = IC_RIGHT(nextic);
10752 nextleft = IC_LEFT(nextic);
10753 nextresult = IC_RESULT(nextic);
10755 pic16_aopOp(right,ic,FALSE);
10756 pic16_aopOp(result,ic,FALSE);
10757 pic16_aopOp(nextright, nextic, FALSE);
10758 pic16_aopOp(nextleft, nextic, FALSE);
10759 pic16_aopOp(nextresult, nextic, FALSE);
10761 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10763 operand *t = right;
10767 pic16_emitcode(";remove right +","");
10769 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10771 operand *t = right;
10775 pic16_emitcode(";remove left +","");
10779 big = AOP_SIZE(nextleft);
10780 small = AOP_SIZE(nextright);
10782 switch(nextic->op) {
10785 pic16_emitcode(";optimize a +","");
10786 /* if unsigned or not an integral type */
10787 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10788 pic16_emitcode(";add a bit to something","");
10791 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10793 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10794 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10795 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10797 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10805 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10806 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10807 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10810 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10812 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10813 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10814 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10815 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10816 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10819 pic16_emitcode("rlf","known_zero,w");
10826 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10827 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10828 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10830 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10840 pic16_freeAsmop(right,NULL,ic,TRUE);
10841 pic16_freeAsmop(result,NULL,ic,TRUE);
10842 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10843 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10845 nextic->generated = 1;
10852 /*-----------------------------------------------------------------*/
10853 /* genCast - gen code for casting */
10854 /*-----------------------------------------------------------------*/
10855 static void genCast (iCode *ic)
10857 operand *result = IC_RESULT(ic);
10858 sym_link *ctype = operandType(IC_LEFT(ic));
10859 sym_link *rtype = operandType(IC_RIGHT(ic));
10860 operand *right = IC_RIGHT(ic);
10863 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10864 /* if they are equivalent then do nothing */
10865 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10868 pic16_aopOp(right,ic,FALSE) ;
10869 pic16_aopOp(result,ic,FALSE);
10871 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10873 /* if the result is a bit */
10874 if (AOP_TYPE(result) == AOP_CRY) {
10876 /* if the right size is a literal then
10877 * we know what the value is */
10878 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10880 if (AOP_TYPE(right) == AOP_LIT) {
10881 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10882 pic16_popGet(AOP(result),0));
10884 if (((int) operandLitValue(right)))
10885 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10886 AOP(result)->aopu.aop_dir,
10887 AOP(result)->aopu.aop_dir);
10889 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10890 AOP(result)->aopu.aop_dir,
10891 AOP(result)->aopu.aop_dir);
10895 /* the right is also a bit variable */
10896 if (AOP_TYPE(right) == AOP_CRY) {
10898 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10900 pic16_emitcode("clrc","");
10901 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10902 AOP(right)->aopu.aop_dir,
10903 AOP(right)->aopu.aop_dir);
10904 pic16_aopPut(AOP(result),"c",0);
10908 /* we need to or */
10909 if (AOP_TYPE(right) == AOP_REG) {
10910 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10911 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10912 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10914 pic16_toBoolean(right);
10915 pic16_aopPut(AOP(result),"a",0);
10919 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10922 size = AOP_SIZE(result);
10924 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10926 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10927 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10928 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10931 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10936 /* if they are the same size : or less */
10937 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10939 /* if they are in the same place */
10940 if (pic16_sameRegs(AOP(right),AOP(result)))
10943 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10945 if (IS_PTR_CONST(rtype))
10947 if (IS_CODEPTR(rtype))
10949 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10952 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10954 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10956 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10959 if(AOP_TYPE(right) == AOP_IMMD) {
10960 pCodeOp *pcop0, *pcop1, *pcop2;
10961 symbol *sym = OP_SYMBOL( right );
10963 size = AOP_SIZE(result);
10965 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10967 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10969 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10972 pic16_emitpcode(POC_MOVLW, pcop0);
10973 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10974 pic16_emitpcode(POC_MOVLW, pcop1);
10975 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10976 pic16_emitpcode(POC_MOVLW, pcop2);
10977 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10980 pic16_emitpcode(POC_MOVLW, pcop0);
10981 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10982 pic16_emitpcode(POC_MOVLW, pcop1);
10983 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10985 pic16_emitpcode(POC_MOVLW, pcop0);
10986 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10990 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10991 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10992 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10993 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10994 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10995 if(AOP_SIZE(result) <2)
10996 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10998 /* if they in different places then copy */
10999 size = AOP_SIZE(result);
11002 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11003 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11010 /* if the result is of type pointer */
11011 if (IS_PTR(ctype)) {
11013 sym_link *type = operandType(right);
11014 sym_link *etype = getSpec(type);
11016 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
11018 /* pointer to generic pointer */
11019 if (IS_GENPTR(ctype)) {
11023 p_type = DCL_TYPE(type);
11025 /* we have to go by the storage class */
11026 p_type = PTR_TYPE(SPEC_OCLS(etype));
11028 /* if (SPEC_OCLS(etype)->codesp ) */
11029 /* p_type = CPOINTER ; */
11031 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11032 /* p_type = FPOINTER ; */
11034 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11035 /* p_type = PPOINTER; */
11037 /* if (SPEC_OCLS(etype) == idata ) */
11038 /* p_type = IPOINTER ; */
11040 /* p_type = POINTER ; */
11043 /* the first two bytes are known */
11044 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
11045 size = GPTRSIZE - 1;
11048 if(offset < AOP_SIZE(right)) {
11049 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
11050 if ((AOP_TYPE(right) == AOP_PCODE) &&
11051 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
11052 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11053 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11055 pic16_aopPut(AOP(result),
11056 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11060 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
11063 /* the last byte depending on type */
11067 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
11070 pic16_emitcode(";BUG!? ","%d",__LINE__);
11074 pic16_emitcode(";BUG!? ","%d",__LINE__);
11078 pic16_emitcode(";BUG!? ","%d",__LINE__);
11083 /* this should never happen */
11084 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11085 "got unknown pointer type");
11088 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
11092 /* just copy the pointers */
11093 size = AOP_SIZE(result);
11096 pic16_aopPut(AOP(result),
11097 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11106 /* so we now know that the size of destination is greater
11107 than the size of the source.
11108 Now, if the next iCode is an operator then we might be
11109 able to optimize the operation without performing a cast.
11111 if(genMixedOperation(ic))
11114 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11116 /* we move to result for the size of source */
11117 size = AOP_SIZE(right);
11120 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11121 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11125 /* now depending on the sign of the destination */
11126 size = AOP_SIZE(result) - AOP_SIZE(right);
11127 /* if unsigned or not an integral type */
11128 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
11130 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
11132 /* we need to extend the sign :( */
11135 /* Save one instruction of casting char to int */
11136 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11137 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11138 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
11140 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
11143 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11145 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
11147 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
11150 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
11155 pic16_freeAsmop(right,NULL,ic,TRUE);
11156 pic16_freeAsmop(result,NULL,ic,TRUE);
11160 /*-----------------------------------------------------------------*/
11161 /* genDjnz - generate decrement & jump if not zero instrucion */
11162 /*-----------------------------------------------------------------*/
11163 static int genDjnz (iCode *ic, iCode *ifx)
11165 symbol *lbl, *lbl1;
11166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11171 /* if the if condition has a false label
11172 then we cannot save */
11176 /* if the minus is not of the form
11178 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
11179 !IS_OP_LITERAL(IC_RIGHT(ic)))
11182 if (operandLitValue(IC_RIGHT(ic)) != 1)
11185 /* if the size of this greater than one then no
11187 if (getSize(operandType(IC_RESULT(ic))) > 1)
11190 /* otherwise we can save BIG */
11191 lbl = newiTempLabel(NULL);
11192 lbl1= newiTempLabel(NULL);
11194 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11196 if (IS_AOP_PREG(IC_RESULT(ic))) {
11197 pic16_emitcode("dec","%s",
11198 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11199 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11200 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11204 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11205 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11207 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11208 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
11211 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11212 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11213 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11214 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11217 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11218 ifx->generated = 1;
11222 /*-----------------------------------------------------------------*/
11223 /* genReceive - generate code for a receive iCode */
11224 /*-----------------------------------------------------------------*/
11225 static void genReceive (iCode *ic)
11227 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11229 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11230 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11231 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11233 int size = getSize(operandType(IC_RESULT(ic)));
11234 int offset = pic16_fReturnSizePic - size;
11237 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11238 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11242 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11244 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11245 size = AOP_SIZE(IC_RESULT(ic));
11248 pic16_emitcode ("pop","acc");
11249 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11252 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11255 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11257 assignResultValue(IC_RESULT(ic), 0);
11260 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11263 /*-----------------------------------------------------------------*/
11264 /* genDummyRead - generate code for dummy read of volatiles */
11265 /*-----------------------------------------------------------------*/
11267 genDummyRead (iCode * ic)
11269 pic16_emitcode ("; genDummyRead","");
11270 pic16_emitcode ("; not implemented","");
11275 /*-----------------------------------------------------------------*/
11276 /* genpic16Code - generate code for pic16 based controllers */
11277 /*-----------------------------------------------------------------*/
11279 * At this point, ralloc.c has gone through the iCode and attempted
11280 * to optimize in a way suitable for a PIC. Now we've got to generate
11281 * PIC instructions that correspond to the iCode.
11283 * Once the instructions are generated, we'll pass through both the
11284 * peep hole optimizer and the pCode optimizer.
11285 *-----------------------------------------------------------------*/
11287 void genpic16Code (iCode *lic)
11292 lineHead = lineCurr = NULL;
11294 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11295 pic16_addpBlock(pb);
11298 /* if debug information required */
11299 if (options.debug && currFunc) {
11301 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11306 for (ic = lic ; ic ; ic = ic->next ) {
11308 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11309 if ( cln != ic->lineno ) {
11310 if ( options.debug ) {
11311 debugFile->writeCLine (ic);
11314 if(!options.noCcodeInAsm) {
11315 pic16_addpCode2pBlock(pb,
11316 pic16_newpCodeCSource(ic->lineno, ic->filename,
11317 printCLine(ic->filename, ic->lineno)));
11323 if(options.iCodeInAsm) {
11325 /* insert here code to print iCode as comment */
11326 l = Safe_strdup(printILine(ic));
11327 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
11330 /* if the result is marked as
11331 spilt and rematerializable or code for
11332 this has already been generated then
11334 if (resultRemat(ic) || ic->generated )
11337 /* depending on the operation */
11356 /* IPOP happens only when trying to restore a
11357 spilt live range, if there is an ifx statement
11358 following this pop then the if statement might
11359 be using some of the registers being popped which
11360 would destroy the contents of the register so
11361 we need to check for this condition and handle it */
11363 ic->next->op == IFX &&
11364 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11365 genIfx (ic->next,ic);
11383 genEndFunction (ic);
11399 pic16_genPlus (ic) ;
11403 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11404 pic16_genMinus (ic);
11420 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11424 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11431 /* note these two are xlated by algebraic equivalence
11432 during parsing SDCC.y */
11433 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11434 "got '>=' or '<=' shouldn't have come here");
11438 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
11450 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
11454 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
11458 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
11482 genRightShift (ic);
11485 case GET_VALUE_AT_ADDRESS:
11490 if (POINTER_SET(ic))
11517 addSet(&_G.sendSet,ic);
11520 case DUMMY_READ_VOLATILE:
11530 /* now we are ready to call the
11531 peep hole optimizer */
11532 if (!options.nopeep) {
11533 peepHole (&lineHead);
11535 /* now do the actual printing */
11536 printLine (lineHead,codeOutFile);
11539 DFPRINTF((stderr,"printing pBlock\n\n"));
11540 pic16_printpBlock(stdout,pb);