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 pCode *pic16_AssembleLine(char *line, int peeps);
53 extern void pic16_printpBlock(FILE *of, pBlock *pb);
54 static asmop *newAsmop (short type);
55 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
56 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
57 static void mov2w (asmop *aop, int offset);
58 static int aopIdx (asmop *aop, int offset);
60 static int labelOffset=0;
61 extern int pic16_debug_verbose;
62 static int optimized_for_speed = 0;
68 /* max_key keeps track of the largest label number used in
69 a function. This is then used to adjust the label offset
70 for the next function.
73 static int GpsuedoStkPtr=0;
75 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
76 unsigned int pic16aopLiteral (value *val, int offset);
77 const char *pic16_AopType(short type);
78 static iCode *ifxForOp ( operand *op, iCode *ic );
80 void pic16_pushpCodeOp(pCodeOp *pcop);
81 void pic16_poppCodeOp(pCodeOp *pcop);
85 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
87 /* this is the down and dirty file with all kinds of
88 kludgy & hacky stuff. This is what it is all about
89 CODE GENERATION for a specific MCU . some of the
90 routines may be reusable, will have to see */
92 static char *zero = "#0x00";
93 static char *one = "#0x01";
94 static char *spname = "sp";
98 * Function return value policy (MSB-->LSB):
100 * 16 bits -> PRODL:WREG
101 * 24 bits -> PRODH:PRODL:WREG
102 * 32 bits -> FSR0L:PRODH:PRODL:WREG
103 * >32 bits -> on stack, and FSR0 points to the beginning
108 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
109 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
110 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
111 static char **fReturn = fReturnpic16;
113 static char *accUse[] = {"WREG"};
115 //static short rbank = -1;
127 /* Resolved ifx structure. This structure stores information
128 about an iCode ifx that makes it easier to generate code.
130 typedef struct resolvedIfx {
131 symbol *lbl; /* pointer to a label */
132 int condition; /* true or false ifx */
133 int generated; /* set true when the code associated with the ifx
137 extern int pic16_ptrRegReq ;
138 extern int pic16_nRegs;
139 extern FILE *codeOutFile;
140 static void saverbank (int, iCode *,bool);
142 static lineNode *lineHead = NULL;
143 static lineNode *lineCurr = NULL;
145 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
146 0xE0, 0xC0, 0x80, 0x00};
147 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
148 0x07, 0x03, 0x01, 0x00};
152 /*-----------------------------------------------------------------*/
153 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
154 /* exponent of 2 is returned, otherwise -1 is */
156 /* note that this is similar to the function `powof2' in SDCCsymt */
160 /*-----------------------------------------------------------------*/
161 static int my_powof2 (unsigned long num)
164 if( (num & (num-1)) == 0) {
177 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
180 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
182 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
183 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
184 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
185 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
186 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
187 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
188 ((result) ? AOP_SIZE(result) : 0));
192 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
195 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
197 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
198 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
199 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
200 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
201 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
202 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
206 void pic16_emitpcomment (char *fmt, ...)
209 char lb[INITIAL_INLINEASM];
215 vsprintf(lb+1,fmt,ap);
217 while (isspace(*lbp)) lbp++;
220 lineCurr = (lineCurr ?
221 connectLine(lineCurr,newLineNode(lb)) :
222 (lineHead = newLineNode(lb)));
223 lineCurr->isInline = _G.inLine;
224 lineCurr->isDebug = _G.debugLine;
226 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
229 // fprintf(stderr, "%s\n", lb);
232 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
235 char lb[INITIAL_INLINEASM];
238 if(!pic16_debug_verbose)
245 sprintf(lb,"%s\t",inst);
247 sprintf(lb,"%s",inst);
248 vsprintf(lb+(strlen(lb)),fmt,ap);
252 while (isspace(*lbp)) lbp++;
255 lineCurr = (lineCurr ?
256 connectLine(lineCurr,newLineNode(lb)) :
257 (lineHead = newLineNode(lb)));
258 lineCurr->isInline = _G.inLine;
259 lineCurr->isDebug = _G.debugLine;
261 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
264 // fprintf(stderr, "%s\n", lb);
267 void pic16_emitpLabel(int key)
269 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
272 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
276 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
278 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
280 // fprintf(stderr, "%s\n", pcop->name);
283 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
286 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
292 #define pic16_emitcode DEBUGpic16_emitcode
294 /*-----------------------------------------------------------------*/
295 /* pic16_emitcode - writes the code into a file : for now it is simple */
296 /*-----------------------------------------------------------------*/
297 void pic16_emitcode (char *inst,char *fmt, ...)
300 char lb[INITIAL_INLINEASM];
307 sprintf(lb,"%s\t",inst);
309 sprintf(lb,"%s",inst);
310 vsprintf(lb+(strlen(lb)),fmt,ap);
314 while (isspace(*lbp)) lbp++;
317 lineCurr = (lineCurr ?
318 connectLine(lineCurr,newLineNode(lb)) :
319 (lineHead = newLineNode(lb)));
320 lineCurr->isInline = _G.inLine;
321 lineCurr->isDebug = _G.debugLine;
323 // VR fprintf(stderr, "lb = <%s>\n", lbp);
325 // if(pic16_debug_verbose)
326 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
333 /*-----------------------------------------------------------------*/
334 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
335 /*-----------------------------------------------------------------*/
336 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
338 bool r0iu = FALSE , r1iu = FALSE;
339 bool r0ou = FALSE , r1ou = FALSE;
341 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
343 /* the logic: if r0 & r1 used in the instruction
344 then we are in trouble otherwise */
346 /* first check if r0 & r1 are used by this
347 instruction, in which case we are in trouble */
348 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
349 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
354 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
355 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
357 /* if no usage of r0 then return it */
358 if (!r0iu && !r0ou) {
359 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
360 (*aopp)->type = AOP_R0;
362 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
365 /* if no usage of r1 then return it */
366 if (!r1iu && !r1ou) {
367 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
368 (*aopp)->type = AOP_R1;
370 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
373 /* now we know they both have usage */
374 /* if r0 not used in this instruction */
376 /* push it if not already pushed */
378 //pic16_emitcode ("push","%s",
379 // pic16_regWithIdx(R0_IDX)->dname);
383 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
384 (*aopp)->type = AOP_R0;
386 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
389 /* if r1 not used then */
392 /* push it if not already pushed */
394 //pic16_emitcode ("push","%s",
395 // pic16_regWithIdx(R1_IDX)->dname);
399 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
400 (*aopp)->type = AOP_R1;
401 return pic16_regWithIdx(R1_IDX);
405 /* I said end of world but not quite end of world yet */
406 /* if this is a result then we can push it on the stack*/
408 (*aopp)->type = AOP_STK;
412 /* other wise this is true end of the world */
413 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
414 "getFreePtr should never reach here");
418 /*-----------------------------------------------------------------*/
419 /* newAsmop - creates a new asmOp */
420 /*-----------------------------------------------------------------*/
421 static asmop *newAsmop (short type)
425 aop = Safe_calloc(1,sizeof(asmop));
430 static void genSetDPTR(int n)
434 pic16_emitcode(";", "Select standard DPTR");
435 pic16_emitcode("mov", "dps, #0x00");
439 pic16_emitcode(";", "Select alternate DPTR");
440 pic16_emitcode("mov", "dps, #0x01");
444 /*-----------------------------------------------------------------*/
445 /* resolveIfx - converts an iCode ifx into a form more useful for */
446 /* generating code */
447 /*-----------------------------------------------------------------*/
448 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
453 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
455 resIfx->condition = 1; /* assume that the ifx is true */
456 resIfx->generated = 0; /* indicate that the ifx has not been used */
459 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
461 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
462 __FUNCTION__,__LINE__,resIfx->lbl->key);
466 resIfx->lbl = IC_TRUE(ifx);
468 resIfx->lbl = IC_FALSE(ifx);
469 resIfx->condition = 0;
473 DEBUGpic16_emitcode("; ***","ifx true is non-null");
475 DEBUGpic16_emitcode("; ***","ifx false is non-null");
479 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
483 /*-----------------------------------------------------------------*/
484 /* pointerCode - returns the code for a pointer type */
485 /*-----------------------------------------------------------------*/
486 static int pointerCode (sym_link *etype)
489 return PTR_TYPE(SPEC_OCLS(etype));
493 /*-----------------------------------------------------------------*/
494 /* aopForSym - for a true symbol */
495 /*-----------------------------------------------------------------*/
496 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
499 memmap *space= SPEC_OCLS(sym->etype);
501 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
502 /* if already has one */
504 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
508 /* assign depending on the storage class */
509 /* if it is on the stack or indirectly addressable */
510 /* space we need to assign either r0 or r1 to it */
511 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
513 DEBUGpic16_emitcode("; ***", "sum->onStack || sym->iaccess");
515 sym->aop = aop = newAsmop(0);
516 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
517 aop->size = getSize(sym->type);
519 /* now assign the address of the variable to
520 the pointer register */
521 if (aop->type != AOP_STK) {
525 pic16_emitcode("push","acc");
527 pic16_emitcode("mov","a,_bp");
528 pic16_emitcode("add","a,#0x%02x",
530 ((char)(sym->stack - _G.nRegsSaved )) :
531 ((char)sym->stack)) & 0xff);
532 pic16_emitcode("mov","%s,a",
533 aop->aopu.aop_ptr->name);
536 pic16_emitcode("pop","acc");
538 pic16_emitcode("mov","%s,#%s",
539 aop->aopu.aop_ptr->name,
541 aop->paged = space->paged;
543 aop->aopu.aop_stk = sym->stack;
547 if (sym->onStack && options.stack10bit)
549 /* It's on the 10 bit stack, which is located in
553 //DEBUGpic16_emitcode(";","%d",__LINE__);
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);
565 pic16_emitcode ("mov","dpx1,#0x40");
566 pic16_emitcode ("mov","dph1,#0x00");
567 pic16_emitcode ("mov","dpl1, a");
571 pic16_emitcode("pop","acc");
573 sym->aop = aop = newAsmop(AOP_DPTR2);
574 aop->size = getSize(sym->type);
578 //DEBUGpic16_emitcode(";","%d",__LINE__);
579 /* if in bit space */
580 if (IN_BITSPACE(space)) {
581 sym->aop = aop = newAsmop (AOP_CRY);
582 aop->aopu.aop_dir = sym->rname ;
583 aop->size = getSize(sym->type);
584 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
587 /* if it is in direct space */
588 if (IN_DIRSPACE(space)) {
589 sym->aop = aop = newAsmop (AOP_DIR);
590 aop->aopu.aop_dir = sym->rname ;
591 aop->size = getSize(sym->type);
592 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
593 pic16_allocDirReg( IC_LEFT(ic) );
597 /* special case for a function */
598 if (IS_FUNC(sym->type)) {
599 sym->aop = aop = newAsmop(AOP_IMMD);
600 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
601 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
602 strcpy(aop->aopu.aop_immd,sym->rname);
603 aop->size = FPTRSIZE;
604 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
609 /* only remaining is far space */
610 /* in which case DPTR gets the address */
611 sym->aop = aop = newAsmop(AOP_PCODE);
613 /* change the next if to 1 to revert to good old immediate code */
614 if(IN_CODESPACE(space)) {
615 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
616 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
617 PCOI(aop->aopu.pcop)->index = 0;
619 /* try to allocate via direct register */
620 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), 0);
621 // aop->size = getSize( sym->type );
624 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
625 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
627 pic16_allocDirReg (IC_LEFT(ic));
629 if(IN_DIRSPACE( space ))
631 else if(IN_CODESPACE( space ))
632 aop->size = FPTRSIZE;
633 else aop->size = AOP_SIZE( IC_LEFT(ic) );
635 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
637 /* if it is in code space */
638 if (IN_CODESPACE(space))
644 /*-----------------------------------------------------------------*/
645 /* aopForRemat - rematerialzes an object */
646 /*-----------------------------------------------------------------*/
647 static asmop *aopForRemat (operand *op) // x symbol *sym)
649 symbol *sym = OP_SYMBOL(op);
650 iCode *ic = NULL, *oldic;
651 asmop *aop = newAsmop(AOP_PCODE);
657 ic = sym->rematiCode;
659 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
661 if(IS_OP_POINTER(op)) {
662 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
668 // pic16_emitpcomment("ic: %s\n", printILine(ic));
671 val += (int) operandLitValue(IC_RIGHT(ic));
672 } else if (ic->op == '-') {
673 val -= (int) operandLitValue(IC_RIGHT(ic));
677 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
680 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
682 if(!op->isaddr)viaimmd++; else viaimmd=0;
684 /* set the following if to 1 to revert to good old immediate code */
685 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
688 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
690 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
693 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
695 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
698 PCOI(aop->aopu.pcop)->index = val;
700 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
702 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
703 // aop->size = AOP_SIZE( IC_LEFT(ic) );
707 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
708 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
710 val, IS_PTR_CONST(operandType(op)));
712 val, IS_CODEPTR(operandType(op)));
715 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
717 pic16_allocDirReg (IC_LEFT(ic));
719 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
725 static int aopIdx (asmop *aop, int offset)
730 if(aop->type != AOP_REG)
733 return aop->aopu.aop_reg[offset]->rIdx;
736 /*-----------------------------------------------------------------*/
737 /* regsInCommon - two operands have some registers in common */
738 /*-----------------------------------------------------------------*/
739 static bool regsInCommon (operand *op1, operand *op2)
744 /* if they have registers in common */
745 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
748 sym1 = OP_SYMBOL(op1);
749 sym2 = OP_SYMBOL(op2);
751 if (sym1->nRegs == 0 || sym2->nRegs == 0)
754 for (i = 0 ; i < sym1->nRegs ; i++) {
759 for (j = 0 ; j < sym2->nRegs ;j++ ) {
763 if (sym2->regs[j] == sym1->regs[i])
771 /*-----------------------------------------------------------------*/
772 /* operandsEqu - equivalent */
773 /*-----------------------------------------------------------------*/
774 static bool operandsEqu ( operand *op1, operand *op2)
778 /* if they not symbols */
779 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
782 sym1 = OP_SYMBOL(op1);
783 sym2 = OP_SYMBOL(op2);
785 /* if both are itemps & one is spilt
786 and the other is not then false */
787 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
788 sym1->isspilt != sym2->isspilt )
791 /* if they are the same */
795 if (strcmp(sym1->rname,sym2->rname) == 0)
799 /* if left is a tmp & right is not */
803 (sym1->usl.spillLoc == sym2))
810 (sym2->usl.spillLoc == sym1))
816 /*-----------------------------------------------------------------*/
817 /* pic16_sameRegs - two asmops have the same registers */
818 /*-----------------------------------------------------------------*/
819 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
826 if (aop1->type != AOP_REG ||
827 aop2->type != AOP_REG )
830 if (aop1->size != aop2->size )
833 for (i = 0 ; i < aop1->size ; i++ )
834 if (aop1->aopu.aop_reg[i] !=
835 aop2->aopu.aop_reg[i] )
841 /*-----------------------------------------------------------------*/
842 /* pic16_aopOp - allocates an asmop for an operand : */
843 /*-----------------------------------------------------------------*/
844 void pic16_aopOp (operand *op, iCode *ic, bool result)
853 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
855 /* if this a literal */
856 if (IS_OP_LITERAL(op)) {
857 op->aop = aop = newAsmop(AOP_LIT);
858 aop->aopu.aop_lit = op->operand.valOperand;
859 aop->size = getSize(operandType(op));
864 sym_link *type = operandType(op);
866 if(IS_PTR_CONST(type))
870 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
873 /* if already has a asmop then continue */
877 /* if the underlying symbol has a aop */
878 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
879 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
880 op->aop = OP_SYMBOL(op)->aop;
884 /* if this is a true symbol */
885 if (IS_TRUE_SYMOP(op)) {
886 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
887 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
891 /* this is a temporary : this has
897 e) can be a return use only */
901 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
902 /* if the type is a conditional */
903 if (sym->regType == REG_CND) {
904 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
909 /* if it is spilt then two situations
911 b) has a spill location */
912 if (sym->isspilt || sym->nRegs == 0) {
914 DEBUGpic16_emitcode(";","%d",__LINE__);
915 /* rematerialize it NOW */
918 sym->aop = op->aop = aop =
920 aop->size = getSize(sym->type);
921 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
928 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
929 aop->size = getSize(sym->type);
930 for ( i = 0 ; i < 1 ; i++ ) {
931 aop->aopu.aop_str[i] = accUse[i];
932 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
934 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
935 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
943 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
944 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
945 //pic16_allocDirReg (IC_LEFT(ic));
946 aop->size = getSize(sym->type);
951 aop = op->aop = sym->aop = newAsmop(AOP_STR);
952 aop->size = getSize(sym->type);
953 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
954 aop->aopu.aop_str[i] = fReturn[i];
956 DEBUGpic16_emitcode(";","%d",__LINE__);
960 /* else spill location */
961 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
962 /* force a new aop if sizes differ */
963 sym->usl.spillLoc->aop = NULL;
965 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
966 __FUNCTION__,__LINE__,
967 sym->usl.spillLoc->rname,
968 sym->rname, sym->usl.spillLoc->offset);
970 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
971 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
972 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
974 sym->usl.spillLoc->offset);
975 aop->size = getSize(sym->type);
981 sym_link *type = operandType(op);
983 if(IS_PTR_CONST(type))
987 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
990 /* must be in a register */
991 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
992 sym->aop = op->aop = aop = newAsmop(AOP_REG);
993 aop->size = sym->nRegs;
994 for ( i = 0 ; i < sym->nRegs ;i++)
995 aop->aopu.aop_reg[i] = sym->regs[i];
998 /*-----------------------------------------------------------------*/
999 /* pic16_freeAsmop - free up the asmop given to an operand */
1000 /*----------------------------------------------------------------*/
1001 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1018 /* depending on the asmop type only three cases need work AOP_RO
1019 , AOP_R1 && AOP_STK */
1021 switch (aop->type) {
1025 pic16_emitcode ("pop","ar0");
1029 bitVectUnSetBit(ic->rUsed,R0_IDX);
1035 pic16_emitcode ("pop","ar1");
1039 bitVectUnSetBit(ic->rUsed,R1_IDX);
1045 int stk = aop->aopu.aop_stk + aop->size;
1046 bitVectUnSetBit(ic->rUsed,R0_IDX);
1047 bitVectUnSetBit(ic->rUsed,R1_IDX);
1049 getFreePtr(ic,&aop,FALSE);
1051 if (options.stack10bit)
1053 /* I'm not sure what to do here yet... */
1056 "*** Warning: probably generating bad code for "
1057 "10 bit stack mode.\n");
1061 pic16_emitcode ("mov","a,_bp");
1062 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1063 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1065 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1069 pic16_emitcode("pop","acc");
1070 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1072 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1075 pic16_freeAsmop(op,NULL,ic,TRUE);
1077 pic16_emitcode("pop","ar0");
1082 pic16_emitcode("pop","ar1");
1090 /* all other cases just dealloc */
1094 OP_SYMBOL(op)->aop = NULL;
1095 /* if the symbol has a spill */
1097 SPIL_LOC(op)->aop = NULL;
1102 /*-----------------------------------------------------------------*/
1103 /* pic16_aopGet - for fetching value of the aop */
1104 /*-----------------------------------------------------------------*/
1105 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1110 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1111 /* offset is greater than
1113 if (offset > (aop->size - 1) &&
1114 aop->type != AOP_LIT)
1117 /* depending on type */
1118 switch (aop->type) {
1122 DEBUGpic16_emitcode(";","%d",__LINE__);
1123 /* if we need to increment it */
1124 while (offset > aop->coff) {
1125 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1129 while (offset < aop->coff) {
1130 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1134 aop->coff = offset ;
1136 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1137 return (dname ? "acc" : "a");
1139 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1140 rs = Safe_calloc(1,strlen(s)+1);
1146 DEBUGpic16_emitcode(";","%d",__LINE__);
1147 if (aop->type == AOP_DPTR2)
1152 while (offset > aop->coff) {
1153 pic16_emitcode ("inc","dptr");
1157 while (offset < aop->coff) {
1158 pic16_emitcode("lcall","__decdptr");
1164 pic16_emitcode("clr","a");
1165 pic16_emitcode("movc","a,@a+dptr");
1168 pic16_emitcode("movx","a,@dptr");
1171 if (aop->type == AOP_DPTR2)
1176 return (dname ? "acc" : "a");
1181 sprintf (s,"%s",aop->aopu.aop_immd);
1184 sprintf(s,"(%s >> %d)",
1189 aop->aopu.aop_immd);
1190 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1191 rs = Safe_calloc(1,strlen(s)+1);
1197 sprintf(s,"(%s + %d)",
1200 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1202 sprintf(s,"%s",aop->aopu.aop_dir);
1203 rs = Safe_calloc(1,strlen(s)+1);
1209 // return aop->aopu.aop_reg[offset]->dname;
1211 return aop->aopu.aop_reg[offset]->name;
1214 //pic16_emitcode(";","%d",__LINE__);
1215 return aop->aopu.aop_dir;
1218 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1219 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1221 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1224 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1225 rs = Safe_calloc(1,strlen(s)+1);
1230 aop->coff = offset ;
1231 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1234 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1236 return aop->aopu.aop_str[offset];
1240 pCodeOp *pcop = aop->aopu.pcop;
1241 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1243 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1244 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1245 sprintf(s,"%s", pcop->name);
1247 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1250 rs = Safe_calloc(1,strlen(s)+1);
1256 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1257 "aopget got unsupported aop->type");
1262 /*-----------------------------------------------------------------*/
1263 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1264 /*-----------------------------------------------------------------*/
1265 pCodeOp *pic16_popGetTempReg(void)
1269 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1270 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1271 PCOR(pcop)->r->wasUsed=1;
1272 PCOR(pcop)->r->isFree=0;
1274 /* push value on stack */
1275 pic16_pushpCodeOp( pcop );
1281 /*-----------------------------------------------------------------*/
1282 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1283 /*-----------------------------------------------------------------*/
1284 void pic16_popReleaseTempReg(pCodeOp *pcop)
1286 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1287 PCOR(pcop)->r->isFree = 1;
1289 pic16_poppCodeOp( pcop );
1292 /*-----------------------------------------------------------------*/
1293 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1294 /*-----------------------------------------------------------------*/
1295 pCodeOp *pic16_popGetLabel(unsigned int key)
1298 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1303 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1306 /*-----------------------------------------------------------------*/
1307 /* pic16_popCopyReg - copy a pcode operator */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1313 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1314 pcor->pcop.type = pc->pcop.type;
1316 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1317 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1319 pcor->pcop.name = NULL;
1322 pcor->rIdx = pc->rIdx;
1325 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1330 /*-----------------------------------------------------------------*/
1331 /* pic16_popGetLit - asm operator to pcode operator conversion */
1332 /*-----------------------------------------------------------------*/
1333 pCodeOp *pic16_popGetLit(unsigned int lit)
1335 return pic16_newpCodeOpLit(lit);
1338 /*-----------------------------------------------------------------*/
1339 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1340 /*-----------------------------------------------------------------*/
1341 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1343 return pic16_newpCodeOpLit2(lit, arg2);
1347 /*-----------------------------------------------------------------*/
1348 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1349 /*-----------------------------------------------------------------*/
1350 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1353 return pic16_newpCodeOpImmd(name, offset,index, 0);
1357 /*-----------------------------------------------------------------*/
1358 /* pic16_popGet - asm operator to pcode operator conversion */
1359 /*-----------------------------------------------------------------*/
1360 pCodeOp *pic16_popGetWithString(char *str)
1366 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1370 pcop = pic16_newpCodeOp(str,PO_STR);
1375 /*-----------------------------------------------------------------*/
1376 /* pic16_popRegFromString - */
1377 /*-----------------------------------------------------------------*/
1378 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1381 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1382 pcop->type = PO_DIR;
1384 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1385 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1390 pcop->name = Safe_calloc(1,strlen(str)+1);
1391 strcpy(pcop->name,str);
1393 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1395 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1396 if(PCOR(pcop)->r == NULL) {
1397 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1398 // __FUNCTION__, __LINE__, str, size, offset);
1399 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1401 //fprintf(stderr, "allocating new register -> %s\n", str);
1403 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1405 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1407 PCOR(pcop)->instance = offset;
1412 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1416 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1418 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1419 PCOR(pcop)->rIdx = rIdx;
1420 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1421 PCOR(pcop)->r->isFree = 0;
1422 PCOR(pcop)->r->wasUsed = 1;
1424 pcop->type = PCOR(pcop)->r->pc_type;
1429 /*---------------------------------------------------------------------------------*/
1430 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1432 /*---------------------------------------------------------------------------------*/
1433 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1438 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1440 /* comment the following check, so errors to throw up */
1441 // if(!pcop2)return NULL;
1443 temp = pic16_popGet(aop_dst, offset);
1444 pcop2->pcop2 = temp;
1451 /*--------------------------------------------------------------------------------.-*/
1452 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1453 /* VR 030601 , adapted by Hans Dorn */
1454 /*--------------------------------------------------------------------------------.-*/
1455 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1459 pcop2 = (pCodeOpReg2 *)src;
1467 /*---------------------------------------------------------------------------------*/
1468 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1469 /* movff instruction */
1470 /*---------------------------------------------------------------------------------*/
1471 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1476 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1477 pcop2->pcop2 = pic16_popCopyReg(dst);
1479 /* the pCodeOp may be already allocated */
1480 pcop2 = (pCodeOpReg2 *)(src);
1481 pcop2->pcop2 = (pCodeOp *)(dst);
1488 /*-----------------------------------------------------------------*/
1489 /* pic16_popGet - asm operator to pcode operator conversion */
1490 /*-----------------------------------------------------------------*/
1491 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1493 //char *s = buffer ;
1497 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1498 /* offset is greater than
1501 // if (offset > (aop->size - 1) &&
1502 // aop->type != AOP_LIT)
1503 // return NULL; //zero;
1505 /* depending on type */
1506 switch (aop->type) {
1512 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1513 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1520 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1521 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1524 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1526 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1528 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1530 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1531 PCOR(pcop)->rIdx = rIdx;
1532 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1533 PCOR(pcop)->r->wasUsed=1;
1534 PCOR(pcop)->r->isFree=0;
1536 PCOR(pcop)->instance = offset;
1537 pcop->type = PCOR(pcop)->r->pc_type;
1538 // rs = aop->aopu.aop_reg[offset]->name;
1539 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1543 return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1544 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1549 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1550 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1554 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1556 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1558 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1559 PCOR(pcop)->rIdx = rIdx;
1560 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1561 PCOR(pcop)->r->wasUsed=1;
1562 PCOR(pcop)->r->isFree=0;
1564 PCOR(pcop)->instance = offset;
1565 pcop->type = PCOR(pcop)->r->pc_type;
1566 rs = aop->aopu.aop_reg[offset]->name;
1567 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1572 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1574 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1575 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1576 //if(PCOR(pcop)->r == NULL)
1577 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1581 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1582 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1585 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1586 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1589 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1590 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1591 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1592 pcop->type = PCOR(pcop)->r->pc_type;
1593 pcop->name = PCOR(pcop)->r->name;
1599 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1601 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1602 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1604 switch( aop->aopu.pcop->type ) {
1605 case PO_DIR: PCOR(pcop)->instance = offset; break;
1606 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1608 assert( 0 ); /* should never reach here */;
1611 PCOI(pcop)->offset = offset;
1616 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1617 "pic16_popGet got unsupported aop->type");
1620 /*-----------------------------------------------------------------*/
1621 /* pic16_aopPut - puts a string for a aop */
1622 /*-----------------------------------------------------------------*/
1623 void pic16_aopPut (asmop *aop, char *s, int offset)
1628 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1630 if (aop->size && offset > ( aop->size - 1)) {
1631 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1632 "pic16_aopPut got offset > aop->size");
1636 /* will assign value to value */
1637 /* depending on where it is ofcourse */
1638 switch (aop->type) {
1641 sprintf(d,"(%s + %d)",
1642 aop->aopu.aop_dir,offset);
1643 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1646 sprintf(d,"%s",aop->aopu.aop_dir);
1649 DEBUGpic16_emitcode(";","%d",__LINE__);
1651 pic16_emitcode("movf","%s,w",s);
1652 pic16_emitcode("movwf","%s",d);
1655 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1656 if(offset >= aop->size) {
1657 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1660 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1663 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1670 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1671 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1674 strcmp(s,"r0") == 0 ||
1675 strcmp(s,"r1") == 0 ||
1676 strcmp(s,"r2") == 0 ||
1677 strcmp(s,"r3") == 0 ||
1678 strcmp(s,"r4") == 0 ||
1679 strcmp(s,"r5") == 0 ||
1680 strcmp(s,"r6") == 0 ||
1681 strcmp(s,"r7") == 0 )
1682 pic16_emitcode("mov","%s,%s ; %d",
1683 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1687 if(strcmp(s,"W")==0 )
1688 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1690 pic16_emitcode("movwf","%s",
1691 aop->aopu.aop_reg[offset]->name);
1693 if(strcmp(s,zero)==0) {
1694 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1696 } else if(strcmp(s,"W")==0) {
1697 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1698 pcop->type = PO_GPR_REGISTER;
1700 PCOR(pcop)->rIdx = -1;
1701 PCOR(pcop)->r = NULL;
1703 DEBUGpic16_emitcode(";","%d",__LINE__);
1704 pcop->name = Safe_strdup(s);
1705 pic16_emitpcode(POC_MOVFW,pcop);
1706 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1707 } else if(strcmp(s,one)==0) {
1708 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1709 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1711 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1719 if (aop->type == AOP_DPTR2)
1725 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1726 "pic16_aopPut writting to code space");
1730 while (offset > aop->coff) {
1732 pic16_emitcode ("inc","dptr");
1735 while (offset < aop->coff) {
1737 pic16_emitcode("lcall","__decdptr");
1742 /* if not in accumulater */
1745 pic16_emitcode ("movx","@dptr,a");
1747 if (aop->type == AOP_DPTR2)
1755 while (offset > aop->coff) {
1757 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1759 while (offset < aop->coff) {
1761 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1767 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1772 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1774 if (strcmp(s,"r0") == 0 ||
1775 strcmp(s,"r1") == 0 ||
1776 strcmp(s,"r2") == 0 ||
1777 strcmp(s,"r3") == 0 ||
1778 strcmp(s,"r4") == 0 ||
1779 strcmp(s,"r5") == 0 ||
1780 strcmp(s,"r6") == 0 ||
1781 strcmp(s,"r7") == 0 ) {
1783 sprintf(buffer,"a%s",s);
1784 pic16_emitcode("mov","@%s,%s",
1785 aop->aopu.aop_ptr->name,buffer);
1787 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1792 if (strcmp(s,"a") == 0)
1793 pic16_emitcode("push","acc");
1795 pic16_emitcode("push","%s",s);
1800 /* if bit variable */
1801 if (!aop->aopu.aop_dir) {
1802 pic16_emitcode("clr","a");
1803 pic16_emitcode("rlc","a");
1806 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1809 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1812 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1814 lbl = newiTempLabel(NULL);
1816 if (strcmp(s,"a")) {
1819 pic16_emitcode("clr","c");
1820 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1821 pic16_emitcode("cpl","c");
1822 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1823 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1830 if (strcmp(aop->aopu.aop_str[offset],s))
1831 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1836 if (!offset && (strcmp(s,"acc") == 0))
1839 if (strcmp(aop->aopu.aop_str[offset],s))
1840 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1844 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1845 "pic16_aopPut got unsupported aop->type");
1851 /*-----------------------------------------------------------------*/
1852 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1853 /*-----------------------------------------------------------------*/
1854 static void mov2w (asmop *aop, int offset)
1860 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1862 if ( aop->type == AOP_PCODE ||
1863 aop->type == AOP_LIT )
1864 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1866 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1871 /* push pcop into stack */
1872 void pic16_pushpCodeOp(pCodeOp *pcop)
1874 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1877 /* pop pcop from stack */
1878 void pic16_poppCodeOp(pCodeOp *pcop)
1880 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1884 /*-----------------------------------------------------------------*/
1885 /* pushw - pushes wreg to stack */
1886 /*-----------------------------------------------------------------*/
1889 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1890 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1894 /*-----------------------------------------------------------------*/
1895 /* pushaop - pushes aop to stack */
1896 /*-----------------------------------------------------------------*/
1897 void pushaop(asmop *aop, int offset)
1899 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1900 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1903 /*-----------------------------------------------------------------*/
1904 /* popaop - pops aop from stack */
1905 /*-----------------------------------------------------------------*/
1906 void popaop(asmop *aop, int offset)
1908 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1909 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1912 void popaopidx(asmop *aop, int offset, int index)
1916 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1918 if(STACK_MODEL_LARGE)ofs++;
1920 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1921 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1924 /*-----------------------------------------------------------------*/
1925 /* reAdjustPreg - points a register back to where it should */
1926 /*-----------------------------------------------------------------*/
1927 static void reAdjustPreg (asmop *aop)
1931 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1933 if ((size = aop->size) <= 1)
1936 switch (aop->type) {
1940 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1944 if (aop->type == AOP_DPTR2)
1950 pic16_emitcode("lcall","__decdptr");
1953 if (aop->type == AOP_DPTR2)
1965 /*-----------------------------------------------------------------*/
1966 /* opIsGptr: returns non-zero if the passed operand is */
1967 /* a generic pointer type. */
1968 /*-----------------------------------------------------------------*/
1969 static int opIsGptr(operand *op)
1971 sym_link *type = operandType(op);
1973 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1974 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1982 /*-----------------------------------------------------------------*/
1983 /* pic16_getDataSize - get the operand data size */
1984 /*-----------------------------------------------------------------*/
1985 int pic16_getDataSize(operand *op)
1987 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1990 return AOP_SIZE(op);
1992 // tsd- in the pic port, the genptr size is 1, so this code here
1993 // fails. ( in the 8051 port, the size was 4).
1996 size = AOP_SIZE(op);
1997 if (size == GPTRSIZE)
1999 sym_link *type = operandType(op);
2000 if (IS_GENPTR(type))
2002 /* generic pointer; arithmetic operations
2003 * should ignore the high byte (pointer type).
2006 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2013 /*-----------------------------------------------------------------*/
2014 /* pic16_outAcc - output Acc */
2015 /*-----------------------------------------------------------------*/
2016 void pic16_outAcc(operand *result)
2019 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2020 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2023 size = pic16_getDataSize(result);
2025 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2028 /* unsigned or positive */
2030 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2035 /*-----------------------------------------------------------------*/
2036 /* pic16_outBitC - output a bit C */
2037 /*-----------------------------------------------------------------*/
2038 void pic16_outBitC(operand *result)
2041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2042 /* if the result is bit */
2043 if (AOP_TYPE(result) == AOP_CRY)
2044 pic16_aopPut(AOP(result),"c",0);
2046 pic16_emitcode("clr","a ; %d", __LINE__);
2047 pic16_emitcode("rlc","a");
2048 pic16_outAcc(result);
2052 /*-----------------------------------------------------------------*/
2053 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2054 /*-----------------------------------------------------------------*/
2055 void pic16_toBoolean(operand *oper)
2057 int size = AOP_SIZE(oper) - 1;
2060 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2062 if ( AOP_TYPE(oper) != AOP_ACC) {
2063 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2066 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2071 #if !defined(GEN_Not)
2072 /*-----------------------------------------------------------------*/
2073 /* genNot - generate code for ! operation */
2074 /*-----------------------------------------------------------------*/
2075 static void pic16_genNot (iCode *ic)
2080 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2081 /* assign asmOps to operand & result */
2082 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2083 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2085 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2086 /* if in bit space then a special case */
2087 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2088 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2089 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2090 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2092 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2093 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2094 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2099 size = AOP_SIZE(IC_LEFT(ic));
2101 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2102 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2103 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2106 pic16_toBoolean(IC_LEFT(ic));
2108 tlbl = newiTempLabel(NULL);
2109 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2110 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2111 pic16_outBitC(IC_RESULT(ic));
2114 /* release the aops */
2115 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2116 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2121 #if !defined(GEN_Cpl)
2122 /*-----------------------------------------------------------------*/
2123 /* genCpl - generate code for complement */
2124 /*-----------------------------------------------------------------*/
2125 static void pic16_genCpl (iCode *ic)
2131 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2132 /* assign asmOps to operand & result */
2133 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2134 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2136 /* if both are in bit space then
2138 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2139 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2141 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2142 pic16_emitcode("cpl","c");
2143 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2147 size = AOP_SIZE(IC_RESULT(ic));
2150 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2152 pic16_emitcode("cpl","a");
2153 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2155 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2156 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2158 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2159 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2167 /* release the aops */
2168 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2169 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2173 /*-----------------------------------------------------------------*/
2174 /* genUminusFloat - unary minus for floating points */
2175 /*-----------------------------------------------------------------*/
2176 static void genUminusFloat(operand *op,operand *result)
2178 int size ,offset =0 ;
2181 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2182 /* for this we just need to flip the
2183 first it then copy the rest in place */
2184 size = AOP_SIZE(op) - 1;
2185 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2189 pic16_emitcode("cpl","acc.7");
2190 pic16_aopPut(AOP(result),"a",3);
2193 pic16_aopPut(AOP(result),
2194 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2200 /*-----------------------------------------------------------------*/
2201 /* genUminus - unary minus code generation */
2202 /*-----------------------------------------------------------------*/
2203 static void genUminus (iCode *ic)
2206 sym_link *optype, *rtype;
2209 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2211 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2212 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2214 /* if both in bit space then special
2216 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2217 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2219 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2220 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2221 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2226 optype = operandType(IC_LEFT(ic));
2227 rtype = operandType(IC_RESULT(ic));
2229 /* if float then do float stuff */
2230 if (IS_FLOAT(optype)) {
2231 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2235 /* otherwise subtract from zero by taking the 2's complement */
2236 size = AOP_SIZE(IC_LEFT(ic));
2238 for(i=0; i<size; i++) {
2239 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2240 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2242 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2243 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2247 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2248 for(i=1; i<size; i++) {
2250 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2254 /* release the aops */
2255 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2256 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2259 /*-----------------------------------------------------------------*/
2260 /* saveRegisters - will look for a call and save the registers */
2261 /*-----------------------------------------------------------------*/
2262 static void saveRegisters(iCode *lic)
2269 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2271 for (ic = lic ; ic ; ic = ic->next)
2272 if (ic->op == CALL || ic->op == PCALL)
2276 fprintf(stderr,"found parameter push with no function call\n");
2280 /* if the registers have been saved already then
2282 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2285 /* find the registers in use at this time
2286 and push them away to safety */
2287 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2291 if (options.useXstack) {
2292 if (bitVectBitValue(rsave,R0_IDX))
2293 pic16_emitcode("mov","b,r0");
2294 pic16_emitcode("mov","r0,%s",spname);
2295 for (i = 0 ; i < pic16_nRegs ; i++) {
2296 if (bitVectBitValue(rsave,i)) {
2298 pic16_emitcode("mov","a,b");
2300 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2301 pic16_emitcode("movx","@r0,a");
2302 pic16_emitcode("inc","r0");
2305 pic16_emitcode("mov","%s,r0",spname);
2306 if (bitVectBitValue(rsave,R0_IDX))
2307 pic16_emitcode("mov","r0,b");
2309 //for (i = 0 ; i < pic16_nRegs ; i++) {
2310 // if (bitVectBitValue(rsave,i))
2311 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2314 dtype = operandType(IC_LEFT(ic));
2315 if (currFunc && dtype &&
2316 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2317 IFFUNC_ISISR(currFunc->type) &&
2320 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2323 /*-----------------------------------------------------------------*/
2324 /* unsaveRegisters - pop the pushed registers */
2325 /*-----------------------------------------------------------------*/
2326 static void unsaveRegisters (iCode *ic)
2331 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2332 /* find the registers in use at this time
2333 and push them away to safety */
2334 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2337 if (options.useXstack) {
2338 pic16_emitcode("mov","r0,%s",spname);
2339 for (i = pic16_nRegs ; i >= 0 ; i--) {
2340 if (bitVectBitValue(rsave,i)) {
2341 pic16_emitcode("dec","r0");
2342 pic16_emitcode("movx","a,@r0");
2344 pic16_emitcode("mov","b,a");
2346 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2350 pic16_emitcode("mov","%s,r0",spname);
2351 if (bitVectBitValue(rsave,R0_IDX))
2352 pic16_emitcode("mov","r0,b");
2354 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2355 // if (bitVectBitValue(rsave,i))
2356 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2362 /*-----------------------------------------------------------------*/
2364 /*-----------------------------------------------------------------*/
2365 static void pushSide(operand * oper, int size)
2369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2371 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2372 if (AOP_TYPE(oper) != AOP_REG &&
2373 AOP_TYPE(oper) != AOP_DIR &&
2375 pic16_emitcode("mov","a,%s",l);
2376 pic16_emitcode("push","acc");
2378 pic16_emitcode("push","%s",l);
2383 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2385 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2387 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2388 pic16_emitpcode(POC_MOVFW, src);
2389 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2391 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2392 src, pic16_popGet(AOP(op), offset)));
2397 /*-----------------------------------------------------------------*/
2398 /* assignResultValue - assign results to oper, rescall==1 is */
2399 /* called from genCall() or genPCall() */
2400 /*-----------------------------------------------------------------*/
2401 static void assignResultValue(operand * oper, int rescall)
2403 int size = AOP_SIZE(oper);
2405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2406 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2409 /* assign result from a call/pcall function() */
2411 /* function results are stored in a special order,
2412 * see top of file with Function return policy, or manual */
2415 /* 8-bits, result in WREG */
2416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2419 /* 16-bits, result in PRODL:WREG */
2420 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2421 // pic16_emitpcode(POC_MOVFF,
2422 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1)));
2426 /* 24-bits, result in PRODH:PRODL:WREG */
2427 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodl));
2429 // pic16_emitpcode(POC_MOVFF,
2430 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2)));
2434 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2435 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_prodl));
2437 // pic16_emitpcode(POC_MOVFF,
2438 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3)));
2441 /* >32-bits, result on stack, and FSR0 points to beginning.
2442 * Fix stack when done */
2445 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2446 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2448 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2453 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2454 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2455 if(STACK_MODEL_LARGE) {
2457 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2461 if(!GpsuedoStkPtr) {
2462 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2463 /* The last byte in the assignment is in W */
2465 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2470 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2471 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2473 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2479 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2481 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2491 /*-----------------------------------------------------------------*/
2492 /* genIpush - genrate code for pushing this gets a little complex */
2493 /*-----------------------------------------------------------------*/
2494 static void genIpush (iCode *ic)
2497 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2499 int size, offset = 0 ;
2503 /* if this is not a parm push : ie. it is spill push
2504 and spill push is always done on the local stack */
2505 if (!ic->parmPush) {
2507 /* and the item is spilt then do nothing */
2508 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2511 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2512 size = AOP_SIZE(IC_LEFT(ic));
2513 /* push it on the stack */
2515 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2520 pic16_emitcode("push","%s",l);
2525 /* this is a paramter push: in this case we call
2526 the routine to find the call and save those
2527 registers that need to be saved */
2530 /* then do the push */
2531 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2534 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2535 size = AOP_SIZE(IC_LEFT(ic));
2538 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2539 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2540 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2542 pic16_emitcode("mov","a,%s",l);
2543 pic16_emitcode("push","acc");
2545 pic16_emitcode("push","%s",l);
2548 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2552 /*-----------------------------------------------------------------*/
2553 /* genIpop - recover the registers: can happen only for spilling */
2554 /*-----------------------------------------------------------------*/
2555 static void genIpop (iCode *ic)
2557 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2562 /* if the temp was not pushed then */
2563 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2566 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2567 size = AOP_SIZE(IC_LEFT(ic));
2570 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2573 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2577 /*-----------------------------------------------------------------*/
2578 /* unsaverbank - restores the resgister bank from stack */
2579 /*-----------------------------------------------------------------*/
2580 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2582 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2588 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2590 if (options.useXstack) {
2592 r = getFreePtr(ic,&aop,FALSE);
2595 pic16_emitcode("mov","%s,_spx",r->name);
2596 pic16_emitcode("movx","a,@%s",r->name);
2597 pic16_emitcode("mov","psw,a");
2598 pic16_emitcode("dec","%s",r->name);
2601 pic16_emitcode ("pop","psw");
2604 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2605 if (options.useXstack) {
2606 pic16_emitcode("movx","a,@%s",r->name);
2607 //pic16_emitcode("mov","(%s+%d),a",
2608 // regspic16[i].base,8*bank+regspic16[i].offset);
2609 pic16_emitcode("dec","%s",r->name);
2612 pic16_emitcode("pop",""); //"(%s+%d)",
2613 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2616 if (options.useXstack) {
2618 pic16_emitcode("mov","_spx,%s",r->name);
2619 pic16_freeAsmop(NULL,aop,ic,TRUE);
2625 /*-----------------------------------------------------------------*/
2626 /* saverbank - saves an entire register bank on the stack */
2627 /*-----------------------------------------------------------------*/
2628 static void saverbank (int bank, iCode *ic, bool pushPsw)
2630 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2637 if (options.useXstack) {
2640 r = getFreePtr(ic,&aop,FALSE);
2641 pic16_emitcode("mov","%s,_spx",r->name);
2645 for (i = 0 ; i < pic16_nRegs ;i++) {
2646 if (options.useXstack) {
2647 pic16_emitcode("inc","%s",r->name);
2648 //pic16_emitcode("mov","a,(%s+%d)",
2649 // regspic16[i].base,8*bank+regspic16[i].offset);
2650 pic16_emitcode("movx","@%s,a",r->name);
2652 pic16_emitcode("push","");// "(%s+%d)",
2653 //regspic16[i].base,8*bank+regspic16[i].offset);
2657 if (options.useXstack) {
2658 pic16_emitcode("mov","a,psw");
2659 pic16_emitcode("movx","@%s,a",r->name);
2660 pic16_emitcode("inc","%s",r->name);
2661 pic16_emitcode("mov","_spx,%s",r->name);
2662 pic16_freeAsmop (NULL,aop,ic,TRUE);
2665 pic16_emitcode("push","psw");
2667 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2675 /*-----------------------------------------------------------------*/
2676 /* genCall - generates a call statement */
2677 /*-----------------------------------------------------------------*/
2678 static void genCall (iCode *ic)
2683 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2685 /* if caller saves & we have not saved then */
2689 /* if we are calling a function that is not using
2690 * the same register bank then we need to save the
2691 * destination registers on the stack */
2692 dtype = operandType(IC_LEFT(ic));
2693 if (currFunc && dtype &&
2694 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2695 IFFUNC_ISISR(currFunc->type) &&
2698 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2700 /* if send set is not empty the assign */
2704 /* For the Pic port, there is no data stack.
2705 * So parameters passed to functions are stored
2706 * in registers. (The pCode optimizer will get
2707 * rid of most of these :). */
2709 int psuedoStkPtr=-1;
2710 int firstTimeThruLoop = 1;
2712 _G.sendSet = reverseSet(_G.sendSet);
2714 /* First figure how many parameters are getting passed */
2715 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2716 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2717 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2718 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2721 stackParms = psuedoStkPtr;
2723 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2724 int size, offset = 0;
2726 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2727 size = AOP_SIZE(IC_LEFT(sic));
2730 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2731 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2732 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2734 if(!firstTimeThruLoop) {
2735 /* If this is not the first time we've been through the loop
2736 * then we need to save the parameter in a temporary
2737 * register. The last byte of the last parameter is
2741 --psuedoStkPtr; // sanity check
2744 firstTimeThruLoop=0;
2746 mov2w (AOP(IC_LEFT(sic)), offset);
2749 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2755 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2756 OP_SYMBOL(IC_LEFT(ic))->rname :
2757 OP_SYMBOL(IC_LEFT(ic))->name));
2760 /* if we need assign a result value */
2761 if ((IS_ITEMP(IC_RESULT(ic)) &&
2762 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2763 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2764 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2767 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2770 assignResultValue(IC_RESULT(ic), 1);
2772 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2773 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2775 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2779 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2780 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2781 if(STACK_MODEL_LARGE) {
2783 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2787 /* adjust the stack for parameters if required */
2788 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2790 if (ic->parmBytes) {
2793 if (ic->parmBytes > 3) {
2794 pic16_emitcode("mov","a,%s",spname);
2795 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2796 pic16_emitcode("mov","%s,a",spname);
2798 for ( i = 0 ; i < ic->parmBytes ;i++)
2799 pic16_emitcode("dec","%s",spname);
2802 /* if register bank was saved then pop them */
2804 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2806 /* if we hade saved some registers then unsave them */
2807 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2808 unsaveRegisters (ic);
2811 /*-----------------------------------------------------------------*/
2812 /* genPcall - generates a call by pointer statement */
2813 /*-----------------------------------------------------------------*/
2814 static void genPcall (iCode *ic)
2817 symbol *rlbl = newiTempLabel(NULL);
2820 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2821 /* if caller saves & we have not saved then */
2825 /* if we are calling a function that is not using
2826 the same register bank then we need to save the
2827 destination registers on the stack */
2828 dtype = operandType(IC_LEFT(ic));
2829 if (currFunc && dtype &&
2830 IFFUNC_ISISR(currFunc->type) &&
2831 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2832 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2835 /* push the return address on to the stack */
2836 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2837 pic16_emitcode("push","acc");
2838 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2839 pic16_emitcode("push","acc");
2841 if (options.model == MODEL_FLAT24)
2843 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2844 pic16_emitcode("push","acc");
2847 /* now push the calling address */
2848 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2850 pushSide(IC_LEFT(ic), FPTRSIZE);
2852 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2854 /* if send set is not empty the assign */
2858 for (sic = setFirstItem(_G.sendSet) ; sic ;
2859 sic = setNextItem(_G.sendSet)) {
2860 int size, offset = 0;
2861 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2862 size = AOP_SIZE(IC_LEFT(sic));
2864 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2866 if (strcmp(l,fReturn[offset]))
2867 pic16_emitcode("mov","%s,%s",
2872 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2877 pic16_emitcode("ret","");
2878 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2881 /* if we need assign a result value */
2882 if ((IS_ITEMP(IC_RESULT(ic)) &&
2883 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2884 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2885 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2888 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2891 assignResultValue(IC_RESULT(ic), 1);
2893 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2896 /* adjust the stack for parameters if
2898 if (ic->parmBytes) {
2900 if (ic->parmBytes > 3) {
2901 pic16_emitcode("mov","a,%s",spname);
2902 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2903 pic16_emitcode("mov","%s,a",spname);
2905 for ( i = 0 ; i < ic->parmBytes ;i++)
2906 pic16_emitcode("dec","%s",spname);
2910 /* if register bank was saved then unsave them */
2911 if (currFunc && dtype &&
2912 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2913 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2915 /* if we hade saved some registers then
2918 unsaveRegisters (ic);
2922 /*-----------------------------------------------------------------*/
2923 /* resultRemat - result is rematerializable */
2924 /*-----------------------------------------------------------------*/
2925 static int resultRemat (iCode *ic)
2927 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2928 if (SKIP_IC(ic) || ic->op == IFX)
2931 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2932 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2933 if (sym->remat && !POINTER_SET(ic))
2940 #if defined(__BORLANDC__) || defined(_MSC_VER)
2941 #define STRCASECMP stricmp
2943 #define STRCASECMP strcasecmp
2947 /*-----------------------------------------------------------------*/
2948 /* inExcludeList - return 1 if the string is in exclude Reg list */
2949 /*-----------------------------------------------------------------*/
2950 static bool inExcludeList(char *s)
2952 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2956 if (options.excludeRegs[i] &&
2957 STRCASECMP(options.excludeRegs[i],"none") == 0)
2960 for ( i = 0 ; options.excludeRegs[i]; i++) {
2961 if (options.excludeRegs[i] &&
2962 STRCASECMP(s,options.excludeRegs[i]) == 0)
2969 /*-----------------------------------------------------------------*/
2970 /* genFunction - generated code for function entry */
2971 /*-----------------------------------------------------------------*/
2972 static void genFunction (iCode *ic)
2977 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2979 labelOffset += (max_key+4);
2984 ftype = operandType(IC_LEFT(ic));
2986 if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) {
2987 /* create an absolute section at the interrupt vector:
2988 * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */
2996 sym = OP_SYMBOL( IC_LEFT(ic));
2998 if(STRCASECMP(interrupts[i]->name, sym->name))break;
3001 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3002 __FILE__, __LINE__, sym->name);
3007 sprintf(asymname, "ivec_%s", sym->name);
3008 asym = newSymbol(asymname, 0);
3009 pic16_emitcode(";","-----------------------------------------");
3010 pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name);
3011 pic16_emitcode(";","-----------------------------------------");
3012 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name));
3013 pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname ));
3015 pic16_pBlockConvert2Absolute(pb);
3019 /* create the function header */
3020 pic16_emitcode(";","-----------------------------------------");
3021 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
3022 pic16_emitcode(";","-----------------------------------------");
3024 pic16_emitcode("","%s:",sym->rname);
3025 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3030 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3031 if(strcmp(ab->name, sym->name)) {
3032 pic16_pBlockConvert2Absolute(pb);
3039 if(IFFUNC_ISNAKED(ftype)) {
3040 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3044 /* if critical function then turn interrupts off */
3045 if (IFFUNC_ISCRITICAL(ftype))
3046 pic16_emitcode("clr","ea");
3048 /* if this is an interrupt service routine then
3049 * save acc, b, dpl, dph */
3050 if (IFFUNC_ISISR(sym->type)) {
3052 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH */
3053 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3054 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3055 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3056 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3057 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3058 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3059 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3063 /* VR -- this is the old code which clears STATUS register for
3064 * the ISR routine. Why? */
3065 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
3066 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
3067 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3068 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
3071 pic16_pBlockConvert2ISR(pb);
3074 if (!inExcludeList("acc"))
3075 pic16_emitcode ("push","acc");
3076 if (!inExcludeList("b"))
3077 pic16_emitcode ("push","b");
3078 if (!inExcludeList("dpl"))
3079 pic16_emitcode ("push","dpl");
3080 if (!inExcludeList("dph"))
3081 pic16_emitcode ("push","dph");
3084 /* if any registers used */
3085 if (sym->regsUsed) {
3086 /* save the registers used */
3087 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3088 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3089 if (bitVectBitValue(sym->regsUsed,i)) {
3090 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3091 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3092 // pic16_regWithIdx(i)->name);
3094 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3100 /* emit code to setup stack frame if user enabled,
3101 * and function is not main() */
3103 // fprintf(stderr, "function name: %s\n", sym->name);
3104 if(strcmp(sym->name, "main")) {
3105 if(!options.ommitFramePtr || sym->regsUsed) {
3106 /* setup the stack frame */
3107 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3108 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3109 if(STACK_MODEL_LARGE)
3110 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3114 /* if callee-save to be used for this function
3115 * then save the registers being used in this function */
3116 if (IFFUNC_CALLEESAVES(sym->type)) {
3119 // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
3121 /* if any registers used */
3122 if (sym->regsUsed) {
3123 /* save the registers used */
3124 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3125 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3126 if (bitVectBitValue(sym->regsUsed,i)) {
3127 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3128 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3129 // pic16_regWithIdx(i)->name);
3131 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3132 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3133 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3134 // &pic16_pc_postdec1, 0));
3145 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3147 if (options.useXstack) {
3148 pic16_emitcode("mov","r0,%s",spname);
3149 pic16_emitcode("mov","a,_bp");
3150 pic16_emitcode("movx","@r0,a");
3151 pic16_emitcode("inc","%s",spname);
3153 /* set up the stack */
3154 pic16_emitcode ("push","_bp"); /* save the callers stack */
3156 pic16_emitcode ("mov","_bp,%s",spname);
3159 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3161 /* adjust the stack for the function */
3166 werror(W_STACK_OVERFLOW,sym->name);
3168 if (i > 3 && sym->recvSize < 4) {
3169 pic16_emitcode ("mov","a,sp");
3170 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3171 pic16_emitcode ("mov","sp,a");
3174 pic16_emitcode("inc","sp");
3178 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3180 pic16_emitcode ("mov","a,_spx");
3181 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3182 pic16_emitcode ("mov","_spx,a");
3187 /*-----------------------------------------------------------------*/
3188 /* genEndFunction - generates epilogue for functions */
3189 /*-----------------------------------------------------------------*/
3190 static void genEndFunction (iCode *ic)
3192 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3196 if(IFFUNC_ISNAKED(sym->type)) {
3197 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3202 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3204 pic16_emitcode ("mov","%s,_bp",spname);
3208 /* if use external stack but some variables were
3209 added to the local stack then decrement the
3211 if (options.useXstack && sym->stack) {
3212 pic16_emitcode("mov","a,sp");
3213 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3214 pic16_emitcode("mov","sp,a");
3219 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3220 if (options.useXstack) {
3221 pic16_emitcode("mov","r0,%s",spname);
3222 pic16_emitcode("movx","a,@r0");
3223 pic16_emitcode("mov","_bp,a");
3224 pic16_emitcode("dec","%s",spname);
3228 pic16_emitcode ("pop","_bp");
3233 /* restore the register bank */
3234 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3235 pic16_emitcode ("pop","psw");
3237 if (IFFUNC_ISISR(sym->type)) {
3239 /* now we need to restore the registers */
3241 /* if any registers used */
3242 if (sym->regsUsed) {
3245 /* restore registers used */
3246 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3247 for ( i = sym->regsUsed->size; i >= 0; i--) {
3248 if (bitVectBitValue(sym->regsUsed,i)) {
3249 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3250 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3251 // pic16_regWithIdx(i)->name);
3253 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3255 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3260 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3261 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3262 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3263 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3264 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3265 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3266 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3269 /* if debug then send end of function */
3270 /* if (options.debug && currFunc) */
3273 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3274 FileBaseName(ic->filename),currFunc->lastLine,
3275 ic->level,ic->block);
3276 if (IS_STATIC(currFunc->etype))
3277 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3279 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3284 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3285 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3286 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3287 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3288 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3291 pic16_emitpcodeNULLop(POC_RETFIE);
3294 if (IFFUNC_ISCRITICAL(sym->type))
3295 pic16_emitcode("setb","ea");
3297 /* if any registers used */
3298 if (sym->regsUsed) {
3300 /* save the registers used */
3301 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3302 for ( i = sym->regsUsed->size; i >= 0; i--) {
3303 if (bitVectBitValue(sym->regsUsed,i)) {
3304 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3305 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3306 // pic16_regWithIdx(i)->name);
3308 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3310 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3316 /* if debug then send end of function */
3319 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3320 FileBaseName(ic->filename),currFunc->lastLine,
3321 ic->level,ic->block);
3322 if (IS_STATIC(currFunc->etype))
3323 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3325 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3329 /* insert code to restore stack frame, if user enabled it
3330 * and function is not main() */
3332 if(strcmp(sym->name, "main")) {
3333 if(!options.ommitFramePtr || sym->regsUsed) {
3334 /* restore stack frame */
3335 if(STACK_MODEL_LARGE)
3336 pic16_emitpcode(POC_MOVFF,
3337 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3338 pic16_emitpcode(POC_MOVFF,
3339 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3343 pic16_emitcode ("return","");
3344 pic16_emitpcodeNULLop(POC_RETURN);
3346 /* Mark the end of a function */
3347 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3353 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3355 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3357 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3358 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3359 pic16_emitpcode(POC_MOVWF, dest);
3361 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3362 pic16_popGet(AOP(op), offset), dest));
3366 /*-----------------------------------------------------------------*/
3367 /* genRet - generate code for return statement */
3368 /*-----------------------------------------------------------------*/
3369 static void genRet (iCode *ic)
3374 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3375 /* if we have no return value then
3376 * just generate the "ret" */
3381 /* we have something to return then
3382 * move the return value into place */
3383 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3384 size = AOP_SIZE(IC_LEFT(ic));
3388 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3389 // pic16_emitpcode(POC_MOVFF,
3390 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3393 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3394 // pic16_emitpcode(POC_MOVFF,
3395 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3398 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3399 // pic16_emitpcode(POC_MOVFF,
3400 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3403 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0));
3405 // pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg));
3406 // pic16_emitpcode(POC_MOVFF,
3407 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3410 /* >32-bits, setup stack and FSR0 */
3412 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3413 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3415 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3417 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3422 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3423 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3425 if(STACK_MODEL_LARGE) {
3426 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3427 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3429 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3434 /* old code, left here for reference -- VR */
3438 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3440 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3441 pic16_emitpcomment("push %s",l);
3444 DEBUGpic16_emitcode(";", "%d", __LINE__);
3445 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3446 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3448 if (strcmp(fReturn[offset],l)) {
3449 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3450 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3451 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3453 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3457 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3467 if (strcmp(fReturn[pushed],"a"))
3468 pic16_emitcode("pop",fReturn[pushed]);
3470 pic16_emitcode("pop","acc");
3476 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3479 /* generate a jump to the return label
3480 * if the next is not the return statement */
3481 if (!(ic->next && ic->next->op == LABEL
3482 && IC_LABEL(ic->next) == returnLabel)) {
3484 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3485 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3489 /*-----------------------------------------------------------------*/
3490 /* genLabel - generates a label */
3491 /*-----------------------------------------------------------------*/
3492 static void genLabel (iCode *ic)
3494 /* special case never generate */
3495 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3496 if (IC_LABEL(ic) == entryLabel)
3499 pic16_emitpLabel(IC_LABEL(ic)->key);
3500 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3503 /*-----------------------------------------------------------------*/
3504 /* genGoto - generates a goto */
3505 /*-----------------------------------------------------------------*/
3507 static void genGoto (iCode *ic)
3509 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3510 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3514 /*-----------------------------------------------------------------*/
3515 /* genMultbits :- multiplication of bits */
3516 /*-----------------------------------------------------------------*/
3517 static void genMultbits (operand *left,
3521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3523 if(!pic16_sameRegs(AOP(result),AOP(right)))
3524 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3526 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3527 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3528 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3533 /*-----------------------------------------------------------------*/
3534 /* genMultOneByte : 8 bit multiplication & division */
3535 /*-----------------------------------------------------------------*/
3536 static void genMultOneByte (operand *left,
3540 sym_link *opetype = operandType(result);
3545 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3546 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3547 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3549 /* (if two literals, the value is computed before) */
3550 /* if one literal, literal on the right */
3551 if (AOP_TYPE(left) == AOP_LIT){
3557 size = AOP_SIZE(result);
3560 if (AOP_TYPE(right) == AOP_LIT){
3561 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3562 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3563 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3564 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3566 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3567 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3568 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3569 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3571 pic16_genMult8X8_8 (left, right,result);
3572 } else { // (size > 1)
3574 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3575 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3576 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3577 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3579 if (SPEC_USIGN(opetype)){
3580 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3581 pic16_genUMult8X8_16 (left, right, result, NULL);
3584 /* for filling the MSBs */
3585 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3586 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3590 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3592 pic16_emitcode("mov","a,b");
3594 /* adjust the MSB if left or right neg */
3596 /* if one literal */
3597 if (AOP_TYPE(right) == AOP_LIT){
3598 pic16_emitcode("multiply ","right is a lit");
3599 /* AND literal negative */
3600 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3601 /* adjust MSB (c==0 after mul) */
3602 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3606 pic16_genSMult8X8_16 (left, right, result, NULL);
3610 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3612 pic16_emitcode("rlc","a");
3613 pic16_emitcode("subb","a,acc");
3621 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3622 //pic16_aopPut(AOP(result),"a",offset++);
3626 /*-----------------------------------------------------------------*/
3627 /* genMult - generates code for multiplication */
3628 /*-----------------------------------------------------------------*/
3629 static void genMult (iCode *ic)
3631 operand *left = IC_LEFT(ic);
3632 operand *right = IC_RIGHT(ic);
3633 operand *result= IC_RESULT(ic);
3635 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3636 /* assign the amsops */
3637 pic16_aopOp (left,ic,FALSE);
3638 pic16_aopOp (right,ic,FALSE);
3639 pic16_aopOp (result,ic,TRUE);
3641 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3643 /* special cases first */
3645 if (AOP_TYPE(left) == AOP_CRY &&
3646 AOP_TYPE(right)== AOP_CRY) {
3647 genMultbits(left,right,result);
3651 /* if both are of size == 1 */
3652 if (AOP_SIZE(left) == 1 &&
3653 AOP_SIZE(right) == 1 ) {
3654 genMultOneByte(left,right,result);
3658 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3660 /* should have been converted to function call */
3664 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3665 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3666 pic16_freeAsmop(result,NULL,ic,TRUE);
3669 /*-----------------------------------------------------------------*/
3670 /* genDivbits :- division of bits */
3671 /*-----------------------------------------------------------------*/
3672 static void genDivbits (operand *left,
3679 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3680 /* the result must be bit */
3681 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3682 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3686 pic16_emitcode("div","ab");
3687 pic16_emitcode("rrc","a");
3688 pic16_aopPut(AOP(result),"c",0);
3691 /*-----------------------------------------------------------------*/
3692 /* genDivOneByte : 8 bit division */
3693 /*-----------------------------------------------------------------*/
3694 static void genDivOneByte (operand *left,
3698 sym_link *opetype = operandType(result);
3703 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3704 size = AOP_SIZE(result) - 1;
3706 /* signed or unsigned */
3707 if (SPEC_USIGN(opetype)) {
3708 /* unsigned is easy */
3709 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3710 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3712 pic16_emitcode("div","ab");
3713 pic16_aopPut(AOP(result),"a",0);
3715 pic16_aopPut(AOP(result),zero,offset++);
3719 /* signed is a little bit more difficult */
3721 /* save the signs of the operands */
3722 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3724 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3725 pic16_emitcode("push","acc"); /* save it on the stack */
3727 /* now sign adjust for both left & right */
3728 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3730 lbl = newiTempLabel(NULL);
3731 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3732 pic16_emitcode("cpl","a");
3733 pic16_emitcode("inc","a");
3734 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3735 pic16_emitcode("mov","b,a");
3737 /* sign adjust left side */
3738 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3741 lbl = newiTempLabel(NULL);
3742 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3743 pic16_emitcode("cpl","a");
3744 pic16_emitcode("inc","a");
3745 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3747 /* now the division */
3748 pic16_emitcode("div","ab");
3749 /* we are interested in the lower order
3751 pic16_emitcode("mov","b,a");
3752 lbl = newiTempLabel(NULL);
3753 pic16_emitcode("pop","acc");
3754 /* if there was an over flow we don't
3755 adjust the sign of the result */
3756 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3757 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3759 pic16_emitcode("clr","a");
3760 pic16_emitcode("subb","a,b");
3761 pic16_emitcode("mov","b,a");
3762 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3764 /* now we are done */
3765 pic16_aopPut(AOP(result),"b",0);
3767 pic16_emitcode("mov","c,b.7");
3768 pic16_emitcode("subb","a,acc");
3771 pic16_aopPut(AOP(result),"a",offset++);
3775 /*-----------------------------------------------------------------*/
3776 /* genDiv - generates code for division */
3777 /*-----------------------------------------------------------------*/
3778 static void genDiv (iCode *ic)
3780 operand *left = IC_LEFT(ic);
3781 operand *right = IC_RIGHT(ic);
3782 operand *result= IC_RESULT(ic);
3784 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3785 /* assign the amsops */
3786 pic16_aopOp (left,ic,FALSE);
3787 pic16_aopOp (right,ic,FALSE);
3788 pic16_aopOp (result,ic,TRUE);
3790 /* special cases first */
3792 if (AOP_TYPE(left) == AOP_CRY &&
3793 AOP_TYPE(right)== AOP_CRY) {
3794 genDivbits(left,right,result);
3798 /* if both are of size == 1 */
3799 if (AOP_SIZE(left) == 1 &&
3800 AOP_SIZE(right) == 1 ) {
3801 genDivOneByte(left,right,result);
3805 /* should have been converted to function call */
3808 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3809 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3810 pic16_freeAsmop(result,NULL,ic,TRUE);
3813 /*-----------------------------------------------------------------*/
3814 /* genModbits :- modulus of bits */
3815 /*-----------------------------------------------------------------*/
3816 static void genModbits (operand *left,
3823 /* the result must be bit */
3824 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3825 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3829 pic16_emitcode("div","ab");
3830 pic16_emitcode("mov","a,b");
3831 pic16_emitcode("rrc","a");
3832 pic16_aopPut(AOP(result),"c",0);
3835 /*-----------------------------------------------------------------*/
3836 /* genModOneByte : 8 bit modulus */
3837 /*-----------------------------------------------------------------*/
3838 static void genModOneByte (operand *left,
3842 sym_link *opetype = operandType(result);
3846 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3847 /* signed or unsigned */
3848 if (SPEC_USIGN(opetype)) {
3849 /* unsigned is easy */
3850 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3851 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3853 pic16_emitcode("div","ab");
3854 pic16_aopPut(AOP(result),"b",0);
3858 /* signed is a little bit more difficult */
3860 /* save the signs of the operands */
3861 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3864 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3865 pic16_emitcode("push","acc"); /* save it on the stack */
3867 /* now sign adjust for both left & right */
3868 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3871 lbl = newiTempLabel(NULL);
3872 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3873 pic16_emitcode("cpl","a");
3874 pic16_emitcode("inc","a");
3875 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3876 pic16_emitcode("mov","b,a");
3878 /* sign adjust left side */
3879 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3882 lbl = newiTempLabel(NULL);
3883 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3884 pic16_emitcode("cpl","a");
3885 pic16_emitcode("inc","a");
3886 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3888 /* now the multiplication */
3889 pic16_emitcode("div","ab");
3890 /* we are interested in the lower order
3892 lbl = newiTempLabel(NULL);
3893 pic16_emitcode("pop","acc");
3894 /* if there was an over flow we don't
3895 adjust the sign of the result */
3896 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3897 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3899 pic16_emitcode("clr","a");
3900 pic16_emitcode("subb","a,b");
3901 pic16_emitcode("mov","b,a");
3902 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3904 /* now we are done */
3905 pic16_aopPut(AOP(result),"b",0);
3909 /*-----------------------------------------------------------------*/
3910 /* genMod - generates code for division */
3911 /*-----------------------------------------------------------------*/
3912 static void genMod (iCode *ic)
3914 operand *left = IC_LEFT(ic);
3915 operand *right = IC_RIGHT(ic);
3916 operand *result= IC_RESULT(ic);
3918 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3919 /* assign the amsops */
3920 pic16_aopOp (left,ic,FALSE);
3921 pic16_aopOp (right,ic,FALSE);
3922 pic16_aopOp (result,ic,TRUE);
3924 /* special cases first */
3926 if (AOP_TYPE(left) == AOP_CRY &&
3927 AOP_TYPE(right)== AOP_CRY) {
3928 genModbits(left,right,result);
3932 /* if both are of size == 1 */
3933 if (AOP_SIZE(left) == 1 &&
3934 AOP_SIZE(right) == 1 ) {
3935 genModOneByte(left,right,result);
3939 /* should have been converted to function call */
3943 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3944 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3945 pic16_freeAsmop(result,NULL,ic,TRUE);
3948 /*-----------------------------------------------------------------*/
3949 /* genIfxJump :- will create a jump depending on the ifx */
3950 /*-----------------------------------------------------------------*/
3952 note: May need to add parameter to indicate when a variable is in bit space.
3954 static void genIfxJump (iCode *ic, char *jval)
3957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3958 /* if true label then we jump if condition
3960 if ( IC_TRUE(ic) ) {
3962 if(strcmp(jval,"a") == 0)
3964 else if (strcmp(jval,"c") == 0)
3967 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3968 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3971 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3972 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3976 /* false label is present */
3977 if(strcmp(jval,"a") == 0)
3979 else if (strcmp(jval,"c") == 0)
3982 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3983 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3986 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3987 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3992 /* mark the icode as generated */
3996 /*-----------------------------------------------------------------*/
3998 /*-----------------------------------------------------------------*/
3999 static void genSkip(iCode *ifx,int status_bit)
4001 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4005 if ( IC_TRUE(ifx) ) {
4006 switch(status_bit) {
4021 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4022 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4026 switch(status_bit) {
4040 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4041 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4047 /*-----------------------------------------------------------------*/
4049 /*-----------------------------------------------------------------*/
4050 static void genSkipc(resolvedIfx *rifx)
4060 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4061 rifx->generated = 1;
4064 /*-----------------------------------------------------------------*/
4066 /*-----------------------------------------------------------------*/
4067 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4072 if( (rifx->condition ^ invert_condition) & 1)
4077 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4078 rifx->generated = 1;
4082 /*-----------------------------------------------------------------*/
4084 /*-----------------------------------------------------------------*/
4085 static void genSkipz(iCode *ifx, int condition)
4096 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4098 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4101 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4103 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4108 /*-----------------------------------------------------------------*/
4110 /*-----------------------------------------------------------------*/
4111 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4117 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4119 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4122 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4123 rifx->generated = 1;
4127 /*-----------------------------------------------------------------*/
4128 /* genChkZeroes :- greater or less than comparison */
4129 /* For each byte in a literal that is zero, inclusive or the */
4130 /* the corresponding byte in the operand with W */
4131 /* returns true if any of the bytes are zero */
4132 /*-----------------------------------------------------------------*/
4133 static int genChkZeroes(operand *op, int lit, int size)
4140 i = (lit >> (size*8)) & 0xff;
4144 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4146 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4155 /*-----------------------------------------------------------------*/
4156 /* genCmp :- greater or less than comparison */
4157 /*-----------------------------------------------------------------*/
4158 static void genCmp (operand *left,operand *right,
4159 operand *result, iCode *ifx, int sign)
4161 int size; //, offset = 0 ;
4162 unsigned long lit = 0L,i = 0;
4163 resolvedIfx rFalseIfx;
4164 // resolvedIfx rTrueIfx;
4166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4169 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4170 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4174 resolveIfx(&rFalseIfx,ifx);
4175 truelbl = newiTempLabel(NULL);
4176 size = max(AOP_SIZE(left),AOP_SIZE(right));
4178 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4182 /* if literal is on the right then swap with left */
4183 if ((AOP_TYPE(right) == AOP_LIT)) {
4184 operand *tmp = right ;
4185 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4186 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4189 lit = (lit - 1) & mask;
4192 rFalseIfx.condition ^= 1;
4195 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4196 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4200 //if(IC_TRUE(ifx) == NULL)
4201 /* if left & right are bit variables */
4202 if (AOP_TYPE(left) == AOP_CRY &&
4203 AOP_TYPE(right) == AOP_CRY ) {
4204 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4205 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4207 /* subtract right from left if at the
4208 end the carry flag is set then we know that
4209 left is greater than right */
4213 symbol *lbl = newiTempLabel(NULL);
4216 if(AOP_TYPE(right) == AOP_LIT) {
4218 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4220 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4227 genSkipCond(&rFalseIfx,left,size-1,7);
4229 /* no need to compare to 0...*/
4230 /* NOTE: this is a de-generate compare that most certainly
4231 * creates some dead code. */
4232 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4234 if(ifx) ifx->generated = 1;
4241 //i = (lit >> (size*8)) & 0xff;
4242 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4244 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4246 i = ((0-lit) & 0xff);
4249 /* lit is 0x7f, all signed chars are less than
4250 * this except for 0x7f itself */
4251 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4252 genSkipz2(&rFalseIfx,0);
4254 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4255 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4256 genSkipc(&rFalseIfx);
4261 genSkipz2(&rFalseIfx,1);
4263 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4264 genSkipc(&rFalseIfx);
4268 if(ifx) ifx->generated = 1;
4272 /* chars are out of the way. now do ints and longs */
4275 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4282 genSkipCond(&rFalseIfx,left,size,7);
4283 if(ifx) ifx->generated = 1;
4288 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4290 //rFalseIfx.condition ^= 1;
4291 //genSkipCond(&rFalseIfx,left,size,7);
4292 //rFalseIfx.condition ^= 1;
4294 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4295 if(rFalseIfx.condition)
4296 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4298 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4300 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4301 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4302 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4305 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4307 if(rFalseIfx.condition) {
4309 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4315 genSkipc(&rFalseIfx);
4316 pic16_emitpLabel(truelbl->key);
4317 if(ifx) ifx->generated = 1;
4324 if( (lit & 0xff) == 0) {
4325 /* lower byte is zero */
4326 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4327 i = ((lit >> 8) & 0xff) ^0x80;
4328 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4329 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4330 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4331 genSkipc(&rFalseIfx);
4334 if(ifx) ifx->generated = 1;
4339 /* Special cases for signed longs */
4340 if( (lit & 0xffffff) == 0) {
4341 /* lower byte is zero */
4342 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4343 i = ((lit >> 8*3) & 0xff) ^0x80;
4344 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4345 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4346 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4347 genSkipc(&rFalseIfx);
4350 if(ifx) ifx->generated = 1;
4358 if(lit & (0x80 << (size*8))) {
4359 /* lit is negative */
4360 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4362 //genSkipCond(&rFalseIfx,left,size,7);
4364 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4366 if(rFalseIfx.condition)
4367 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4369 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4373 /* lit is positive */
4374 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4375 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4376 if(rFalseIfx.condition)
4377 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4379 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4384 This works, but is only good for ints.
4385 It also requires a "known zero" register.
4386 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4387 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4388 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4389 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4390 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4391 genSkipc(&rFalseIfx);
4393 pic16_emitpLabel(truelbl->key);
4394 if(ifx) ifx->generated = 1;
4398 /* There are no more special cases, so perform a general compare */
4400 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4401 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4405 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4407 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4409 //rFalseIfx.condition ^= 1;
4410 genSkipc(&rFalseIfx);
4412 pic16_emitpLabel(truelbl->key);
4414 if(ifx) ifx->generated = 1;
4421 /* sign is out of the way. So now do an unsigned compare */
4422 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4425 /* General case - compare to an unsigned literal on the right.*/
4427 i = (lit >> (size*8)) & 0xff;
4428 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4429 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4431 i = (lit >> (size*8)) & 0xff;
4434 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4436 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4438 /* this byte of the lit is zero,
4439 *if it's not the last then OR in the variable */
4441 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4446 pic16_emitpLabel(lbl->key);
4447 //if(emitFinalCheck)
4448 genSkipc(&rFalseIfx);
4450 pic16_emitpLabel(truelbl->key);
4452 if(ifx) ifx->generated = 1;
4459 if(AOP_TYPE(left) == AOP_LIT) {
4460 //symbol *lbl = newiTempLabel(NULL);
4462 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4465 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4468 if((lit == 0) && (sign == 0)){
4471 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4473 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4475 genSkipz2(&rFalseIfx,0);
4476 if(ifx) ifx->generated = 1;
4483 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4484 /* degenerate compare can never be true */
4485 if(rFalseIfx.condition == 0)
4486 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4488 if(ifx) ifx->generated = 1;
4493 /* signed comparisons to a literal byte */
4495 int lp1 = (lit+1) & 0xff;
4497 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4500 rFalseIfx.condition ^= 1;
4501 genSkipCond(&rFalseIfx,right,0,7);
4504 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4505 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4506 genSkipz2(&rFalseIfx,1);
4509 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4510 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4511 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4512 rFalseIfx.condition ^= 1;
4513 genSkipc(&rFalseIfx);
4517 /* unsigned comparisons to a literal byte */
4519 switch(lit & 0xff ) {
4521 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4522 genSkipz2(&rFalseIfx,0);
4525 rFalseIfx.condition ^= 1;
4526 genSkipCond(&rFalseIfx,right,0,7);
4530 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4531 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4532 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4533 rFalseIfx.condition ^= 1;
4534 if (AOP_TYPE(result) == AOP_CRY)
4535 genSkipc(&rFalseIfx);
4537 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4538 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4544 if(ifx) ifx->generated = 1;
4550 /* Size is greater than 1 */
4558 /* this means lit = 0xffffffff, or -1 */
4561 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4562 rFalseIfx.condition ^= 1;
4563 genSkipCond(&rFalseIfx,right,size,7);
4564 if(ifx) ifx->generated = 1;
4571 if(rFalseIfx.condition) {
4572 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4573 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4576 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4578 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4582 if(rFalseIfx.condition) {
4583 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4584 pic16_emitpLabel(truelbl->key);
4586 rFalseIfx.condition ^= 1;
4587 genSkipCond(&rFalseIfx,right,s,7);
4590 if(ifx) ifx->generated = 1;
4594 if((size == 1) && (0 == (lp1&0xff))) {
4595 /* lower byte of signed word is zero */
4596 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4597 i = ((lp1 >> 8) & 0xff) ^0x80;
4598 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4599 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4600 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4601 rFalseIfx.condition ^= 1;
4602 genSkipc(&rFalseIfx);
4605 if(ifx) ifx->generated = 1;
4609 if(lit & (0x80 << (size*8))) {
4610 /* Lit is less than zero */
4611 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4612 //rFalseIfx.condition ^= 1;
4613 //genSkipCond(&rFalseIfx,left,size,7);
4614 //rFalseIfx.condition ^= 1;
4615 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4616 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4618 if(rFalseIfx.condition)
4619 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4621 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4625 /* Lit is greater than or equal to zero */
4626 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4627 //rFalseIfx.condition ^= 1;
4628 //genSkipCond(&rFalseIfx,right,size,7);
4629 //rFalseIfx.condition ^= 1;
4631 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4632 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4634 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4635 if(rFalseIfx.condition)
4636 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4638 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4643 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4644 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4648 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4650 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4652 rFalseIfx.condition ^= 1;
4653 //rFalseIfx.condition = 1;
4654 genSkipc(&rFalseIfx);
4656 pic16_emitpLabel(truelbl->key);
4658 if(ifx) ifx->generated = 1;
4663 /* compare word or long to an unsigned literal on the right.*/
4668 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4671 break; /* handled above */
4674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4676 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4677 genSkipz2(&rFalseIfx,0);
4681 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4683 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4686 if(rFalseIfx.condition)
4687 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4689 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4692 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4693 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4695 rFalseIfx.condition ^= 1;
4696 genSkipc(&rFalseIfx);
4699 pic16_emitpLabel(truelbl->key);
4701 if(ifx) ifx->generated = 1;
4707 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4708 i = (lit >> (size*8)) & 0xff;
4710 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4711 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4714 i = (lit >> (size*8)) & 0xff;
4717 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4719 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4721 /* this byte of the lit is zero,
4722 *if it's not the last then OR in the variable */
4724 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4729 pic16_emitpLabel(lbl->key);
4731 rFalseIfx.condition ^= 1;
4732 genSkipc(&rFalseIfx);
4736 pic16_emitpLabel(truelbl->key);
4737 if(ifx) ifx->generated = 1;
4741 /* Compare two variables */
4743 DEBUGpic16_emitcode(";sign","%d",sign);
4747 /* Sigh. thus sucks... */
4749 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4750 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4752 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4753 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4754 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4756 /* Signed char comparison */
4757 /* Special thanks to Nikolai Golovchenko for this snippet */
4758 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4759 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4760 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4761 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4762 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4763 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4766 genSkipc(&rFalseIfx);
4768 if(ifx) ifx->generated = 1;
4774 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4775 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4779 /* The rest of the bytes of a multi-byte compare */
4783 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4786 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4787 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4792 pic16_emitpLabel(lbl->key);
4794 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4795 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4796 (AOP_TYPE(result) == AOP_REG)) {
4797 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4798 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4800 genSkipc(&rFalseIfx);
4802 //genSkipc(&rFalseIfx);
4803 if(ifx) ifx->generated = 1;
4810 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4812 pic16_outBitC(result);
4814 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4815 /* if the result is used in the next
4816 ifx conditional branch then generate
4817 code a little differently */
4819 genIfxJump (ifx,"c");
4821 pic16_outBitC(result);
4822 /* leave the result in acc */
4827 /*-----------------------------------------------------------------*/
4828 /* genCmpGt :- greater than comparison */
4829 /*-----------------------------------------------------------------*/
4830 static void genCmpGt (iCode *ic, iCode *ifx)
4832 operand *left, *right, *result;
4833 sym_link *letype , *retype;
4836 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4838 right= IC_RIGHT(ic);
4839 result = IC_RESULT(ic);
4841 letype = getSpec(operandType(left));
4842 retype =getSpec(operandType(right));
4843 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4844 /* assign the amsops */
4845 pic16_aopOp (left,ic,FALSE);
4846 pic16_aopOp (right,ic,FALSE);
4847 pic16_aopOp (result,ic,TRUE);
4849 genCmp(right, left, result, ifx, sign);
4851 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4852 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4853 pic16_freeAsmop(result,NULL,ic,TRUE);
4856 /*-----------------------------------------------------------------*/
4857 /* genCmpLt - less than comparisons */
4858 /*-----------------------------------------------------------------*/
4859 static void genCmpLt (iCode *ic, iCode *ifx)
4861 operand *left, *right, *result;
4862 sym_link *letype , *retype;
4865 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4867 right= IC_RIGHT(ic);
4868 result = IC_RESULT(ic);
4870 letype = getSpec(operandType(left));
4871 retype =getSpec(operandType(right));
4872 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4874 /* assign the amsops */
4875 pic16_aopOp (left,ic,FALSE);
4876 pic16_aopOp (right,ic,FALSE);
4877 pic16_aopOp (result,ic,TRUE);
4879 genCmp(left, right, result, ifx, sign);
4881 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4882 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4883 pic16_freeAsmop(result,NULL,ic,TRUE);
4886 /*-----------------------------------------------------------------*/
4887 /* genc16bit2lit - compare a 16 bit value to a literal */
4888 /*-----------------------------------------------------------------*/
4889 static void genc16bit2lit(operand *op, int lit, int offset)
4893 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4894 if( (lit&0xff) == 0)
4899 switch( BYTEofLONG(lit,i)) {
4901 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4904 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4907 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4910 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4911 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4916 switch( BYTEofLONG(lit,i)) {
4918 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4922 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4926 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4929 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4931 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4937 /*-----------------------------------------------------------------*/
4938 /* gencjneshort - compare and jump if not equal */
4939 /*-----------------------------------------------------------------*/
4940 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4942 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4944 int res_offset = 0; /* the result may be a different size then left or right */
4945 int res_size = AOP_SIZE(result);
4949 unsigned long lit = 0L;
4950 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4951 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4953 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4954 resolveIfx(&rIfx,ifx);
4955 lbl = newiTempLabel(NULL);
4958 /* if the left side is a literal or
4959 if the right is in a pointer register and left
4961 if ((AOP_TYPE(left) == AOP_LIT) ||
4962 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4967 if(AOP_TYPE(right) == AOP_LIT)
4968 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4970 /* if the right side is a literal then anything goes */
4971 if (AOP_TYPE(right) == AOP_LIT &&
4972 AOP_TYPE(left) != AOP_DIR ) {
4975 genc16bit2lit(left, lit, 0);
4977 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4982 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4983 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4985 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4989 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4991 if(res_offset < res_size-1)
4999 /* if the right side is in a register or in direct space or
5000 if the left is a pointer register & right is not */
5001 else if (AOP_TYPE(right) == AOP_REG ||
5002 AOP_TYPE(right) == AOP_DIR ||
5003 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5004 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5005 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5006 int lbl_key = lbl->key;
5009 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5010 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5012 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5013 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5014 __FUNCTION__,__LINE__);
5018 /* switch(size) { */
5020 /* genc16bit2lit(left, lit, 0); */
5022 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5027 if((AOP_TYPE(left) == AOP_DIR) &&
5028 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5030 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5031 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5033 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5035 switch (lit & 0xff) {
5037 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5040 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5041 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5042 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5046 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5047 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5048 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5049 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5053 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5054 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5059 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5062 if(AOP_TYPE(result) == AOP_CRY) {
5063 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5068 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5070 /* fix me. probably need to check result size too */
5071 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5076 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5077 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5084 if(res_offset < res_size-1)
5089 } else if(AOP_TYPE(right) == AOP_REG &&
5090 AOP_TYPE(left) != AOP_DIR){
5093 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5094 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5095 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5100 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5102 if(res_offset < res_size-1)
5107 /* right is a pointer reg need both a & b */
5109 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5111 pic16_emitcode("mov","b,%s",l);
5112 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5113 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5118 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5120 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5122 pic16_emitpLabel(lbl->key);
5124 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5131 /*-----------------------------------------------------------------*/
5132 /* gencjne - compare and jump if not equal */
5133 /*-----------------------------------------------------------------*/
5134 static void gencjne(operand *left, operand *right, iCode *ifx)
5136 symbol *tlbl = newiTempLabel(NULL);
5138 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5139 gencjneshort(left, right, lbl);
5141 pic16_emitcode("mov","a,%s",one);
5142 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5143 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5144 pic16_emitcode("clr","a");
5145 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5147 pic16_emitpLabel(lbl->key);
5148 pic16_emitpLabel(tlbl->key);
5153 /*-----------------------------------------------------------------*/
5154 /* genCmpEq - generates code for equal to */
5155 /*-----------------------------------------------------------------*/
5156 static void genCmpEq (iCode *ic, iCode *ifx)
5158 operand *left, *right, *result;
5159 unsigned long lit = 0L;
5161 symbol *falselbl = newiTempLabel(NULL);
5164 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5167 DEBUGpic16_emitcode ("; ifx is non-null","");
5169 DEBUGpic16_emitcode ("; ifx is null","");
5171 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5172 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5173 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5175 size = max(AOP_SIZE(left),AOP_SIZE(right));
5177 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5179 /* if literal, literal on the right or
5180 if the right is in a pointer register and left
5182 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5183 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5184 operand *tmp = right ;
5190 if(ifx && !AOP_SIZE(result)){
5192 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5193 /* if they are both bit variables */
5194 if (AOP_TYPE(left) == AOP_CRY &&
5195 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5196 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5197 if(AOP_TYPE(right) == AOP_LIT){
5198 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5200 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5201 pic16_emitcode("cpl","c");
5202 } else if(lit == 1L) {
5203 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5205 pic16_emitcode("clr","c");
5207 /* AOP_TYPE(right) == AOP_CRY */
5209 symbol *lbl = newiTempLabel(NULL);
5210 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5212 pic16_emitcode("cpl","c");
5213 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5215 /* if true label then we jump if condition
5217 tlbl = newiTempLabel(NULL);
5218 if ( IC_TRUE(ifx) ) {
5219 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5220 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5222 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5223 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5225 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5228 /* left and right are both bit variables, result is carry */
5231 resolveIfx(&rIfx,ifx);
5233 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5234 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5235 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5236 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5241 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5243 /* They're not both bit variables. Is the right a literal? */
5244 if(AOP_TYPE(right) == AOP_LIT) {
5245 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5250 switch(lit & 0xff) {
5252 if ( IC_TRUE(ifx) ) {
5253 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5255 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5257 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5258 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5262 if ( IC_TRUE(ifx) ) {
5263 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5265 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5267 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5268 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5272 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5274 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5279 /* end of size == 1 */
5283 genc16bit2lit(left,lit,offset);
5286 /* end of size == 2 */
5291 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5292 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5293 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5294 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5297 /* search for patterns that can be optimized */
5299 genc16bit2lit(left,lit,0);
5303 emitSKPZ; // if hi word unequal
5305 emitSKPNZ; // if hi word equal
5307 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5308 genc16bit2lit(left,lit,2);
5311 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5312 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5316 pic16_emitpLabel(falselbl->key);
5325 } else if(AOP_TYPE(right) == AOP_CRY ) {
5326 /* we know the left is not a bit, but that the right is */
5327 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5328 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5329 pic16_popGet(AOP(right),offset));
5330 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5332 /* if the two are equal, then W will be 0 and the Z bit is set
5333 * we could test Z now, or go ahead and check the high order bytes if
5334 * the variable we're comparing is larger than a byte. */
5337 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5339 if ( IC_TRUE(ifx) ) {
5341 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5342 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5345 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5346 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5350 /* They're both variables that are larger than bits */
5353 tlbl = newiTempLabel(NULL);
5356 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5357 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5359 if ( IC_TRUE(ifx) ) {
5363 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5365 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5366 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5370 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5373 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5374 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5379 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5381 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5382 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5386 if(s>1 && IC_TRUE(ifx)) {
5387 pic16_emitpLabel(tlbl->key);
5388 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5392 /* mark the icode as generated */
5397 /* if they are both bit variables */
5398 if (AOP_TYPE(left) == AOP_CRY &&
5399 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5400 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5401 if(AOP_TYPE(right) == AOP_LIT){
5402 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5404 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5405 pic16_emitcode("cpl","c");
5406 } else if(lit == 1L) {
5407 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5409 pic16_emitcode("clr","c");
5411 /* AOP_TYPE(right) == AOP_CRY */
5413 symbol *lbl = newiTempLabel(NULL);
5414 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5415 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5416 pic16_emitcode("cpl","c");
5417 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5420 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5421 pic16_outBitC(result);
5425 genIfxJump (ifx,"c");
5428 /* if the result is used in an arithmetic operation
5429 then put the result in place */
5430 pic16_outBitC(result);
5433 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5434 gencjne(left,right,result,ifx);
5437 gencjne(left,right,newiTempLabel(NULL));
5439 if(IC_TRUE(ifx)->key)
5440 gencjne(left,right,IC_TRUE(ifx)->key);
5442 gencjne(left,right,IC_FALSE(ifx)->key);
5446 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5447 pic16_aopPut(AOP(result),"a",0);
5452 genIfxJump (ifx,"a");
5456 /* if the result is used in an arithmetic operation
5457 then put the result in place */
5459 if (AOP_TYPE(result) != AOP_CRY)
5460 pic16_outAcc(result);
5462 /* leave the result in acc */
5466 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5467 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5468 pic16_freeAsmop(result,NULL,ic,TRUE);
5471 /*-----------------------------------------------------------------*/
5472 /* ifxForOp - returns the icode containing the ifx for operand */
5473 /*-----------------------------------------------------------------*/
5474 static iCode *ifxForOp ( operand *op, iCode *ic )
5476 /* if true symbol then needs to be assigned */
5477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5478 if (IS_TRUE_SYMOP(op))
5481 /* if this has register type condition and
5482 the next instruction is ifx with the same operand
5483 and live to of the operand is upto the ifx only then */
5485 ic->next->op == IFX &&
5486 IC_COND(ic->next)->key == op->key &&
5487 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5491 ic->next->op == IFX &&
5492 IC_COND(ic->next)->key == op->key) {
5493 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5497 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5499 ic->next->op == IFX)
5500 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5503 ic->next->op == IFX &&
5504 IC_COND(ic->next)->key == op->key) {
5505 DEBUGpic16_emitcode ("; "," key is okay");
5506 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5507 OP_SYMBOL(op)->liveTo,
5514 /*-----------------------------------------------------------------*/
5515 /* genAndOp - for && operation */
5516 /*-----------------------------------------------------------------*/
5517 static void genAndOp (iCode *ic)
5519 operand *left,*right, *result;
5522 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5523 /* note here that && operations that are in an
5524 if statement are taken away by backPatchLabels
5525 only those used in arthmetic operations remain */
5526 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5527 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5528 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5530 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5532 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5533 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5534 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5536 /* if both are bit variables */
5537 /* if (AOP_TYPE(left) == AOP_CRY && */
5538 /* AOP_TYPE(right) == AOP_CRY ) { */
5539 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5540 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5541 /* pic16_outBitC(result); */
5543 /* tlbl = newiTempLabel(NULL); */
5544 /* pic16_toBoolean(left); */
5545 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5546 /* pic16_toBoolean(right); */
5547 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5548 /* pic16_outBitAcc(result); */
5551 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5552 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5553 pic16_freeAsmop(result,NULL,ic,TRUE);
5557 /*-----------------------------------------------------------------*/
5558 /* genOrOp - for || operation */
5559 /*-----------------------------------------------------------------*/
5562 modified this code, but it doesn't appear to ever get called
5565 static void genOrOp (iCode *ic)
5567 operand *left,*right, *result;
5570 /* note here that || operations that are in an
5571 if statement are taken away by backPatchLabels
5572 only those used in arthmetic operations remain */
5573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5574 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5575 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5576 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5578 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5580 /* if both are bit variables */
5581 if (AOP_TYPE(left) == AOP_CRY &&
5582 AOP_TYPE(right) == AOP_CRY ) {
5583 pic16_emitcode("clrc","");
5584 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5585 AOP(left)->aopu.aop_dir,
5586 AOP(left)->aopu.aop_dir);
5587 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5588 AOP(right)->aopu.aop_dir,
5589 AOP(right)->aopu.aop_dir);
5590 pic16_emitcode("setc","");
5593 tlbl = newiTempLabel(NULL);
5594 pic16_toBoolean(left);
5596 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5597 pic16_toBoolean(right);
5598 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5600 pic16_outBitAcc(result);
5603 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5604 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5605 pic16_freeAsmop(result,NULL,ic,TRUE);
5608 /*-----------------------------------------------------------------*/
5609 /* isLiteralBit - test if lit == 2^n */
5610 /*-----------------------------------------------------------------*/
5611 static int isLiteralBit(unsigned long lit)
5613 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5614 0x100L,0x200L,0x400L,0x800L,
5615 0x1000L,0x2000L,0x4000L,0x8000L,
5616 0x10000L,0x20000L,0x40000L,0x80000L,
5617 0x100000L,0x200000L,0x400000L,0x800000L,
5618 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5619 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5622 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5623 for(idx = 0; idx < 32; idx++)
5629 /*-----------------------------------------------------------------*/
5630 /* continueIfTrue - */
5631 /*-----------------------------------------------------------------*/
5632 static void continueIfTrue (iCode *ic)
5634 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5636 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5640 /*-----------------------------------------------------------------*/
5642 /*-----------------------------------------------------------------*/
5643 static void jumpIfTrue (iCode *ic)
5645 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5647 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5651 /*-----------------------------------------------------------------*/
5652 /* jmpTrueOrFalse - */
5653 /*-----------------------------------------------------------------*/
5654 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5656 // ugly but optimized by peephole
5657 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5659 symbol *nlbl = newiTempLabel(NULL);
5660 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5661 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5662 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5663 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5666 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5667 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5672 /*-----------------------------------------------------------------*/
5673 /* genAnd - code for and */
5674 /*-----------------------------------------------------------------*/
5675 static void genAnd (iCode *ic, iCode *ifx)
5677 operand *left, *right, *result;
5679 unsigned long lit = 0L;
5684 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5685 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5686 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5687 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5689 resolveIfx(&rIfx,ifx);
5691 /* if left is a literal & right is not then exchange them */
5692 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5693 AOP_NEEDSACC(left)) {
5694 operand *tmp = right ;
5699 /* if result = right then exchange them */
5700 if(pic16_sameRegs(AOP(result),AOP(right))){
5701 operand *tmp = right ;
5706 /* if right is bit then exchange them */
5707 if (AOP_TYPE(right) == AOP_CRY &&
5708 AOP_TYPE(left) != AOP_CRY){
5709 operand *tmp = right ;
5713 if(AOP_TYPE(right) == AOP_LIT)
5714 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5716 size = AOP_SIZE(result);
5718 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5721 // result = bit & yy;
5722 if (AOP_TYPE(left) == AOP_CRY){
5723 // c = bit & literal;
5724 if(AOP_TYPE(right) == AOP_LIT){
5726 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5729 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5732 if(size && (AOP_TYPE(result) == AOP_CRY)){
5733 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5736 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5740 pic16_emitcode("clr","c");
5743 if (AOP_TYPE(right) == AOP_CRY){
5745 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5746 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5749 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5751 pic16_emitcode("rrc","a");
5752 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5758 pic16_outBitC(result);
5760 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5761 genIfxJump(ifx, "c");
5765 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5766 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5767 if((AOP_TYPE(right) == AOP_LIT) &&
5768 (AOP_TYPE(result) == AOP_CRY) &&
5769 (AOP_TYPE(left) != AOP_CRY)){
5770 int posbit = isLiteralBit(lit);
5774 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5777 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5783 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5784 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5786 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5787 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5790 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5791 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5792 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5799 symbol *tlbl = newiTempLabel(NULL);
5800 int sizel = AOP_SIZE(left);
5802 pic16_emitcode("setb","c");
5804 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5805 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5807 if((posbit = isLiteralBit(bytelit)) != 0)
5808 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5810 if(bytelit != 0x0FFL)
5811 pic16_emitcode("anl","a,%s",
5812 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5813 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5818 // bit = left & literal
5820 pic16_emitcode("clr","c");
5821 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5823 // if(left & literal)
5826 jmpTrueOrFalse(ifx, tlbl);
5830 pic16_outBitC(result);
5834 /* if left is same as result */
5835 if(pic16_sameRegs(AOP(result),AOP(left))){
5837 for(;size--; offset++,lit>>=8) {
5838 if(AOP_TYPE(right) == AOP_LIT){
5839 switch(lit & 0xff) {
5841 /* and'ing with 0 has clears the result */
5842 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5843 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5846 /* and'ing with 0xff is a nop when the result and left are the same */
5851 int p = my_powof2( (~lit) & 0xff );
5853 /* only one bit is set in the literal, so use a bcf instruction */
5854 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5855 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5858 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5859 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5860 if(know_W != (lit&0xff))
5861 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5863 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5868 if (AOP_TYPE(left) == AOP_ACC) {
5869 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5871 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5872 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5879 // left & result in different registers
5880 if(AOP_TYPE(result) == AOP_CRY){
5882 // if(size), result in bit
5883 // if(!size && ifx), conditional oper: if(left & right)
5884 symbol *tlbl = newiTempLabel(NULL);
5885 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5887 pic16_emitcode("setb","c");
5889 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5890 pic16_emitcode("anl","a,%s",
5891 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5892 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5897 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5898 pic16_outBitC(result);
5900 jmpTrueOrFalse(ifx, tlbl);
5902 for(;(size--);offset++) {
5904 // result = left & right
5905 if(AOP_TYPE(right) == AOP_LIT){
5906 int t = (lit >> (offset*8)) & 0x0FFL;
5909 pic16_emitcode("clrf","%s",
5910 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5911 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5914 pic16_emitcode("movf","%s,w",
5915 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5916 pic16_emitcode("movwf","%s",
5917 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5918 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5919 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5922 pic16_emitcode("movlw","0x%x",t);
5923 pic16_emitcode("andwf","%s,w",
5924 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5925 pic16_emitcode("movwf","%s",
5926 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5928 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5929 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5930 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5935 if (AOP_TYPE(left) == AOP_ACC) {
5936 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5937 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5939 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5940 pic16_emitcode("andwf","%s,w",
5941 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5942 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5943 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5945 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5946 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5952 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5953 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5954 pic16_freeAsmop(result,NULL,ic,TRUE);
5957 /*-----------------------------------------------------------------*/
5958 /* genOr - code for or */
5959 /*-----------------------------------------------------------------*/
5960 static void genOr (iCode *ic, iCode *ifx)
5962 operand *left, *right, *result;
5964 unsigned long lit = 0L;
5966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5968 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5969 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5970 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5972 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5974 /* if left is a literal & right is not then exchange them */
5975 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5976 AOP_NEEDSACC(left)) {
5977 operand *tmp = right ;
5982 /* if result = right then exchange them */
5983 if(pic16_sameRegs(AOP(result),AOP(right))){
5984 operand *tmp = right ;
5989 /* if right is bit then exchange them */
5990 if (AOP_TYPE(right) == AOP_CRY &&
5991 AOP_TYPE(left) != AOP_CRY){
5992 operand *tmp = right ;
5997 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5999 if(AOP_TYPE(right) == AOP_LIT)
6000 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6002 size = AOP_SIZE(result);
6006 if (AOP_TYPE(left) == AOP_CRY){
6007 if(AOP_TYPE(right) == AOP_LIT){
6008 // c = bit & literal;
6010 // lit != 0 => result = 1
6011 if(AOP_TYPE(result) == AOP_CRY){
6013 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6014 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6015 // AOP(result)->aopu.aop_dir,
6016 // AOP(result)->aopu.aop_dir);
6018 continueIfTrue(ifx);
6022 // lit == 0 => result = left
6023 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6025 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6028 if (AOP_TYPE(right) == AOP_CRY){
6029 if(pic16_sameRegs(AOP(result),AOP(left))){
6031 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6032 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6033 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6035 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6036 AOP(result)->aopu.aop_dir,
6037 AOP(result)->aopu.aop_dir);
6038 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6039 AOP(right)->aopu.aop_dir,
6040 AOP(right)->aopu.aop_dir);
6041 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6042 AOP(result)->aopu.aop_dir,
6043 AOP(result)->aopu.aop_dir);
6045 if( AOP_TYPE(result) == AOP_ACC) {
6046 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6047 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6048 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6049 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6053 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6054 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6055 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6056 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6058 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6059 AOP(result)->aopu.aop_dir,
6060 AOP(result)->aopu.aop_dir);
6061 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6062 AOP(right)->aopu.aop_dir,
6063 AOP(right)->aopu.aop_dir);
6064 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6065 AOP(left)->aopu.aop_dir,
6066 AOP(left)->aopu.aop_dir);
6067 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6068 AOP(result)->aopu.aop_dir,
6069 AOP(result)->aopu.aop_dir);
6074 symbol *tlbl = newiTempLabel(NULL);
6075 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6078 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6079 if( AOP_TYPE(right) == AOP_ACC) {
6080 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6082 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6083 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6088 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6089 pic16_emitcode(";XXX setb","c");
6090 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6091 AOP(left)->aopu.aop_dir,tlbl->key+100);
6092 pic16_toBoolean(right);
6093 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6094 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6095 jmpTrueOrFalse(ifx, tlbl);
6099 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6106 pic16_outBitC(result);
6108 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6109 genIfxJump(ifx, "c");
6113 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6114 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6115 if((AOP_TYPE(right) == AOP_LIT) &&
6116 (AOP_TYPE(result) == AOP_CRY) &&
6117 (AOP_TYPE(left) != AOP_CRY)){
6119 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6122 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6124 continueIfTrue(ifx);
6127 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6128 // lit = 0, result = boolean(left)
6130 pic16_emitcode(";XXX setb","c");
6131 pic16_toBoolean(right);
6133 symbol *tlbl = newiTempLabel(NULL);
6134 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6136 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6138 genIfxJump (ifx,"a");
6142 pic16_outBitC(result);
6146 /* if left is same as result */
6147 if(pic16_sameRegs(AOP(result),AOP(left))){
6149 for(;size--; offset++,lit>>=8) {
6150 if(AOP_TYPE(right) == AOP_LIT){
6151 if((lit & 0xff) == 0)
6152 /* or'ing with 0 has no effect */
6155 int p = my_powof2(lit & 0xff);
6157 /* only one bit is set in the literal, so use a bsf instruction */
6158 pic16_emitpcode(POC_BSF,
6159 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6161 if(know_W != (lit & 0xff))
6162 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6163 know_W = lit & 0xff;
6164 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6169 if (AOP_TYPE(left) == AOP_ACC) {
6170 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6171 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6173 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6174 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6176 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6177 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6183 // left & result in different registers
6184 if(AOP_TYPE(result) == AOP_CRY){
6186 // if(size), result in bit
6187 // if(!size && ifx), conditional oper: if(left | right)
6188 symbol *tlbl = newiTempLabel(NULL);
6189 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6190 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6194 pic16_emitcode(";XXX setb","c");
6196 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6197 pic16_emitcode(";XXX orl","a,%s",
6198 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6199 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6204 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6205 pic16_outBitC(result);
6207 jmpTrueOrFalse(ifx, tlbl);
6208 } else for(;(size--);offset++){
6210 // result = left & right
6211 if(AOP_TYPE(right) == AOP_LIT){
6212 int t = (lit >> (offset*8)) & 0x0FFL;
6215 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6216 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6218 pic16_emitcode("movf","%s,w",
6219 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6220 pic16_emitcode("movwf","%s",
6221 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6224 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6225 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6226 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6228 pic16_emitcode("movlw","0x%x",t);
6229 pic16_emitcode("iorwf","%s,w",
6230 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6231 pic16_emitcode("movwf","%s",
6232 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6238 // faster than result <- left, anl result,right
6239 // and better if result is SFR
6240 if (AOP_TYPE(left) == AOP_ACC) {
6241 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6242 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6244 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6245 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6247 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6248 pic16_emitcode("iorwf","%s,w",
6249 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6251 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6252 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6257 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6258 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6259 pic16_freeAsmop(result,NULL,ic,TRUE);
6262 /*-----------------------------------------------------------------*/
6263 /* genXor - code for xclusive or */
6264 /*-----------------------------------------------------------------*/
6265 static void genXor (iCode *ic, iCode *ifx)
6267 operand *left, *right, *result;
6269 unsigned long lit = 0L;
6271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6273 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6274 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6275 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6277 /* if left is a literal & right is not ||
6278 if left needs acc & right does not */
6279 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6280 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6281 operand *tmp = right ;
6286 /* if result = right then exchange them */
6287 if(pic16_sameRegs(AOP(result),AOP(right))){
6288 operand *tmp = right ;
6293 /* if right is bit then exchange them */
6294 if (AOP_TYPE(right) == AOP_CRY &&
6295 AOP_TYPE(left) != AOP_CRY){
6296 operand *tmp = right ;
6300 if(AOP_TYPE(right) == AOP_LIT)
6301 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6303 size = AOP_SIZE(result);
6307 if (AOP_TYPE(left) == AOP_CRY){
6308 if(AOP_TYPE(right) == AOP_LIT){
6309 // c = bit & literal;
6311 // lit>>1 != 0 => result = 1
6312 if(AOP_TYPE(result) == AOP_CRY){
6314 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6315 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6317 continueIfTrue(ifx);
6320 pic16_emitcode("setb","c");
6324 // lit == 0, result = left
6325 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6327 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6329 // lit == 1, result = not(left)
6330 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6331 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6332 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6333 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6336 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6337 pic16_emitcode("cpl","c");
6344 symbol *tlbl = newiTempLabel(NULL);
6345 if (AOP_TYPE(right) == AOP_CRY){
6347 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6350 int sizer = AOP_SIZE(right);
6352 // if val>>1 != 0, result = 1
6353 pic16_emitcode("setb","c");
6355 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6357 // test the msb of the lsb
6358 pic16_emitcode("anl","a,#0xfe");
6359 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6363 pic16_emitcode("rrc","a");
6365 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6366 pic16_emitcode("cpl","c");
6367 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6372 pic16_outBitC(result);
6374 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6375 genIfxJump(ifx, "c");
6379 if(pic16_sameRegs(AOP(result),AOP(left))){
6380 /* if left is same as result */
6381 for(;size--; offset++) {
6382 if(AOP_TYPE(right) == AOP_LIT){
6383 int t = (lit >> (offset*8)) & 0x0FFL;
6387 if (IS_AOP_PREG(left)) {
6388 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6389 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6390 pic16_aopPut(AOP(result),"a",offset);
6392 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6393 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6394 pic16_emitcode("xrl","%s,%s",
6395 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6396 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6399 if (AOP_TYPE(left) == AOP_ACC)
6400 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6402 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6403 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6405 if (IS_AOP_PREG(left)) {
6406 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6407 pic16_aopPut(AOP(result),"a",offset);
6409 pic16_emitcode("xrl","%s,a",
6410 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6416 // left & result in different registers
6417 if(AOP_TYPE(result) == AOP_CRY){
6419 // if(size), result in bit
6420 // if(!size && ifx), conditional oper: if(left ^ right)
6421 symbol *tlbl = newiTempLabel(NULL);
6422 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6424 pic16_emitcode("setb","c");
6426 if((AOP_TYPE(right) == AOP_LIT) &&
6427 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6428 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6430 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6431 pic16_emitcode("xrl","a,%s",
6432 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6434 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6439 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6440 pic16_outBitC(result);
6442 jmpTrueOrFalse(ifx, tlbl);
6443 } else for(;(size--);offset++){
6445 // result = left & right
6446 if(AOP_TYPE(right) == AOP_LIT){
6447 int t = (lit >> (offset*8)) & 0x0FFL;
6450 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6451 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6452 pic16_emitcode("movf","%s,w",
6453 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6454 pic16_emitcode("movwf","%s",
6455 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6458 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6459 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6460 pic16_emitcode("comf","%s,w",
6461 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6462 pic16_emitcode("movwf","%s",
6463 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6466 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6467 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6468 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6469 pic16_emitcode("movlw","0x%x",t);
6470 pic16_emitcode("xorwf","%s,w",
6471 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6472 pic16_emitcode("movwf","%s",
6473 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6479 // faster than result <- left, anl result,right
6480 // and better if result is SFR
6481 if (AOP_TYPE(left) == AOP_ACC) {
6482 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6483 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6485 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6486 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6487 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6488 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6490 if ( AOP_TYPE(result) != AOP_ACC){
6491 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6492 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6498 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6499 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6500 pic16_freeAsmop(result,NULL,ic,TRUE);
6503 /*-----------------------------------------------------------------*/
6504 /* genInline - write the inline code out */
6505 /*-----------------------------------------------------------------*/
6506 static void genInline (iCode *ic)
6508 char *buffer, *bp, *bp1;
6510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6512 _G.inLine += (!options.asmpeep);
6514 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6515 strcpy(buffer,IC_INLINE(ic));
6517 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
6519 /* emit each line as a code */
6526 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6528 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6536 pic16_emitcode(bp1,"");
6543 if ((bp1 != bp) && *bp1)
6545 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6547 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6553 _G.inLine -= (!options.asmpeep);
6556 /*-----------------------------------------------------------------*/
6557 /* genRRC - rotate right with carry */
6558 /*-----------------------------------------------------------------*/
6559 static void genRRC (iCode *ic)
6561 operand *left , *result ;
6562 int size, offset = 0, same;
6564 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6566 /* rotate right with carry */
6568 result=IC_RESULT(ic);
6569 pic16_aopOp (left,ic,FALSE);
6570 pic16_aopOp (result,ic,FALSE);
6572 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6574 same = pic16_sameRegs(AOP(result),AOP(left));
6576 size = AOP_SIZE(result);
6578 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6580 /* get the lsb and put it into the carry */
6581 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6588 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6590 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6591 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6597 pic16_freeAsmop(left,NULL,ic,TRUE);
6598 pic16_freeAsmop(result,NULL,ic,TRUE);
6601 /*-----------------------------------------------------------------*/
6602 /* genRLC - generate code for rotate left with carry */
6603 /*-----------------------------------------------------------------*/
6604 static void genRLC (iCode *ic)
6606 operand *left , *result ;
6607 int size, offset = 0;
6610 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6611 /* rotate right with carry */
6613 result=IC_RESULT(ic);
6614 pic16_aopOp (left,ic,FALSE);
6615 pic16_aopOp (result,ic,FALSE);
6617 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6619 same = pic16_sameRegs(AOP(result),AOP(left));
6621 /* move it to the result */
6622 size = AOP_SIZE(result);
6624 /* get the msb and put it into the carry */
6625 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6632 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6634 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6635 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6642 pic16_freeAsmop(left,NULL,ic,TRUE);
6643 pic16_freeAsmop(result,NULL,ic,TRUE);
6647 /* gpasm can get the highest order bit with HIGH/UPPER
6648 * so the following probably is not needed -- VR */
6650 /*-----------------------------------------------------------------*/
6651 /* genGetHbit - generates code get highest order bit */
6652 /*-----------------------------------------------------------------*/
6653 static void genGetHbit (iCode *ic)
6655 operand *left, *result;
6657 result=IC_RESULT(ic);
6658 pic16_aopOp (left,ic,FALSE);
6659 pic16_aopOp (result,ic,FALSE);
6661 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6662 /* get the highest order byte into a */
6663 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6664 if(AOP_TYPE(result) == AOP_CRY){
6665 pic16_emitcode("rlc","a");
6666 pic16_outBitC(result);
6669 pic16_emitcode("rl","a");
6670 pic16_emitcode("anl","a,#0x01");
6671 pic16_outAcc(result);
6675 pic16_freeAsmop(left,NULL,ic,TRUE);
6676 pic16_freeAsmop(result,NULL,ic,TRUE);
6680 /*-----------------------------------------------------------------*/
6681 /* AccRol - rotate left accumulator by known count */
6682 /*-----------------------------------------------------------------*/
6683 static void AccRol (int shCount)
6685 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6686 shCount &= 0x0007; // shCount : 0..7
6691 pic16_emitcode("rl","a");
6694 pic16_emitcode("rl","a");
6695 pic16_emitcode("rl","a");
6698 pic16_emitcode("swap","a");
6699 pic16_emitcode("rr","a");
6702 pic16_emitcode("swap","a");
6705 pic16_emitcode("swap","a");
6706 pic16_emitcode("rl","a");
6709 pic16_emitcode("rr","a");
6710 pic16_emitcode("rr","a");
6713 pic16_emitcode("rr","a");
6719 /*-----------------------------------------------------------------*/
6720 /* AccLsh - left shift accumulator by known count */
6721 /*-----------------------------------------------------------------*/
6722 static void AccLsh (int shCount)
6724 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6730 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6733 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6734 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6737 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6738 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6741 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6744 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6745 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6748 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6749 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6752 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6756 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6759 /*-----------------------------------------------------------------*/
6760 /* AccRsh - right shift accumulator by known count */
6761 /*-----------------------------------------------------------------*/
6762 static void AccRsh (int shCount, int andmask)
6764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6769 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6770 // andmask = 0; /* no need */
6773 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6774 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6775 // andmask = 0; /* no need */
6778 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6779 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6782 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6785 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6786 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6789 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6790 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6793 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6798 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6800 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
6804 /*-----------------------------------------------------------------*/
6805 /* AccSRsh - signed right shift accumulator by known count */
6806 /*-----------------------------------------------------------------*/
6807 static void AccSRsh (int shCount)
6810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6813 pic16_emitcode("mov","c,acc.7");
6814 pic16_emitcode("rrc","a");
6815 } else if(shCount == 2){
6816 pic16_emitcode("mov","c,acc.7");
6817 pic16_emitcode("rrc","a");
6818 pic16_emitcode("mov","c,acc.7");
6819 pic16_emitcode("rrc","a");
6821 tlbl = newiTempLabel(NULL);
6822 /* rotate right accumulator */
6823 AccRol(8 - shCount);
6824 /* and kill the higher order bits */
6825 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6826 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6827 pic16_emitcode("orl","a,#0x%02x",
6828 (unsigned char)~SRMask[shCount]);
6829 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6834 /*-----------------------------------------------------------------*/
6835 /* shiftR1Left2Result - shift right one byte from left to result */
6836 /*-----------------------------------------------------------------*/
6837 static void shiftR1Left2ResultSigned (operand *left, int offl,
6838 operand *result, int offr,
6843 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6845 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6849 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6851 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6853 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6854 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6860 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6862 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6864 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6865 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6867 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6868 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6874 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6876 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6877 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6880 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6881 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6882 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6884 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6885 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6887 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6891 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6892 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6893 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6894 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6895 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6899 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6902 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6904 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6905 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6906 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6907 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6908 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6913 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6914 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6915 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6916 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6917 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6918 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6920 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6921 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6922 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6923 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6924 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6930 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6931 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6932 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6933 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6935 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6936 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6937 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6945 /*-----------------------------------------------------------------*/
6946 /* shiftR1Left2Result - shift right one byte from left to result */
6947 /*-----------------------------------------------------------------*/
6948 static void shiftR1Left2Result (operand *left, int offl,
6949 operand *result, int offr,
6950 int shCount, int sign)
6954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6956 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6958 /* Copy the msb into the carry if signed. */
6960 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6970 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6972 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6973 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6979 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6981 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6982 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6985 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6990 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6992 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6993 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6996 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6997 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6998 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6999 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7003 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7004 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7005 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7009 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7010 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7011 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7013 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7018 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7019 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7020 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7021 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7022 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7027 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7028 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7038 /*-----------------------------------------------------------------*/
7039 /* shiftL1Left2Result - shift left one byte from left to result */
7040 /*-----------------------------------------------------------------*/
7041 static void shiftL1Left2Result (operand *left, int offl,
7042 operand *result, int offr, int shCount)
7047 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7049 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7050 DEBUGpic16_emitcode ("; ***","same = %d",same);
7051 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7053 /* shift left accumulator */
7054 //AccLsh(shCount); // don't comment out just yet...
7055 // pic16_aopPut(AOP(result),"a",offr);
7059 /* Shift left 1 bit position */
7060 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7062 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7064 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7065 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7069 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7070 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7071 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7072 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7075 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7076 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7077 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7078 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7079 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7082 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7083 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7084 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7087 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7088 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7089 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7090 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7093 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7094 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7095 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7096 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7097 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7100 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7101 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7102 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7106 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7111 /*-----------------------------------------------------------------*/
7112 /* movLeft2Result - move byte from left to result */
7113 /*-----------------------------------------------------------------*/
7114 static void movLeft2Result (operand *left, int offl,
7115 operand *result, int offr)
7118 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7119 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7120 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7122 if (*l == '@' && (IS_AOP_PREG(result))) {
7123 pic16_emitcode("mov","a,%s",l);
7124 pic16_aopPut(AOP(result),"a",offr);
7126 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7127 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7132 /*-----------------------------------------------------------------*/
7133 /* shiftL2Left2Result - shift left two bytes from left to result */
7134 /*-----------------------------------------------------------------*/
7135 static void shiftL2Left2Result (operand *left, int offl,
7136 operand *result, int offr, int shCount)
7138 int same = pic16_sameRegs(AOP(result), AOP(left));
7141 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7143 if (same && (offl != offr)) { // shift bytes
7146 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7147 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7149 } else { // just treat as different later on
7162 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7163 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7164 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7168 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7169 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7175 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7176 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7177 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7178 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7179 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7180 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7181 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7183 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7184 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7188 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7189 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7190 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7191 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7192 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7193 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7194 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7195 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7196 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7197 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7200 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7201 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7202 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7203 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7204 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7214 /* note, use a mov/add for the shift since the mov has a
7215 chance of getting optimized out */
7216 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7217 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7218 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7219 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7220 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7224 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7225 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7231 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7232 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7233 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7234 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7236 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7237 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7238 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7242 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7243 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7247 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7248 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7249 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7250 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7252 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7253 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7254 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7255 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7256 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7257 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7258 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7259 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7262 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7263 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7264 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7265 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7266 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7271 /*-----------------------------------------------------------------*/
7272 /* shiftR2Left2Result - shift right two bytes from left to result */
7273 /*-----------------------------------------------------------------*/
7274 static void shiftR2Left2Result (operand *left, int offl,
7275 operand *result, int offr,
7276 int shCount, int sign)
7278 int same = pic16_sameRegs(AOP(result), AOP(left));
7280 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7282 if (same && (offl != offr)) { // shift right bytes
7285 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7286 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7288 } else { // just treat as different later on
7300 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7305 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7306 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7308 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7309 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7310 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7311 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7316 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7319 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7320 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7327 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7328 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7329 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7331 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7332 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7333 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7334 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7336 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7337 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7338 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7340 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7341 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7342 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7343 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7344 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7348 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7349 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7353 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7354 pic16_emitpcode(POC_BTFSC,
7355 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7356 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7364 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7365 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7367 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7368 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7369 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7370 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7372 pic16_emitpcode(POC_BTFSC,
7373 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7374 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7376 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7377 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7378 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7379 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7381 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7382 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7383 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7384 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7385 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7386 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7387 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7388 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7390 pic16_emitpcode(POC_BTFSC,
7391 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7392 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7394 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7395 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7402 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7403 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7404 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7405 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7408 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7410 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7415 /*-----------------------------------------------------------------*/
7416 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7417 /*-----------------------------------------------------------------*/
7418 static void shiftLLeftOrResult (operand *left, int offl,
7419 operand *result, int offr, int shCount)
7421 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7423 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7424 /* shift left accumulator */
7426 /* or with result */
7427 /* back to result */
7428 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7431 /*-----------------------------------------------------------------*/
7432 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7433 /*-----------------------------------------------------------------*/
7434 static void shiftRLeftOrResult (operand *left, int offl,
7435 operand *result, int offr, int shCount)
7437 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7439 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7440 /* shift right accumulator */
7442 /* or with result */
7443 /* back to result */
7444 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7447 /*-----------------------------------------------------------------*/
7448 /* genlshOne - left shift a one byte quantity by known count */
7449 /*-----------------------------------------------------------------*/
7450 static void genlshOne (operand *result, operand *left, int shCount)
7452 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7453 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7456 /*-----------------------------------------------------------------*/
7457 /* genlshTwo - left shift two bytes by known amount != 0 */
7458 /*-----------------------------------------------------------------*/
7459 static void genlshTwo (operand *result,operand *left, int shCount)
7463 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7464 size = pic16_getDataSize(result);
7466 /* if shCount >= 8 */
7472 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7474 movLeft2Result(left, LSB, result, MSB16);
7476 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7479 /* 1 <= shCount <= 7 */
7482 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7484 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7488 /*-----------------------------------------------------------------*/
7489 /* shiftLLong - shift left one long from left to result */
7490 /* offr = LSB or MSB16 */
7491 /*-----------------------------------------------------------------*/
7492 static void shiftLLong (operand *left, operand *result, int offr )
7494 int size = AOP_SIZE(result);
7495 int same = pic16_sameRegs(AOP(left),AOP(result));
7498 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7500 if (same && (offr == MSB16)) { //shift one byte
7501 for(i=size-1;i>=MSB16;i--) {
7502 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7503 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7506 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7509 if (size >= LSB+offr ){
7511 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7513 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7514 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7518 if(size >= MSB16+offr){
7520 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7522 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7523 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7527 if(size >= MSB24+offr){
7529 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7531 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7532 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7536 if(size > MSB32+offr){
7538 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7540 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7541 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7545 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7549 /*-----------------------------------------------------------------*/
7550 /* genlshFour - shift four byte by a known amount != 0 */
7551 /*-----------------------------------------------------------------*/
7552 static void genlshFour (operand *result, operand *left, int shCount)
7556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7557 size = AOP_SIZE(result);
7559 /* if shifting more that 3 bytes */
7560 if (shCount >= 24 ) {
7563 /* lowest order of left goes to the highest
7564 order of the destination */
7565 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7567 movLeft2Result(left, LSB, result, MSB32);
7569 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7570 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7571 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7576 /* more than two bytes */
7577 else if ( shCount >= 16 ) {
7578 /* lower order two bytes goes to higher order two bytes */
7580 /* if some more remaining */
7582 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7584 movLeft2Result(left, MSB16, result, MSB32);
7585 movLeft2Result(left, LSB, result, MSB24);
7587 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7588 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7592 /* if more than 1 byte */
7593 else if ( shCount >= 8 ) {
7594 /* lower order three bytes goes to higher order three bytes */
7598 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7600 movLeft2Result(left, LSB, result, MSB16);
7602 else{ /* size = 4 */
7604 movLeft2Result(left, MSB24, result, MSB32);
7605 movLeft2Result(left, MSB16, result, MSB24);
7606 movLeft2Result(left, LSB, result, MSB16);
7607 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7609 else if(shCount == 1)
7610 shiftLLong(left, result, MSB16);
7612 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7613 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7614 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7615 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7620 /* 1 <= shCount <= 7 */
7621 else if(shCount <= 3)
7623 shiftLLong(left, result, LSB);
7624 while(--shCount >= 1)
7625 shiftLLong(result, result, LSB);
7627 /* 3 <= shCount <= 7, optimize */
7629 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7630 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7631 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7635 /*-----------------------------------------------------------------*/
7636 /* genLeftShiftLiteral - left shifting by known count */
7637 /*-----------------------------------------------------------------*/
7638 static void genLeftShiftLiteral (operand *left,
7643 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7646 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7647 pic16_freeAsmop(right,NULL,ic,TRUE);
7649 pic16_aopOp(left,ic,FALSE);
7650 pic16_aopOp(result,ic,FALSE);
7652 size = getSize(operandType(result));
7655 pic16_emitcode("; shift left ","result %d, left %d",size,
7659 /* I suppose that the left size >= result size */
7662 movLeft2Result(left, size, result, size);
7666 else if(shCount >= (size * 8))
7668 pic16_aopPut(AOP(result),zero,size);
7672 genlshOne (result,left,shCount);
7677 genlshTwo (result,left,shCount);
7681 genlshFour (result,left,shCount);
7685 pic16_freeAsmop(left,NULL,ic,TRUE);
7686 pic16_freeAsmop(result,NULL,ic,TRUE);
7689 /*-----------------------------------------------------------------*
7690 * genMultiAsm - repeat assembly instruction for size of register.
7691 * if endian == 1, then the high byte (i.e base address + size of
7692 * register) is used first else the low byte is used first;
7693 *-----------------------------------------------------------------*/
7694 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7712 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7717 /*-----------------------------------------------------------------*/
7718 /* genLeftShift - generates code for left shifting */
7719 /*-----------------------------------------------------------------*/
7720 static void genLeftShift (iCode *ic)
7722 operand *left,*right, *result;
7725 symbol *tlbl , *tlbl1;
7728 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7730 right = IC_RIGHT(ic);
7732 result = IC_RESULT(ic);
7734 pic16_aopOp(right,ic,FALSE);
7736 /* if the shift count is known then do it
7737 as efficiently as possible */
7738 if (AOP_TYPE(right) == AOP_LIT) {
7739 genLeftShiftLiteral (left,right,result,ic);
7743 /* shift count is unknown then we have to form
7744 a loop get the loop count in B : Note: we take
7745 only the lower order byte since shifting
7746 more that 32 bits make no sense anyway, ( the
7747 largest size of an object can be only 32 bits ) */
7750 pic16_aopOp(left,ic,FALSE);
7751 pic16_aopOp(result,ic,FALSE);
7753 /* now move the left to the result if they are not the
7755 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7756 AOP_SIZE(result) > 1) {
7758 size = AOP_SIZE(result);
7761 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7762 if (*l == '@' && (IS_AOP_PREG(result))) {
7764 pic16_emitcode("mov","a,%s",l);
7765 pic16_aopPut(AOP(result),"a",offset);
7767 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7768 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7769 //pic16_aopPut(AOP(result),l,offset);
7775 size = AOP_SIZE(result);
7777 /* if it is only one byte then */
7779 if(optimized_for_speed) {
7780 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7781 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7782 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7783 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7785 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7786 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7787 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7788 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7789 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7790 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7791 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7794 tlbl = newiTempLabel(NULL);
7795 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7796 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7800 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7801 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7802 pic16_emitpLabel(tlbl->key);
7803 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7804 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7806 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7811 if (pic16_sameRegs(AOP(left),AOP(result))) {
7813 tlbl = newiTempLabel(NULL);
7814 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7815 genMultiAsm(POC_RRCF, result, size,1);
7816 pic16_emitpLabel(tlbl->key);
7817 genMultiAsm(POC_RLCF, result, size,0);
7818 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7820 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7824 //tlbl = newiTempLabel(NULL);
7826 //tlbl1 = newiTempLabel(NULL);
7828 //reAdjustPreg(AOP(result));
7830 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7831 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7832 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7834 //pic16_emitcode("add","a,acc");
7835 //pic16_aopPut(AOP(result),"a",offset++);
7837 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7839 // pic16_emitcode("rlc","a");
7840 // pic16_aopPut(AOP(result),"a",offset++);
7842 //reAdjustPreg(AOP(result));
7844 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7845 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7848 tlbl = newiTempLabel(NULL);
7849 tlbl1= newiTempLabel(NULL);
7851 size = AOP_SIZE(result);
7854 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7856 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7858 /* offset should be 0, 1 or 3 */
7860 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7862 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7864 pic16_emitpcode(POC_MOVWF, pctemp);
7867 pic16_emitpLabel(tlbl->key);
7870 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7872 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7874 pic16_emitpcode(POC_DECFSZ, pctemp);
7875 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7876 pic16_emitpLabel(tlbl1->key);
7878 pic16_popReleaseTempReg(pctemp);
7882 pic16_freeAsmop (right,NULL,ic,TRUE);
7883 pic16_freeAsmop(left,NULL,ic,TRUE);
7884 pic16_freeAsmop(result,NULL,ic,TRUE);
7887 /*-----------------------------------------------------------------*/
7888 /* genrshOne - right shift a one byte quantity by known count */
7889 /*-----------------------------------------------------------------*/
7890 static void genrshOne (operand *result, operand *left,
7891 int shCount, int sign)
7893 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7894 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7897 /*-----------------------------------------------------------------*/
7898 /* genrshTwo - right shift two bytes by known amount != 0 */
7899 /*-----------------------------------------------------------------*/
7900 static void genrshTwo (operand *result,operand *left,
7901 int shCount, int sign)
7903 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7904 /* if shCount >= 8 */
7908 shiftR1Left2Result(left, MSB16, result, LSB,
7911 movLeft2Result(left, MSB16, result, LSB);
7913 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7916 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7917 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7921 /* 1 <= shCount <= 7 */
7923 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7926 /*-----------------------------------------------------------------*/
7927 /* shiftRLong - shift right one long from left to result */
7928 /* offl = LSB or MSB16 */
7929 /*-----------------------------------------------------------------*/
7930 static void shiftRLong (operand *left, int offl,
7931 operand *result, int sign)
7933 int size = AOP_SIZE(result);
7934 int same = pic16_sameRegs(AOP(left),AOP(result));
7936 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7938 if (same && (offl == MSB16)) { //shift one byte right
7939 for(i=MSB16;i<size;i++) {
7940 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7941 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7946 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7952 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7954 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7955 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7959 /* add sign of "a" */
7960 pic16_addSign(result, MSB32, sign);
7964 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7966 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7967 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7971 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7973 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7974 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7978 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7981 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7982 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7987 /*-----------------------------------------------------------------*/
7988 /* genrshFour - shift four byte by a known amount != 0 */
7989 /*-----------------------------------------------------------------*/
7990 static void genrshFour (operand *result, operand *left,
7991 int shCount, int sign)
7993 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7994 /* if shifting more that 3 bytes */
7995 if(shCount >= 24 ) {
7998 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8000 movLeft2Result(left, MSB32, result, LSB);
8002 pic16_addSign(result, MSB16, sign);
8004 else if(shCount >= 16){
8007 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8009 movLeft2Result(left, MSB24, result, LSB);
8010 movLeft2Result(left, MSB32, result, MSB16);
8012 pic16_addSign(result, MSB24, sign);
8014 else if(shCount >= 8){
8017 shiftRLong(left, MSB16, result, sign);
8018 else if(shCount == 0){
8019 movLeft2Result(left, MSB16, result, LSB);
8020 movLeft2Result(left, MSB24, result, MSB16);
8021 movLeft2Result(left, MSB32, result, MSB24);
8022 pic16_addSign(result, MSB32, sign);
8024 else{ //shcount >= 2
8025 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8026 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8027 /* the last shift is signed */
8028 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8029 pic16_addSign(result, MSB32, sign);
8032 else{ /* 1 <= shCount <= 7 */
8034 shiftRLong(left, LSB, result, sign);
8036 shiftRLong(result, LSB, result, sign);
8039 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8040 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8041 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8046 /*-----------------------------------------------------------------*/
8047 /* genRightShiftLiteral - right shifting by known count */
8048 /*-----------------------------------------------------------------*/
8049 static void genRightShiftLiteral (operand *left,
8055 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8058 pic16_freeAsmop(right,NULL,ic,TRUE);
8060 pic16_aopOp(left,ic,FALSE);
8061 pic16_aopOp(result,ic,FALSE);
8063 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8066 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8070 lsize = pic16_getDataSize(left);
8071 res_size = pic16_getDataSize(result);
8072 /* test the LEFT size !!! */
8074 /* I suppose that the left size >= result size */
8077 movLeft2Result(left, lsize, result, res_size);
8080 else if(shCount >= (lsize * 8)){
8083 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8085 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8086 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8091 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8092 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8093 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8095 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8100 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8107 genrshOne (result,left,shCount,sign);
8111 genrshTwo (result,left,shCount,sign);
8115 genrshFour (result,left,shCount,sign);
8123 pic16_freeAsmop(left,NULL,ic,TRUE);
8124 pic16_freeAsmop(result,NULL,ic,TRUE);
8127 /*-----------------------------------------------------------------*/
8128 /* genSignedRightShift - right shift of signed number */
8129 /*-----------------------------------------------------------------*/
8130 static void genSignedRightShift (iCode *ic)
8132 operand *right, *left, *result;
8135 symbol *tlbl, *tlbl1 ;
8138 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8140 /* we do it the hard way put the shift count in b
8141 and loop thru preserving the sign */
8142 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8144 right = IC_RIGHT(ic);
8146 result = IC_RESULT(ic);
8148 pic16_aopOp(right,ic,FALSE);
8149 pic16_aopOp(left,ic,FALSE);
8150 pic16_aopOp(result,ic,FALSE);
8153 if ( AOP_TYPE(right) == AOP_LIT) {
8154 genRightShiftLiteral (left,right,result,ic,1);
8157 /* shift count is unknown then we have to form
8158 a loop get the loop count in B : Note: we take
8159 only the lower order byte since shifting
8160 more that 32 bits make no sense anyway, ( the
8161 largest size of an object can be only 32 bits ) */
8163 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8164 //pic16_emitcode("inc","b");
8165 //pic16_freeAsmop (right,NULL,ic,TRUE);
8166 //pic16_aopOp(left,ic,FALSE);
8167 //pic16_aopOp(result,ic,FALSE);
8169 /* now move the left to the result if they are not the
8171 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8172 AOP_SIZE(result) > 1) {
8174 size = AOP_SIZE(result);
8178 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8179 if (*l == '@' && IS_AOP_PREG(result)) {
8181 pic16_emitcode("mov","a,%s",l);
8182 pic16_aopPut(AOP(result),"a",offset);
8184 pic16_aopPut(AOP(result),l,offset);
8186 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8187 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8193 /* mov the highest order bit to OVR */
8194 tlbl = newiTempLabel(NULL);
8195 tlbl1= newiTempLabel(NULL);
8197 size = AOP_SIZE(result);
8200 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8202 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8204 /* offset should be 0, 1 or 3 */
8205 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8207 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8209 pic16_emitpcode(POC_MOVWF, pctemp);
8212 pic16_emitpLabel(tlbl->key);
8214 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8215 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8218 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8221 pic16_emitpcode(POC_DECFSZ, pctemp);
8222 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8223 pic16_emitpLabel(tlbl1->key);
8225 pic16_popReleaseTempReg(pctemp);
8227 size = AOP_SIZE(result);
8229 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8230 pic16_emitcode("rlc","a");
8231 pic16_emitcode("mov","ov,c");
8232 /* if it is only one byte then */
8234 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8236 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8237 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8238 pic16_emitcode("mov","c,ov");
8239 pic16_emitcode("rrc","a");
8240 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8241 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8242 pic16_aopPut(AOP(result),"a",0);
8246 reAdjustPreg(AOP(result));
8247 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8248 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8249 pic16_emitcode("mov","c,ov");
8251 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8253 pic16_emitcode("rrc","a");
8254 pic16_aopPut(AOP(result),"a",offset--);
8256 reAdjustPreg(AOP(result));
8257 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8258 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8263 pic16_freeAsmop(left,NULL,ic,TRUE);
8264 pic16_freeAsmop(result,NULL,ic,TRUE);
8265 pic16_freeAsmop(right,NULL,ic,TRUE);
8268 /*-----------------------------------------------------------------*/
8269 /* genRightShift - generate code for right shifting */
8270 /*-----------------------------------------------------------------*/
8271 static void genRightShift (iCode *ic)
8273 operand *right, *left, *result;
8277 symbol *tlbl, *tlbl1 ;
8279 /* if signed then we do it the hard way preserve the
8280 sign bit moving it inwards */
8281 letype = getSpec(operandType(IC_LEFT(ic)));
8282 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8284 if (!SPEC_USIGN(letype)) {
8285 genSignedRightShift (ic);
8289 /* signed & unsigned types are treated the same : i.e. the
8290 signed is NOT propagated inwards : quoting from the
8291 ANSI - standard : "for E1 >> E2, is equivalent to division
8292 by 2**E2 if unsigned or if it has a non-negative value,
8293 otherwise the result is implementation defined ", MY definition
8294 is that the sign does not get propagated */
8296 right = IC_RIGHT(ic);
8298 result = IC_RESULT(ic);
8300 pic16_aopOp(right,ic,FALSE);
8302 /* if the shift count is known then do it
8303 as efficiently as possible */
8304 if (AOP_TYPE(right) == AOP_LIT) {
8305 genRightShiftLiteral (left,right,result,ic, 0);
8309 /* shift count is unknown then we have to form
8310 a loop get the loop count in B : Note: we take
8311 only the lower order byte since shifting
8312 more that 32 bits make no sense anyway, ( the
8313 largest size of an object can be only 32 bits ) */
8315 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8316 pic16_emitcode("inc","b");
8317 pic16_aopOp(left,ic,FALSE);
8318 pic16_aopOp(result,ic,FALSE);
8320 /* now move the left to the result if they are not the
8322 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8323 AOP_SIZE(result) > 1) {
8325 size = AOP_SIZE(result);
8328 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8329 if (*l == '@' && IS_AOP_PREG(result)) {
8331 pic16_emitcode("mov","a,%s",l);
8332 pic16_aopPut(AOP(result),"a",offset);
8334 pic16_aopPut(AOP(result),l,offset);
8339 tlbl = newiTempLabel(NULL);
8340 tlbl1= newiTempLabel(NULL);
8341 size = AOP_SIZE(result);
8344 /* if it is only one byte then */
8347 tlbl = newiTempLabel(NULL);
8348 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8349 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8350 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8353 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8354 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8355 pic16_emitpLabel(tlbl->key);
8356 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8357 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8359 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8364 reAdjustPreg(AOP(result));
8365 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8366 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8369 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8371 pic16_emitcode("rrc","a");
8372 pic16_aopPut(AOP(result),"a",offset--);
8374 reAdjustPreg(AOP(result));
8376 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8377 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8380 pic16_freeAsmop(left,NULL,ic,TRUE);
8381 pic16_freeAsmop (right,NULL,ic,TRUE);
8382 pic16_freeAsmop(result,NULL,ic,TRUE);
8385 /*-----------------------------------------------------------------*/
8386 /* genUnpackBits - generates code for unpacking bits */
8387 /*-----------------------------------------------------------------*/
8388 static void genUnpackBits (operand *result, char *rname, int ptype)
8395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8396 etype = getSpec(operandType(result));
8398 /* read the first byte */
8405 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8408 pic16_emitcode("clr","a");
8409 pic16_emitcode("movc","a","@a+dptr");
8414 /* if we have bitdisplacement then it fits */
8415 /* into this byte completely or if length is */
8416 /* less than a byte */
8417 if ((shCnt = SPEC_BSTR(etype)) ||
8418 (SPEC_BLEN(etype) <= 8)) {
8420 /* shift right acc */
8423 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8424 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8426 /* VR -- normally I would use the following, but since we use the hack,
8427 * to avoid the masking from AccRsh, why not mask it right now? */
8430 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8433 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8439 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8440 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8443 /* bit field did not fit in a byte */
8444 rlen = SPEC_BLEN(etype) - 8;
8445 pic16_aopPut(AOP(result),"a",offset++);
8452 pic16_emitcode("inc","%s",rname);
8453 pic16_emitcode("mov","a,@%s",rname);
8457 pic16_emitcode("inc","%s",rname);
8458 pic16_emitcode("movx","a,@%s",rname);
8462 pic16_emitcode("inc","dptr");
8463 pic16_emitcode("movx","a,@dptr");
8467 pic16_emitcode("clr","a");
8468 pic16_emitcode("inc","dptr");
8469 pic16_emitcode("movc","a","@a+dptr");
8473 pic16_emitcode("inc","dptr");
8474 pic16_emitcode("lcall","__gptrget");
8479 /* if we are done */
8483 pic16_aopPut(AOP(result),"a",offset++);
8488 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8489 pic16_aopPut(AOP(result),"a",offset);
8496 static void genDataPointerGet(operand *left,
8500 int size, offset = 0, leoffset=0 ;
8502 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8503 pic16_aopOp(result, ic, FALSE);
8505 size = AOP_SIZE(result);
8506 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
8510 /* The following tests may save a redudant movff instruction when
8511 * accessing unions */
8513 /* if they are the same */
8514 if (operandsEqu (left, result)) {
8515 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
8519 /* if they are the same registers */
8520 if (pic16_sameRegs(AOP(left),AOP(result))) {
8521 DEBUGpic16_emitcode("; ***", "left and result registers are same");
8527 if ( AOP_TYPE(left) == AOP_PCODE) {
8528 fprintf(stderr,"genDataPointerGet %s, %d\n",
8529 AOP(left)->aopu.pcop->name,
8530 (AOP(left)->aopu.pcop->type == PO_DIR)?
8531 PCOR(AOP(left)->aopu.pcop)->instance:
8532 PCOI(AOP(left)->aopu.pcop)->offset);
8536 if(AOP(left)->aopu.pcop->type == PO_DIR)
8537 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
8539 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8542 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
8544 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
8545 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
8546 mov2w(AOP(left), leoffset);
8547 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
8549 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
8550 pic16_popGet(AOP(left), leoffset),
8551 pic16_popGet(AOP(result), offset)));
8559 pic16_freeAsmop(result,NULL,ic,TRUE);
8562 void pic16_loadFSR0(operand *op)
8564 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
8568 /*-----------------------------------------------------------------*/
8569 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8570 /*-----------------------------------------------------------------*/
8571 static void genNearPointerGet (operand *left,
8576 //regs *preg = NULL ;
8577 sym_link *rtype, *retype;
8578 sym_link *ltype = operandType(left);
8580 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8582 rtype = operandType(result);
8583 retype= getSpec(rtype);
8585 pic16_aopOp(left,ic,FALSE);
8587 /* if left is rematerialisable and
8588 * result is not bit variable type and
8589 * the left is pointer to data space i.e
8590 * lower 128 bytes of space */
8591 if (AOP_TYPE(left) == AOP_PCODE
8592 && !IS_BITFIELD(retype)
8593 && DCL_TYPE(ltype) == POINTER) {
8595 genDataPointerGet (left,result,ic);
8596 pic16_freeAsmop(left, NULL, ic, TRUE);
8600 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8602 /* if the value is already in a pointer register
8603 * then don't need anything more */
8604 if (!AOP_INPREG(AOP(left))) {
8605 /* otherwise get a free pointer register */
8606 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8608 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
8609 pic16_loadFSR0( left );
8612 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8614 pic16_aopOp (result,ic,FALSE);
8616 /* if bitfield then unpack the bits */
8617 if (IS_BITFIELD(retype))
8618 genUnpackBits (result, NULL, POINTER);
8620 /* we have can just get the values */
8621 int size = AOP_SIZE(result);
8624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8627 /* fsr0 is loaded already -- VR */
8628 // pic16_loadFSR0( left );
8630 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8631 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8635 pic16_emitpcode(POC_MOVFF,
8636 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
8637 pic16_popGet(AOP(result), offset++)));
8639 pic16_emitpcode(POC_MOVFF,
8640 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
8641 pic16_popGet(AOP(result), offset++)));
8645 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
8646 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8648 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8652 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8654 pic16_emitcode("mov","a,@%s",rname);
8655 pic16_aopPut(AOP(result),"a",offset);
8657 sprintf(buffer,"@%s",rname);
8658 pic16_aopPut(AOP(result),buffer,offset);
8662 pic16_emitcode("inc","%s",rname);
8667 /* now some housekeeping stuff */
8669 /* we had to allocate for this iCode */
8670 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8671 pic16_freeAsmop(NULL,aop,ic,TRUE);
8673 /* we did not allocate which means left
8674 already in a pointer register, then
8675 if size > 0 && this could be used again
8676 we have to point it back to where it
8678 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8679 if (AOP_SIZE(result) > 1 &&
8680 !OP_SYMBOL(left)->remat &&
8681 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8683 // int size = AOP_SIZE(result) - 1;
8685 // pic16_emitcode("dec","%s",rname);
8690 pic16_freeAsmop(left,NULL,ic,TRUE);
8691 pic16_freeAsmop(result,NULL,ic,TRUE);
8695 /*-----------------------------------------------------------------*/
8696 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8697 /*-----------------------------------------------------------------*/
8698 static void genPagedPointerGet (operand *left,
8705 sym_link *rtype, *retype;
8707 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8709 rtype = operandType(result);
8710 retype= getSpec(rtype);
8712 pic16_aopOp(left,ic,FALSE);
8714 /* if the value is already in a pointer register
8715 then don't need anything more */
8716 if (!AOP_INPREG(AOP(left))) {
8717 /* otherwise get a free pointer register */
8719 preg = getFreePtr(ic,&aop,FALSE);
8720 pic16_emitcode("mov","%s,%s",
8722 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8723 rname = preg->name ;
8725 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8727 pic16_freeAsmop(left,NULL,ic,TRUE);
8728 pic16_aopOp (result,ic,FALSE);
8730 /* if bitfield then unpack the bits */
8731 if (IS_BITFIELD(retype))
8732 genUnpackBits (result,rname,PPOINTER);
8734 /* we have can just get the values */
8735 int size = AOP_SIZE(result);
8740 pic16_emitcode("movx","a,@%s",rname);
8741 pic16_aopPut(AOP(result),"a",offset);
8746 pic16_emitcode("inc","%s",rname);
8750 /* now some housekeeping stuff */
8752 /* we had to allocate for this iCode */
8753 pic16_freeAsmop(NULL,aop,ic,TRUE);
8755 /* we did not allocate which means left
8756 already in a pointer register, then
8757 if size > 0 && this could be used again
8758 we have to point it back to where it
8760 if (AOP_SIZE(result) > 1 &&
8761 !OP_SYMBOL(left)->remat &&
8762 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8764 int size = AOP_SIZE(result) - 1;
8766 pic16_emitcode("dec","%s",rname);
8771 pic16_freeAsmop(result,NULL,ic,TRUE);
8776 /*-----------------------------------------------------------------*/
8777 /* genFarPointerGet - gget value from far space */
8778 /*-----------------------------------------------------------------*/
8779 static void genFarPointerGet (operand *left,
8780 operand *result, iCode *ic)
8783 sym_link *retype = getSpec(operandType(result));
8785 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8787 pic16_aopOp(left,ic,FALSE);
8789 /* if the operand is already in dptr
8790 then we do nothing else we move the value to dptr */
8791 if (AOP_TYPE(left) != AOP_STR) {
8792 /* if this is remateriazable */
8793 if (AOP_TYPE(left) == AOP_IMMD)
8794 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8795 else { /* we need to get it byte by byte */
8796 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8797 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8798 if (options.model == MODEL_FLAT24)
8800 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8804 /* so dptr know contains the address */
8805 pic16_freeAsmop(left,NULL,ic,TRUE);
8806 pic16_aopOp(result,ic,FALSE);
8808 /* if bit then unpack */
8809 if (IS_BITFIELD(retype))
8810 genUnpackBits(result,"dptr",FPOINTER);
8812 size = AOP_SIZE(result);
8816 pic16_emitcode("movx","a,@dptr");
8817 pic16_aopPut(AOP(result),"a",offset++);
8819 pic16_emitcode("inc","dptr");
8823 pic16_freeAsmop(result,NULL,ic,TRUE);
8826 /*-----------------------------------------------------------------*/
8827 /* genCodePointerGet - get value from code space */
8828 /*-----------------------------------------------------------------*/
8829 static void genCodePointerGet (operand *left,
8830 operand *result, iCode *ic)
8833 sym_link *retype = getSpec(operandType(result));
8835 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8837 pic16_aopOp(left,ic,FALSE);
8839 /* if the operand is already in dptr
8840 then we do nothing else we move the value to dptr */
8841 if (AOP_TYPE(left) != AOP_STR) {
8842 /* if this is remateriazable */
8843 if (AOP_TYPE(left) == AOP_IMMD)
8844 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8845 else { /* we need to get it byte by byte */
8846 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8847 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8848 if (options.model == MODEL_FLAT24)
8850 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8854 /* so dptr know contains the address */
8855 pic16_freeAsmop(left,NULL,ic,TRUE);
8856 pic16_aopOp(result,ic,FALSE);
8858 /* if bit then unpack */
8859 if (IS_BITFIELD(retype))
8860 genUnpackBits(result,"dptr",CPOINTER);
8862 size = AOP_SIZE(result);
8866 pic16_emitcode("clr","a");
8867 pic16_emitcode("movc","a,@a+dptr");
8868 pic16_aopPut(AOP(result),"a",offset++);
8870 pic16_emitcode("inc","dptr");
8874 pic16_freeAsmop(result,NULL,ic,TRUE);
8877 /*-----------------------------------------------------------------*/
8878 /* genGenPointerGet - gget value from generic pointer space */
8879 /*-----------------------------------------------------------------*/
8880 static void genGenPointerGet (operand *left,
8881 operand *result, iCode *ic)
8883 int size, offset, lit;
8884 sym_link *retype = getSpec(operandType(result));
8886 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8887 pic16_aopOp(left,ic,FALSE);
8888 pic16_aopOp(result,ic,FALSE);
8889 size = AOP_SIZE(result);
8891 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8893 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
8895 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
8896 // load FSR0 from immediate
8897 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
8899 // pic16_loadFSR0( left );
8904 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8906 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8913 else { /* we need to get it byte by byte */
8914 // set up FSR0 with address from left
8915 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
8916 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
8922 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8924 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8931 /* if bit then unpack */
8932 if (IS_BITFIELD(retype))
8933 genUnpackBits(result,"BAD",GPOINTER);
8936 pic16_freeAsmop(left,NULL,ic,TRUE);
8937 pic16_freeAsmop(result,NULL,ic,TRUE);
8941 /*-----------------------------------------------------------------*/
8942 /* genConstPointerGet - get value from const generic pointer space */
8943 /*-----------------------------------------------------------------*/
8944 static void genConstPointerGet (operand *left,
8945 operand *result, iCode *ic)
8947 //sym_link *retype = getSpec(operandType(result));
8948 symbol *albl = newiTempLabel(NULL);
8949 symbol *blbl = newiTempLabel(NULL);
8952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8953 pic16_aopOp(left,ic,FALSE);
8954 pic16_aopOp(result,ic,FALSE);
8957 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8959 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8961 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8962 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8963 pic16_emitpLabel(albl->key);
8965 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8967 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8968 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8969 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8970 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8971 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8973 pic16_emitpLabel(blbl->key);
8975 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8978 pic16_freeAsmop(left,NULL,ic,TRUE);
8979 pic16_freeAsmop(result,NULL,ic,TRUE);
8982 /*-----------------------------------------------------------------*/
8983 /* genPointerGet - generate code for pointer get */
8984 /*-----------------------------------------------------------------*/
8985 static void genPointerGet (iCode *ic)
8987 operand *left, *result ;
8988 sym_link *type, *etype;
8991 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8994 result = IC_RESULT(ic) ;
8996 /* depending on the type of pointer we need to
8997 move it to the correct pointer register */
8998 type = operandType(left);
8999 etype = getSpec(type);
9002 if (IS_PTR_CONST(type))
9004 if (IS_CODEPTR(type))
9006 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9008 /* if left is of type of pointer then it is simple */
9009 if (IS_PTR(type) && !IS_FUNC(type->next))
9010 p_type = DCL_TYPE(type);
9012 /* we have to go by the storage class */
9013 p_type = PTR_TYPE(SPEC_OCLS(etype));
9015 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9017 if (SPEC_OCLS(etype)->codesp ) {
9018 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9019 //p_type = CPOINTER ;
9022 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9023 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9024 /*p_type = FPOINTER ;*/
9026 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9027 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9028 /* p_type = PPOINTER; */
9030 if (SPEC_OCLS(etype) == idata )
9031 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9032 /* p_type = IPOINTER; */
9034 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9035 /* p_type = POINTER ; */
9038 /* now that we have the pointer type we assign
9039 the pointer values */
9044 genNearPointerGet (left,result,ic);
9048 genPagedPointerGet(left,result,ic);
9052 genFarPointerGet (left,result,ic);
9056 genConstPointerGet (left,result,ic);
9057 //pic16_emitcodePointerGet (left,result,ic);
9062 if (IS_PTR_CONST(type))
9063 genConstPointerGet (left,result,ic);
9066 genGenPointerGet (left,result,ic);
9072 /*-----------------------------------------------------------------*/
9073 /* genPackBits - generates code for packed bit storage */
9074 /*-----------------------------------------------------------------*/
9075 static void genPackBits (sym_link *etype ,
9077 char *rname, int p_type)
9085 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9086 blen = SPEC_BLEN(etype);
9087 bstr = SPEC_BSTR(etype);
9089 if(AOP_TYPE(right) == AOP_LIT) {
9090 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9093 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9095 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9098 /* if the bit lenth is less than or */
9099 /* it exactly fits a byte then */
9100 if((shCnt=SPEC_BSTR(etype))
9101 || SPEC_BLEN(etype) <= 8 ) {
9103 /* shift left acc */
9106 /* using PRODL as a temporary register here */
9107 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9113 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9114 // pic16_emitcode ("mov","b,a");
9115 // pic16_emitcode("mov","a,@%s",rname);
9119 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9120 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9121 (unsigned char)(0xff >> (8-bstr))) ));
9122 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9123 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9127 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9128 ((unsigned char)(0xFF << (blen+bstr)) |
9129 (unsigned char)(0xFF >> (8-bstr)) ) );
9130 pic16_emitcode ("orl","a,b");
9131 if (p_type == GPOINTER)
9132 pic16_emitcode("pop","b");
9137 pic16_emitcode("mov","@%s,a",rname);
9140 pic16_emitcode("movx","@dptr,a");
9143 DEBUGpic16_emitcode(";lcall","__gptrput");
9152 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9153 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9158 if ( SPEC_BLEN(etype) <= 8 )
9161 pic16_emitcode("inc","%s",rname);
9162 rLen = SPEC_BLEN(etype) ;
9166 /* now generate for lengths greater than one byte */
9169 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9179 pic16_emitcode("mov","@%s,a",rname);
9181 pic16_emitcode("mov","@%s,%s",rname,l);
9186 pic16_emitcode("movx","@dptr,a");
9191 DEBUGpic16_emitcode(";lcall","__gptrput");
9194 pic16_emitcode ("inc","%s",rname);
9199 /* last last was not complete */
9201 /* save the byte & read byte */
9204 pic16_emitcode ("mov","b,a");
9205 pic16_emitcode("mov","a,@%s",rname);
9209 pic16_emitcode ("mov","b,a");
9210 pic16_emitcode("movx","a,@dptr");
9214 pic16_emitcode ("push","b");
9215 pic16_emitcode ("push","acc");
9216 pic16_emitcode ("lcall","__gptrget");
9217 pic16_emitcode ("pop","b");
9221 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9222 pic16_emitcode ("orl","a,b");
9225 if (p_type == GPOINTER)
9226 pic16_emitcode("pop","b");
9231 pic16_emitcode("mov","@%s,a",rname);
9235 pic16_emitcode("movx","@dptr,a");
9239 DEBUGpic16_emitcode(";lcall","__gptrput");
9243 /*-----------------------------------------------------------------*/
9244 /* genDataPointerSet - remat pointer to data space */
9245 /*-----------------------------------------------------------------*/
9246 static void genDataPointerSet(operand *right,
9250 int size, offset = 0, resoffset=0 ;
9252 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9253 pic16_aopOp(right,ic,FALSE);
9255 size = AOP_SIZE(right);
9256 fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9259 if ( AOP_TYPE(result) == AOP_PCODE) {
9260 fprintf(stderr,"genDataPointerSet %s, %d\n",
9261 AOP(result)->aopu.pcop->name,
9262 (AOP(result)->aopu.pcop->type == PO_DIR)?
9263 PCOR(AOP(result)->aopu.pcop)->instance:
9264 PCOI(AOP(result)->aopu.pcop)->offset);
9268 if(AOP(result)->aopu.pcop->type == PO_DIR)
9269 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9272 if (AOP_TYPE(right) == AOP_LIT) {
9273 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9275 lit = lit >> (8*offset);
9277 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9278 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9280 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),resoffset));
9283 mov2w(AOP(right), offset);
9284 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9290 pic16_freeAsmop(right,NULL,ic,TRUE);
9295 /*-----------------------------------------------------------------*/
9296 /* genNearPointerSet - pic16_emitcode for near pointer put */
9297 /*-----------------------------------------------------------------*/
9298 static void genNearPointerSet (operand *right,
9305 sym_link *ptype = operandType(result);
9308 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9309 retype= getSpec(operandType(right));
9310 resetype = getSpec(operandType(result));
9312 pic16_aopOp(result,ic,FALSE);
9314 /* if the result is rematerializable &
9315 * in data space & not a bit variable */
9317 /* and result is not a bit variable */
9318 if (AOP_TYPE(result) == AOP_PCODE
9319 // && AOP_TYPE(result) == AOP_IMMD
9320 && DCL_TYPE(ptype) == POINTER
9321 && !IS_BITFIELD(retype)
9322 && !IS_BITFIELD(resetype)) {
9324 genDataPointerSet (right,result,ic);
9325 pic16_freeAsmop(result,NULL,ic,TRUE);
9329 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9330 pic16_aopOp(right,ic,FALSE);
9331 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9333 /* if the value is already in a pointer register
9334 * then don't need anything more */
9335 if (!AOP_INPREG(AOP(result))) {
9336 /* otherwise get a free pointer register */
9337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9339 pic16_loadFSR0( result );
9342 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9346 /* if bitfield then unpack the bits */
9347 if (IS_BITFIELD(resetype)) {
9348 genPackBits (resetype, right, NULL, POINTER);
9350 /* we have can just get the values */
9351 int size = AOP_SIZE(right);
9354 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9356 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9359 //pic16_emitcode("mov","@%s,a",rname);
9360 pic16_emitcode("movf","indf0,w ;1");
9363 if (AOP_TYPE(right) == AOP_LIT) {
9364 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9367 pic16_emitcode("movlw","%s",l);
9368 pic16_emitcode("movwf","indf0 ;2");
9370 pic16_emitcode("clrf","indf0");
9372 pic16_emitcode("movf","%s,w",l);
9373 pic16_emitcode("movwf","indf0 ;2");
9375 //pic16_emitcode("mov","@%s,%s",rname,l);
9378 pic16_emitcode("incf","fsr0,f ;3");
9379 //pic16_emitcode("inc","%s",rname);
9384 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9385 /* now some housekeeping stuff */
9387 /* we had to allocate for this iCode */
9388 pic16_freeAsmop(NULL,aop,ic,TRUE);
9390 /* we did not allocate which means left
9391 * already in a pointer register, then
9392 * if size > 0 && this could be used again
9393 * we have to point it back to where it
9395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9396 if (AOP_SIZE(right) > 1
9397 && !OP_SYMBOL(result)->remat
9398 && ( OP_SYMBOL(result)->liveTo > ic->seq
9401 int size = AOP_SIZE(right) - 1;
9404 pic16_emitcode("decf","fsr0,f");
9405 //pic16_emitcode("dec","%s",rname);
9409 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9412 pic16_freeAsmop(right,NULL,ic,TRUE);
9413 pic16_freeAsmop(result,NULL,ic,TRUE);
9416 /*-----------------------------------------------------------------*/
9417 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9418 /*-----------------------------------------------------------------*/
9419 static void genPagedPointerSet (operand *right,
9428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9430 retype= getSpec(operandType(right));
9432 pic16_aopOp(result,ic,FALSE);
9434 /* if the value is already in a pointer register
9435 then don't need anything more */
9436 if (!AOP_INPREG(AOP(result))) {
9437 /* otherwise get a free pointer register */
9439 preg = getFreePtr(ic,&aop,FALSE);
9440 pic16_emitcode("mov","%s,%s",
9442 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9443 rname = preg->name ;
9445 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9447 pic16_freeAsmop(result,NULL,ic,TRUE);
9448 pic16_aopOp (right,ic,FALSE);
9450 /* if bitfield then unpack the bits */
9451 if (IS_BITFIELD(retype))
9452 genPackBits (retype,right,rname,PPOINTER);
9454 /* we have can just get the values */
9455 int size = AOP_SIZE(right);
9459 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9462 pic16_emitcode("movx","@%s,a",rname);
9465 pic16_emitcode("inc","%s",rname);
9471 /* now some housekeeping stuff */
9473 /* we had to allocate for this iCode */
9474 pic16_freeAsmop(NULL,aop,ic,TRUE);
9476 /* we did not allocate which means left
9477 already in a pointer register, then
9478 if size > 0 && this could be used again
9479 we have to point it back to where it
9481 if (AOP_SIZE(right) > 1 &&
9482 !OP_SYMBOL(result)->remat &&
9483 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9485 int size = AOP_SIZE(right) - 1;
9487 pic16_emitcode("dec","%s",rname);
9492 pic16_freeAsmop(right,NULL,ic,TRUE);
9497 /*-----------------------------------------------------------------*/
9498 /* genFarPointerSet - set value from far space */
9499 /*-----------------------------------------------------------------*/
9500 static void genFarPointerSet (operand *right,
9501 operand *result, iCode *ic)
9504 sym_link *retype = getSpec(operandType(right));
9506 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9507 pic16_aopOp(result,ic,FALSE);
9509 /* if the operand is already in dptr
9510 then we do nothing else we move the value to dptr */
9511 if (AOP_TYPE(result) != AOP_STR) {
9512 /* if this is remateriazable */
9513 if (AOP_TYPE(result) == AOP_IMMD)
9514 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9515 else { /* we need to get it byte by byte */
9516 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9517 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9518 if (options.model == MODEL_FLAT24)
9520 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9524 /* so dptr know contains the address */
9525 pic16_freeAsmop(result,NULL,ic,TRUE);
9526 pic16_aopOp(right,ic,FALSE);
9528 /* if bit then unpack */
9529 if (IS_BITFIELD(retype))
9530 genPackBits(retype,right,"dptr",FPOINTER);
9532 size = AOP_SIZE(right);
9536 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9538 pic16_emitcode("movx","@dptr,a");
9540 pic16_emitcode("inc","dptr");
9544 pic16_freeAsmop(right,NULL,ic,TRUE);
9547 /*-----------------------------------------------------------------*/
9548 /* genGenPointerSet - set value from generic pointer space */
9549 /*-----------------------------------------------------------------*/
9550 static void genGenPointerSet (operand *right,
9551 operand *result, iCode *ic)
9553 int size, offset, lit;
9554 sym_link *retype = getSpec(operandType(right));
9556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9558 pic16_aopOp(result,ic,FALSE);
9559 pic16_aopOp(right,ic,FALSE);
9560 size = AOP_SIZE(right);
9563 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9565 /* if the operand is already in dptr
9566 then we do nothing else we move the value to dptr */
9567 if (AOP_TYPE(result) != AOP_STR) {
9568 /* if this is remateriazable */
9569 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9570 // WARNING: anythig until "else" is untested!
9571 if (AOP_TYPE(result) == AOP_IMMD) {
9572 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9573 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
9574 // load FSR0 from immediate
9575 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9579 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9581 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9587 else { /* we need to get it byte by byte */
9588 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9589 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9591 // set up FSR0 with address of result
9592 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9593 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9595 /* hack hack! see if this the FSR. If so don't load W */
9596 if(AOP_TYPE(right) != AOP_ACC) {
9598 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9602 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9604 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9611 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9612 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9614 } // if (AOP_TYPE(result) != AOP_IMMD)
9616 } // if (AOP_TYPE(result) != AOP_STR)
9617 /* so dptr know contains the address */
9620 /* if bit then unpack */
9621 if (IS_BITFIELD(retype))
9622 genPackBits(retype,right,"dptr",GPOINTER);
9624 size = AOP_SIZE(right);
9627 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9629 // set up FSR0 with address of result
9630 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9631 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9634 if (AOP_TYPE(right) == AOP_LIT) {
9635 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9637 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
9639 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9641 } else { // no literal
9643 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9645 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9653 pic16_freeAsmop(right,NULL,ic,TRUE);
9654 pic16_freeAsmop(result,NULL,ic,TRUE);
9657 /*-----------------------------------------------------------------*/
9658 /* genPointerSet - stores the value into a pointer location */
9659 /*-----------------------------------------------------------------*/
9660 static void genPointerSet (iCode *ic)
9662 operand *right, *result ;
9663 sym_link *type, *etype;
9666 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9668 right = IC_RIGHT(ic);
9669 result = IC_RESULT(ic) ;
9671 /* depending on the type of pointer we need to
9672 move it to the correct pointer register */
9673 type = operandType(result);
9674 etype = getSpec(type);
9675 /* if left is of type of pointer then it is simple */
9676 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9677 p_type = DCL_TYPE(type);
9680 /* we have to go by the storage class */
9681 p_type = PTR_TYPE(SPEC_OCLS(etype));
9683 /* if (SPEC_OCLS(etype)->codesp ) { */
9684 /* p_type = CPOINTER ; */
9687 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9688 /* p_type = FPOINTER ; */
9690 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9691 /* p_type = PPOINTER ; */
9693 /* if (SPEC_OCLS(etype) == idata ) */
9694 /* p_type = IPOINTER ; */
9696 /* p_type = POINTER ; */
9699 /* now that we have the pointer type we assign
9700 the pointer values */
9705 genNearPointerSet (right,result,ic);
9709 genPagedPointerSet (right,result,ic);
9713 genFarPointerSet (right,result,ic);
9717 genGenPointerSet (right,result,ic);
9721 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9722 "genPointerSet: illegal pointer type");
9726 /*-----------------------------------------------------------------*/
9727 /* genIfx - generate code for Ifx statement */
9728 /*-----------------------------------------------------------------*/
9729 static void genIfx (iCode *ic, iCode *popIc)
9731 operand *cond = IC_COND(ic);
9734 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9736 pic16_aopOp(cond,ic,FALSE);
9738 /* get the value into acc */
9739 if (AOP_TYPE(cond) != AOP_CRY)
9740 pic16_toBoolean(cond);
9743 /* the result is now in the accumulator */
9744 pic16_freeAsmop(cond,NULL,ic,TRUE);
9746 /* if there was something to be popped then do it */
9750 /* if the condition is a bit variable */
9751 if (isbit && IS_ITEMP(cond) &&
9753 genIfxJump(ic,SPIL_LOC(cond)->rname);
9754 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9757 if (isbit && !IS_ITEMP(cond))
9758 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9766 /*-----------------------------------------------------------------*/
9767 /* genAddrOf - generates code for address of */
9768 /*-----------------------------------------------------------------*/
9769 static void genAddrOf (iCode *ic)
9771 operand *result, *left;
9773 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9774 pCodeOp *pcop0, *pcop1, *pcop2;
9776 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9778 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9779 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9781 sym = OP_SYMBOL( left );
9783 size = AOP_SIZE(IC_RESULT(ic));
9785 if(pic16_debug_verbose) {
9786 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9787 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9790 /* Assume that what we want the address of is in data space
9791 * since there is no stack on the PIC, yet! -- VR */
9793 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9796 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9799 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9803 pic16_emitpcode(POC_MOVLW, pcop0);
9804 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9805 pic16_emitpcode(POC_MOVLW, pcop1);
9806 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9807 pic16_emitpcode(POC_MOVLW, pcop2);
9808 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9811 pic16_emitpcode(POC_MOVLW, pcop0);
9812 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9813 pic16_emitpcode(POC_MOVLW, pcop1);
9814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9816 pic16_emitpcode(POC_MOVLW, pcop0);
9817 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9820 pic16_freeAsmop(result,NULL,ic,TRUE);
9821 pic16_freeAsmop(left, NULL, ic, FALSE);
9826 /*-----------------------------------------------------------------*/
9827 /* genFarFarAssign - assignment when both are in far space */
9828 /*-----------------------------------------------------------------*/
9829 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9831 int size = AOP_SIZE(right);
9834 /* first push the right side on to the stack */
9836 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9838 pic16_emitcode ("push","acc");
9841 pic16_freeAsmop(right,NULL,ic,FALSE);
9842 /* now assign DPTR to result */
9843 pic16_aopOp(result,ic,FALSE);
9844 size = AOP_SIZE(result);
9846 pic16_emitcode ("pop","acc");
9847 pic16_aopPut(AOP(result),"a",--offset);
9849 pic16_freeAsmop(result,NULL,ic,FALSE);
9854 /*-----------------------------------------------------------------*/
9855 /* genAssign - generate code for assignment */
9856 /*-----------------------------------------------------------------*/
9857 static void genAssign (iCode *ic)
9859 operand *result, *right;
9860 int size, offset,know_W;
9861 unsigned long lit = 0L;
9863 result = IC_RESULT(ic);
9864 right = IC_RIGHT(ic) ;
9866 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9868 /* if they are the same */
9869 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9872 pic16_aopOp(right,ic,FALSE);
9873 pic16_aopOp(result,ic,TRUE);
9875 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9877 /* if they are the same registers */
9878 if (pic16_sameRegs(AOP(right),AOP(result)))
9881 /* if the result is a bit */
9882 if (AOP_TYPE(result) == AOP_CRY) {
9883 /* if the right size is a literal then
9884 we know what the value is */
9885 if (AOP_TYPE(right) == AOP_LIT) {
9887 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9888 pic16_popGet(AOP(result),0));
9890 if (((int) operandLitValue(right)))
9891 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9892 AOP(result)->aopu.aop_dir,
9893 AOP(result)->aopu.aop_dir);
9895 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9896 AOP(result)->aopu.aop_dir,
9897 AOP(result)->aopu.aop_dir);
9901 /* the right is also a bit variable */
9902 if (AOP_TYPE(right) == AOP_CRY) {
9903 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9904 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9905 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9907 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9908 AOP(result)->aopu.aop_dir,
9909 AOP(result)->aopu.aop_dir);
9910 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9911 AOP(right)->aopu.aop_dir,
9912 AOP(right)->aopu.aop_dir);
9913 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9914 AOP(result)->aopu.aop_dir,
9915 AOP(result)->aopu.aop_dir);
9920 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9921 pic16_toBoolean(right);
9923 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9924 //pic16_aopPut(AOP(result),"a",0);
9928 /* bit variables done */
9930 size = AOP_SIZE(result);
9932 if(AOP_TYPE(right) == AOP_LIT)
9933 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9935 /* VR - What is this?! */
9936 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9938 if(aopIdx(AOP(result),0) == 4) {
9939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9940 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9941 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9944 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9949 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9950 if(AOP_TYPE(right) == AOP_LIT) {
9952 if(know_W != (lit&0xff))
9953 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9955 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9957 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9961 } else if (AOP_TYPE(right) == AOP_CRY) {
9962 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9964 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9965 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9971 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9972 normally should work, but mind that the W register live range
9973 is not checked, so if the code generator assumes that the W
9974 is already loaded after such a pair, wrong code will be generated.
9976 Checking the live range is the next step.
9977 This is experimental code yet and has not been fully tested yet.
9978 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9979 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9981 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9983 /* This is the old code, which is assumed(?!) that works fine(!?) */
9985 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9986 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9995 pic16_freeAsmop (right,NULL,ic,FALSE);
9996 pic16_freeAsmop (result,NULL,ic,TRUE);
9999 /*-----------------------------------------------------------------*/
10000 /* genJumpTab - generates code for jump table */
10001 /*-----------------------------------------------------------------*/
10002 static void genJumpTab (iCode *ic)
10007 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10009 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10010 /* get the condition into accumulator */
10011 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10013 /* multiply by three */
10014 pic16_emitcode("add","a,acc");
10015 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10017 jtab = newiTempLabel(NULL);
10018 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10019 pic16_emitcode("jmp","@a+dptr");
10020 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10022 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10023 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10025 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10026 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10027 pic16_emitpLabel(jtab->key);
10029 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10031 /* now generate the jump labels */
10032 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10033 jtab = setNextItem(IC_JTLABELS(ic))) {
10034 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10035 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10041 /*-----------------------------------------------------------------*/
10042 /* genMixedOperation - gen code for operators between mixed types */
10043 /*-----------------------------------------------------------------*/
10045 TSD - Written for the PIC port - but this unfortunately is buggy.
10046 This routine is good in that it is able to efficiently promote
10047 types to different (larger) sizes. Unfortunately, the temporary
10048 variables that are optimized out by this routine are sometimes
10049 used in other places. So until I know how to really parse the
10050 iCode tree, I'm going to not be using this routine :(.
10052 static int genMixedOperation (iCode *ic)
10055 operand *result = IC_RESULT(ic);
10056 sym_link *ctype = operandType(IC_LEFT(ic));
10057 operand *right = IC_RIGHT(ic);
10063 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10065 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10071 nextright = IC_RIGHT(nextic);
10072 nextleft = IC_LEFT(nextic);
10073 nextresult = IC_RESULT(nextic);
10075 pic16_aopOp(right,ic,FALSE);
10076 pic16_aopOp(result,ic,FALSE);
10077 pic16_aopOp(nextright, nextic, FALSE);
10078 pic16_aopOp(nextleft, nextic, FALSE);
10079 pic16_aopOp(nextresult, nextic, FALSE);
10081 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10083 operand *t = right;
10087 pic16_emitcode(";remove right +","");
10089 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10091 operand *t = right;
10095 pic16_emitcode(";remove left +","");
10099 big = AOP_SIZE(nextleft);
10100 small = AOP_SIZE(nextright);
10102 switch(nextic->op) {
10105 pic16_emitcode(";optimize a +","");
10106 /* if unsigned or not an integral type */
10107 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10108 pic16_emitcode(";add a bit to something","");
10111 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10113 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10114 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10115 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10117 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10125 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10126 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10127 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10130 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10132 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10133 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10134 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10135 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10136 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10139 pic16_emitcode("rlf","known_zero,w");
10146 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10147 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10148 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10150 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10160 pic16_freeAsmop(right,NULL,ic,TRUE);
10161 pic16_freeAsmop(result,NULL,ic,TRUE);
10162 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10163 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10165 nextic->generated = 1;
10172 /*-----------------------------------------------------------------*/
10173 /* genCast - gen code for casting */
10174 /*-----------------------------------------------------------------*/
10175 static void genCast (iCode *ic)
10177 operand *result = IC_RESULT(ic);
10178 sym_link *ctype = operandType(IC_LEFT(ic));
10179 sym_link *rtype = operandType(IC_RIGHT(ic));
10180 operand *right = IC_RIGHT(ic);
10183 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10184 /* if they are equivalent then do nothing */
10185 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10188 pic16_aopOp(right,ic,FALSE) ;
10189 pic16_aopOp(result,ic,FALSE);
10191 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10193 /* if the result is a bit */
10194 if (AOP_TYPE(result) == AOP_CRY) {
10196 /* if the right size is a literal then
10197 * we know what the value is */
10198 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10200 if (AOP_TYPE(right) == AOP_LIT) {
10201 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10202 pic16_popGet(AOP(result),0));
10204 if (((int) operandLitValue(right)))
10205 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10206 AOP(result)->aopu.aop_dir,
10207 AOP(result)->aopu.aop_dir);
10209 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10210 AOP(result)->aopu.aop_dir,
10211 AOP(result)->aopu.aop_dir);
10215 /* the right is also a bit variable */
10216 if (AOP_TYPE(right) == AOP_CRY) {
10218 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10220 pic16_emitcode("clrc","");
10221 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10222 AOP(right)->aopu.aop_dir,
10223 AOP(right)->aopu.aop_dir);
10224 pic16_aopPut(AOP(result),"c",0);
10228 /* we need to or */
10229 if (AOP_TYPE(right) == AOP_REG) {
10230 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10231 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10232 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10234 pic16_toBoolean(right);
10235 pic16_aopPut(AOP(result),"a",0);
10239 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10242 size = AOP_SIZE(result);
10244 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10246 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10247 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10248 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10251 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10256 /* if they are the same size : or less */
10257 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10259 /* if they are in the same place */
10260 if (pic16_sameRegs(AOP(right),AOP(result)))
10263 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10265 if (IS_PTR_CONST(rtype))
10267 if (IS_CODEPTR(rtype))
10269 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10272 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10274 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10276 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10279 if(AOP_TYPE(right) == AOP_IMMD) {
10280 pCodeOp *pcop0, *pcop1, *pcop2;
10281 symbol *sym = OP_SYMBOL( right );
10283 size = AOP_SIZE(result);
10285 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10287 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10289 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10292 pic16_emitpcode(POC_MOVLW, pcop0);
10293 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10294 pic16_emitpcode(POC_MOVLW, pcop1);
10295 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10296 pic16_emitpcode(POC_MOVLW, pcop2);
10297 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10300 pic16_emitpcode(POC_MOVLW, pcop0);
10301 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10302 pic16_emitpcode(POC_MOVLW, pcop1);
10303 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10305 pic16_emitpcode(POC_MOVLW, pcop0);
10306 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10310 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10311 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10312 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10313 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10314 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10315 if(AOP_SIZE(result) <2)
10316 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10318 /* if they in different places then copy */
10319 size = AOP_SIZE(result);
10322 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10323 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10330 /* if the result is of type pointer */
10331 if (IS_PTR(ctype)) {
10333 sym_link *type = operandType(right);
10334 sym_link *etype = getSpec(type);
10336 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10338 /* pointer to generic pointer */
10339 if (IS_GENPTR(ctype)) {
10343 p_type = DCL_TYPE(type);
10345 /* we have to go by the storage class */
10346 p_type = PTR_TYPE(SPEC_OCLS(etype));
10348 /* if (SPEC_OCLS(etype)->codesp ) */
10349 /* p_type = CPOINTER ; */
10351 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10352 /* p_type = FPOINTER ; */
10354 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10355 /* p_type = PPOINTER; */
10357 /* if (SPEC_OCLS(etype) == idata ) */
10358 /* p_type = IPOINTER ; */
10360 /* p_type = POINTER ; */
10363 /* the first two bytes are known */
10364 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10365 size = GPTRSIZE - 1;
10368 if(offset < AOP_SIZE(right)) {
10369 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10370 if ((AOP_TYPE(right) == AOP_PCODE) &&
10371 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10372 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10373 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10375 pic16_aopPut(AOP(result),
10376 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10380 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10383 /* the last byte depending on type */
10387 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10390 pic16_emitcode(";BUG!? ","%d",__LINE__);
10394 pic16_emitcode(";BUG!? ","%d",__LINE__);
10398 pic16_emitcode(";BUG!? ","%d",__LINE__);
10403 /* this should never happen */
10404 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10405 "got unknown pointer type");
10408 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10412 /* just copy the pointers */
10413 size = AOP_SIZE(result);
10416 pic16_aopPut(AOP(result),
10417 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10426 /* so we now know that the size of destination is greater
10427 than the size of the source.
10428 Now, if the next iCode is an operator then we might be
10429 able to optimize the operation without performing a cast.
10431 if(genMixedOperation(ic))
10434 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10436 /* we move to result for the size of source */
10437 size = AOP_SIZE(right);
10440 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10441 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10445 /* now depending on the sign of the destination */
10446 size = AOP_SIZE(result) - AOP_SIZE(right);
10447 /* if unsigned or not an integral type */
10448 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10450 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10452 /* we need to extend the sign :( */
10455 /* Save one instruction of casting char to int */
10456 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10457 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10458 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10460 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10463 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10465 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10467 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10470 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10475 pic16_freeAsmop(right,NULL,ic,TRUE);
10476 pic16_freeAsmop(result,NULL,ic,TRUE);
10480 /*-----------------------------------------------------------------*/
10481 /* genDjnz - generate decrement & jump if not zero instrucion */
10482 /*-----------------------------------------------------------------*/
10483 static int genDjnz (iCode *ic, iCode *ifx)
10485 symbol *lbl, *lbl1;
10486 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10491 /* if the if condition has a false label
10492 then we cannot save */
10496 /* if the minus is not of the form
10498 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10499 !IS_OP_LITERAL(IC_RIGHT(ic)))
10502 if (operandLitValue(IC_RIGHT(ic)) != 1)
10505 /* if the size of this greater than one then no
10507 if (getSize(operandType(IC_RESULT(ic))) > 1)
10510 /* otherwise we can save BIG */
10511 lbl = newiTempLabel(NULL);
10512 lbl1= newiTempLabel(NULL);
10514 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10516 if (IS_AOP_PREG(IC_RESULT(ic))) {
10517 pic16_emitcode("dec","%s",
10518 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10519 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10520 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10524 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10525 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10527 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10528 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10531 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10532 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10533 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10534 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10537 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10538 ifx->generated = 1;
10542 /*-----------------------------------------------------------------*/
10543 /* genReceive - generate code for a receive iCode */
10544 /*-----------------------------------------------------------------*/
10545 static void genReceive (iCode *ic)
10547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10549 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10550 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10551 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10553 int size = getSize(operandType(IC_RESULT(ic)));
10554 int offset = pic16_fReturnSizePic - size;
10557 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10558 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10562 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10564 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10565 size = AOP_SIZE(IC_RESULT(ic));
10568 pic16_emitcode ("pop","acc");
10569 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10572 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10575 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10577 assignResultValue(IC_RESULT(ic), 0);
10580 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10583 /*-----------------------------------------------------------------*/
10584 /* genDummyRead - generate code for dummy read of volatiles */
10585 /*-----------------------------------------------------------------*/
10587 genDummyRead (iCode * ic)
10589 pic16_emitcode ("; genDummyRead","");
10590 pic16_emitcode ("; not implemented","");
10595 /*-----------------------------------------------------------------*/
10596 /* genpic16Code - generate code for pic16 based controllers */
10597 /*-----------------------------------------------------------------*/
10599 * At this point, ralloc.c has gone through the iCode and attempted
10600 * to optimize in a way suitable for a PIC. Now we've got to generate
10601 * PIC instructions that correspond to the iCode.
10603 * Once the instructions are generated, we'll pass through both the
10604 * peep hole optimizer and the pCode optimizer.
10605 *-----------------------------------------------------------------*/
10607 void genpic16Code (iCode *lic)
10612 lineHead = lineCurr = NULL;
10614 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10615 pic16_addpBlock(pb);
10618 /* if debug information required */
10619 if (options.debug && currFunc) {
10621 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10623 if (IS_STATIC(currFunc->etype)) {
10624 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10625 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10627 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10628 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10635 for (ic = lic ; ic ; ic = ic->next ) {
10637 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10638 if ( cln != ic->lineno ) {
10639 if ( options.debug ) {
10641 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10642 FileBaseName(ic->filename),ic->lineno,
10643 ic->level,ic->block);
10647 if(!options.noCcodeInAsm) {
10648 pic16_addpCode2pBlock(pb,
10649 pic16_newpCodeCSource(ic->lineno, ic->filename,
10650 printCLine(ic->filename, ic->lineno)));
10656 if(options.iCodeInAsm) {
10657 /* insert here code to print iCode as comment */
10658 pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic));
10661 /* if the result is marked as
10662 spilt and rematerializable or code for
10663 this has already been generated then
10665 if (resultRemat(ic) || ic->generated )
10668 /* depending on the operation */
10687 /* IPOP happens only when trying to restore a
10688 spilt live range, if there is an ifx statement
10689 following this pop then the if statement might
10690 be using some of the registers being popped which
10691 would destroy the contents of the register so
10692 we need to check for this condition and handle it */
10694 ic->next->op == IFX &&
10695 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10696 genIfx (ic->next,ic);
10714 genEndFunction (ic);
10730 pic16_genPlus (ic) ;
10734 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10735 pic16_genMinus (ic);
10751 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10755 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10762 /* note these two are xlated by algebraic equivalence
10763 during parsing SDCC.y */
10764 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10765 "got '>=' or '<=' shouldn't have come here");
10769 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10781 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10785 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10789 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10813 genRightShift (ic);
10816 case GET_VALUE_AT_ADDRESS:
10821 if (POINTER_SET(ic))
10848 addSet(&_G.sendSet,ic);
10851 case DUMMY_READ_VOLATILE:
10861 /* now we are ready to call the
10862 peep hole optimizer */
10863 if (!options.nopeep) {
10864 peepHole (&lineHead);
10866 /* now do the actual printing */
10867 printLine (lineHead,codeOutFile);
10870 DFPRINTF((stderr,"printing pBlock\n\n"));
10871 pic16_printpBlock(stdout,pb);