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);
1525 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1527 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1529 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1531 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1532 PCOR(pcop)->rIdx = rIdx;
1533 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1534 PCOR(pcop)->r->wasUsed=1;
1535 PCOR(pcop)->r->isFree=0;
1537 PCOR(pcop)->instance = offset;
1538 pcop->type = PCOR(pcop)->r->pc_type;
1539 // rs = aop->aopu.aop_reg[offset]->name;
1540 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1544 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1545 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1551 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1552 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1556 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1558 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1560 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1561 PCOR(pcop)->rIdx = rIdx;
1562 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1563 PCOR(pcop)->r->wasUsed=1;
1564 PCOR(pcop)->r->isFree=0;
1566 PCOR(pcop)->instance = offset;
1567 pcop->type = PCOR(pcop)->r->pc_type;
1568 rs = aop->aopu.aop_reg[offset]->name;
1569 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1574 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1576 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1577 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1578 //if(PCOR(pcop)->r == NULL)
1579 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1583 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1584 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1587 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1588 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1591 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1592 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1593 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1594 pcop->type = PCOR(pcop)->r->pc_type;
1595 pcop->name = PCOR(pcop)->r->name;
1601 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1603 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1604 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1606 switch( aop->aopu.pcop->type ) {
1607 case PO_DIR: PCOR(pcop)->instance = offset; break;
1608 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1610 assert( 0 ); /* should never reach here */;
1613 PCOI(pcop)->offset = offset;
1618 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1619 "pic16_popGet got unsupported aop->type");
1622 /*-----------------------------------------------------------------*/
1623 /* pic16_aopPut - puts a string for a aop */
1624 /*-----------------------------------------------------------------*/
1625 void pic16_aopPut (asmop *aop, char *s, int offset)
1630 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1632 if (aop->size && offset > ( aop->size - 1)) {
1633 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1634 "pic16_aopPut got offset > aop->size");
1638 /* will assign value to value */
1639 /* depending on where it is ofcourse */
1640 switch (aop->type) {
1643 sprintf(d,"(%s + %d)",
1644 aop->aopu.aop_dir,offset);
1645 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1648 sprintf(d,"%s",aop->aopu.aop_dir);
1651 DEBUGpic16_emitcode(";","%d",__LINE__);
1653 pic16_emitcode("movf","%s,w",s);
1654 pic16_emitcode("movwf","%s",d);
1657 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1658 if(offset >= aop->size) {
1659 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1662 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1665 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1672 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1673 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1676 strcmp(s,"r0") == 0 ||
1677 strcmp(s,"r1") == 0 ||
1678 strcmp(s,"r2") == 0 ||
1679 strcmp(s,"r3") == 0 ||
1680 strcmp(s,"r4") == 0 ||
1681 strcmp(s,"r5") == 0 ||
1682 strcmp(s,"r6") == 0 ||
1683 strcmp(s,"r7") == 0 )
1684 pic16_emitcode("mov","%s,%s ; %d",
1685 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1689 if(strcmp(s,"W")==0 )
1690 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1692 pic16_emitcode("movwf","%s",
1693 aop->aopu.aop_reg[offset]->name);
1695 if(strcmp(s,zero)==0) {
1696 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1698 } else if(strcmp(s,"W")==0) {
1699 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1700 pcop->type = PO_GPR_REGISTER;
1702 PCOR(pcop)->rIdx = -1;
1703 PCOR(pcop)->r = NULL;
1705 DEBUGpic16_emitcode(";","%d",__LINE__);
1706 pcop->name = Safe_strdup(s);
1707 pic16_emitpcode(POC_MOVFW,pcop);
1708 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1709 } else if(strcmp(s,one)==0) {
1710 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1711 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1713 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1721 if (aop->type == AOP_DPTR2)
1727 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1728 "pic16_aopPut writting to code space");
1732 while (offset > aop->coff) {
1734 pic16_emitcode ("inc","dptr");
1737 while (offset < aop->coff) {
1739 pic16_emitcode("lcall","__decdptr");
1744 /* if not in accumulater */
1747 pic16_emitcode ("movx","@dptr,a");
1749 if (aop->type == AOP_DPTR2)
1757 while (offset > aop->coff) {
1759 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1761 while (offset < aop->coff) {
1763 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1769 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1774 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1776 if (strcmp(s,"r0") == 0 ||
1777 strcmp(s,"r1") == 0 ||
1778 strcmp(s,"r2") == 0 ||
1779 strcmp(s,"r3") == 0 ||
1780 strcmp(s,"r4") == 0 ||
1781 strcmp(s,"r5") == 0 ||
1782 strcmp(s,"r6") == 0 ||
1783 strcmp(s,"r7") == 0 ) {
1785 sprintf(buffer,"a%s",s);
1786 pic16_emitcode("mov","@%s,%s",
1787 aop->aopu.aop_ptr->name,buffer);
1789 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1794 if (strcmp(s,"a") == 0)
1795 pic16_emitcode("push","acc");
1797 pic16_emitcode("push","%s",s);
1802 /* if bit variable */
1803 if (!aop->aopu.aop_dir) {
1804 pic16_emitcode("clr","a");
1805 pic16_emitcode("rlc","a");
1808 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1811 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1814 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1816 lbl = newiTempLabel(NULL);
1818 if (strcmp(s,"a")) {
1821 pic16_emitcode("clr","c");
1822 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1823 pic16_emitcode("cpl","c");
1824 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1825 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1832 if (strcmp(aop->aopu.aop_str[offset],s))
1833 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1838 if (!offset && (strcmp(s,"acc") == 0))
1841 if (strcmp(aop->aopu.aop_str[offset],s))
1842 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1846 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1847 "pic16_aopPut got unsupported aop->type");
1853 /*-----------------------------------------------------------------*/
1854 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1855 /*-----------------------------------------------------------------*/
1856 static void mov2w (asmop *aop, int offset)
1862 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1864 if ( aop->type == AOP_PCODE ||
1865 aop->type == AOP_LIT )
1866 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1868 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1873 /* push pcop into stack */
1874 void pic16_pushpCodeOp(pCodeOp *pcop)
1876 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1879 /* pop pcop from stack */
1880 void pic16_poppCodeOp(pCodeOp *pcop)
1882 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1886 /*-----------------------------------------------------------------*/
1887 /* pushw - pushes wreg to stack */
1888 /*-----------------------------------------------------------------*/
1891 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1892 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1896 /*-----------------------------------------------------------------*/
1897 /* pushaop - pushes aop to stack */
1898 /*-----------------------------------------------------------------*/
1899 void pushaop(asmop *aop, int offset)
1901 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1902 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1905 /*-----------------------------------------------------------------*/
1906 /* popaop - pops aop from stack */
1907 /*-----------------------------------------------------------------*/
1908 void popaop(asmop *aop, int offset)
1910 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1911 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1914 void popaopidx(asmop *aop, int offset, int index)
1918 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1920 if(STACK_MODEL_LARGE)ofs++;
1922 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1923 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1926 /*-----------------------------------------------------------------*/
1927 /* reAdjustPreg - points a register back to where it should */
1928 /*-----------------------------------------------------------------*/
1929 static void reAdjustPreg (asmop *aop)
1933 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1935 if ((size = aop->size) <= 1)
1938 switch (aop->type) {
1942 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1946 if (aop->type == AOP_DPTR2)
1952 pic16_emitcode("lcall","__decdptr");
1955 if (aop->type == AOP_DPTR2)
1967 /*-----------------------------------------------------------------*/
1968 /* opIsGptr: returns non-zero if the passed operand is */
1969 /* a generic pointer type. */
1970 /*-----------------------------------------------------------------*/
1971 static int opIsGptr(operand *op)
1973 sym_link *type = operandType(op);
1975 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1976 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1984 /*-----------------------------------------------------------------*/
1985 /* pic16_getDataSize - get the operand data size */
1986 /*-----------------------------------------------------------------*/
1987 int pic16_getDataSize(operand *op)
1989 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1992 return AOP_SIZE(op);
1994 // tsd- in the pic port, the genptr size is 1, so this code here
1995 // fails. ( in the 8051 port, the size was 4).
1998 size = AOP_SIZE(op);
1999 if (size == GPTRSIZE)
2001 sym_link *type = operandType(op);
2002 if (IS_GENPTR(type))
2004 /* generic pointer; arithmetic operations
2005 * should ignore the high byte (pointer type).
2008 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2015 /*-----------------------------------------------------------------*/
2016 /* pic16_outAcc - output Acc */
2017 /*-----------------------------------------------------------------*/
2018 void pic16_outAcc(operand *result)
2021 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2022 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2025 size = pic16_getDataSize(result);
2027 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2030 /* unsigned or positive */
2032 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2037 /*-----------------------------------------------------------------*/
2038 /* pic16_outBitC - output a bit C */
2039 /*-----------------------------------------------------------------*/
2040 void pic16_outBitC(operand *result)
2043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2044 /* if the result is bit */
2045 if (AOP_TYPE(result) == AOP_CRY)
2046 pic16_aopPut(AOP(result),"c",0);
2048 pic16_emitcode("clr","a ; %d", __LINE__);
2049 pic16_emitcode("rlc","a");
2050 pic16_outAcc(result);
2054 /*-----------------------------------------------------------------*/
2055 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2056 /*-----------------------------------------------------------------*/
2057 void pic16_toBoolean(operand *oper)
2059 int size = AOP_SIZE(oper) - 1;
2062 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2064 if ( AOP_TYPE(oper) != AOP_ACC) {
2065 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2068 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2073 #if !defined(GEN_Not)
2074 /*-----------------------------------------------------------------*/
2075 /* genNot - generate code for ! operation */
2076 /*-----------------------------------------------------------------*/
2077 static void pic16_genNot (iCode *ic)
2082 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2083 /* assign asmOps to operand & result */
2084 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2085 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2087 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2088 /* if in bit space then a special case */
2089 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2090 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2091 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2092 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2094 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2095 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2096 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2101 size = AOP_SIZE(IC_LEFT(ic));
2103 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2104 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2105 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2108 pic16_toBoolean(IC_LEFT(ic));
2110 tlbl = newiTempLabel(NULL);
2111 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2112 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2113 pic16_outBitC(IC_RESULT(ic));
2116 /* release the aops */
2117 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2118 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2123 #if !defined(GEN_Cpl)
2124 /*-----------------------------------------------------------------*/
2125 /* genCpl - generate code for complement */
2126 /*-----------------------------------------------------------------*/
2127 static void pic16_genCpl (iCode *ic)
2133 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2134 /* assign asmOps to operand & result */
2135 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2136 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2138 /* if both are in bit space then
2140 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2141 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2143 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2144 pic16_emitcode("cpl","c");
2145 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2149 size = AOP_SIZE(IC_RESULT(ic));
2152 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2154 pic16_emitcode("cpl","a");
2155 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2157 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2158 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2160 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2161 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2169 /* release the aops */
2170 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2171 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2175 /*-----------------------------------------------------------------*/
2176 /* genUminusFloat - unary minus for floating points */
2177 /*-----------------------------------------------------------------*/
2178 static void genUminusFloat(operand *op,operand *result)
2180 int size ,offset =0 ;
2183 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2184 /* for this we just need to flip the
2185 first it then copy the rest in place */
2186 size = AOP_SIZE(op) - 1;
2187 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2191 pic16_emitcode("cpl","acc.7");
2192 pic16_aopPut(AOP(result),"a",3);
2195 pic16_aopPut(AOP(result),
2196 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2202 /*-----------------------------------------------------------------*/
2203 /* genUminus - unary minus code generation */
2204 /*-----------------------------------------------------------------*/
2205 static void genUminus (iCode *ic)
2208 sym_link *optype, *rtype;
2211 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2213 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2214 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2216 /* if both in bit space then special
2218 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2219 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2221 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2222 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2223 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2228 optype = operandType(IC_LEFT(ic));
2229 rtype = operandType(IC_RESULT(ic));
2231 /* if float then do float stuff */
2232 if (IS_FLOAT(optype)) {
2233 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2237 /* otherwise subtract from zero by taking the 2's complement */
2238 size = AOP_SIZE(IC_LEFT(ic));
2240 for(i=0; i<size; i++) {
2241 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2242 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2244 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2245 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2249 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2250 for(i=1; i<size; i++) {
2252 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2256 /* release the aops */
2257 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2258 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2261 /*-----------------------------------------------------------------*/
2262 /* saveRegisters - will look for a call and save the registers */
2263 /*-----------------------------------------------------------------*/
2264 static void saveRegisters(iCode *lic)
2271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2273 for (ic = lic ; ic ; ic = ic->next)
2274 if (ic->op == CALL || ic->op == PCALL)
2278 fprintf(stderr,"found parameter push with no function call\n");
2282 /* if the registers have been saved already then
2284 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2287 /* find the registers in use at this time
2288 and push them away to safety */
2289 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2293 if (options.useXstack) {
2294 if (bitVectBitValue(rsave,R0_IDX))
2295 pic16_emitcode("mov","b,r0");
2296 pic16_emitcode("mov","r0,%s",spname);
2297 for (i = 0 ; i < pic16_nRegs ; i++) {
2298 if (bitVectBitValue(rsave,i)) {
2300 pic16_emitcode("mov","a,b");
2302 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2303 pic16_emitcode("movx","@r0,a");
2304 pic16_emitcode("inc","r0");
2307 pic16_emitcode("mov","%s,r0",spname);
2308 if (bitVectBitValue(rsave,R0_IDX))
2309 pic16_emitcode("mov","r0,b");
2311 //for (i = 0 ; i < pic16_nRegs ; i++) {
2312 // if (bitVectBitValue(rsave,i))
2313 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2316 dtype = operandType(IC_LEFT(ic));
2317 if (currFunc && dtype &&
2318 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2319 IFFUNC_ISISR(currFunc->type) &&
2322 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2325 /*-----------------------------------------------------------------*/
2326 /* unsaveRegisters - pop the pushed registers */
2327 /*-----------------------------------------------------------------*/
2328 static void unsaveRegisters (iCode *ic)
2333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2334 /* find the registers in use at this time
2335 and push them away to safety */
2336 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2339 if (options.useXstack) {
2340 pic16_emitcode("mov","r0,%s",spname);
2341 for (i = pic16_nRegs ; i >= 0 ; i--) {
2342 if (bitVectBitValue(rsave,i)) {
2343 pic16_emitcode("dec","r0");
2344 pic16_emitcode("movx","a,@r0");
2346 pic16_emitcode("mov","b,a");
2348 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2352 pic16_emitcode("mov","%s,r0",spname);
2353 if (bitVectBitValue(rsave,R0_IDX))
2354 pic16_emitcode("mov","r0,b");
2356 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2357 // if (bitVectBitValue(rsave,i))
2358 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2364 /*-----------------------------------------------------------------*/
2366 /*-----------------------------------------------------------------*/
2367 static void pushSide(operand * oper, int size)
2371 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2373 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2374 if (AOP_TYPE(oper) != AOP_REG &&
2375 AOP_TYPE(oper) != AOP_DIR &&
2377 pic16_emitcode("mov","a,%s",l);
2378 pic16_emitcode("push","acc");
2380 pic16_emitcode("push","%s",l);
2385 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2387 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2389 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2390 pic16_emitpcode(POC_MOVFW, src);
2391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2393 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2394 src, pic16_popGet(AOP(op), offset)));
2399 /*-----------------------------------------------------------------*/
2400 /* assignResultValue - assign results to oper, rescall==1 is */
2401 /* called from genCall() or genPCall() */
2402 /*-----------------------------------------------------------------*/
2403 static void assignResultValue(operand * oper, int rescall)
2405 int size = AOP_SIZE(oper);
2407 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2411 /* assign result from a call/pcall function() */
2413 /* function results are stored in a special order,
2414 * see top of file with Function return policy, or manual */
2417 /* 8-bits, result in WREG */
2418 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2421 /* 16-bits, result in PRODL:WREG */
2422 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2423 // pic16_emitpcode(POC_MOVFF,
2424 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(oper), 1)));
2428 /* 24-bits, result in PRODH:PRODL:WREG */
2429 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodl));
2431 // pic16_emitpcode(POC_MOVFF,
2432 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(oper), 2)));
2436 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2437 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_prodl));
2439 // pic16_emitpcode(POC_MOVFF,
2440 // pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popGet(AOP(oper), 3)));
2443 /* >32-bits, result on stack, and FSR0 points to beginning.
2444 * Fix stack when done */
2447 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2448 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2450 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2455 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2456 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2457 if(STACK_MODEL_LARGE) {
2459 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2463 if(!GpsuedoStkPtr) {
2464 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2465 /* The last byte in the assignment is in W */
2467 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2472 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2473 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2475 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2481 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2483 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2493 /*-----------------------------------------------------------------*/
2494 /* genIpush - genrate code for pushing this gets a little complex */
2495 /*-----------------------------------------------------------------*/
2496 static void genIpush (iCode *ic)
2499 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2501 int size, offset = 0 ;
2505 /* if this is not a parm push : ie. it is spill push
2506 and spill push is always done on the local stack */
2507 if (!ic->parmPush) {
2509 /* and the item is spilt then do nothing */
2510 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2513 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2514 size = AOP_SIZE(IC_LEFT(ic));
2515 /* push it on the stack */
2517 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2522 pic16_emitcode("push","%s",l);
2527 /* this is a paramter push: in this case we call
2528 the routine to find the call and save those
2529 registers that need to be saved */
2532 /* then do the push */
2533 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2536 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2537 size = AOP_SIZE(IC_LEFT(ic));
2540 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2541 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2542 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2544 pic16_emitcode("mov","a,%s",l);
2545 pic16_emitcode("push","acc");
2547 pic16_emitcode("push","%s",l);
2550 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2554 /*-----------------------------------------------------------------*/
2555 /* genIpop - recover the registers: can happen only for spilling */
2556 /*-----------------------------------------------------------------*/
2557 static void genIpop (iCode *ic)
2559 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2564 /* if the temp was not pushed then */
2565 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2568 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2569 size = AOP_SIZE(IC_LEFT(ic));
2572 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2575 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2579 /*-----------------------------------------------------------------*/
2580 /* unsaverbank - restores the resgister bank from stack */
2581 /*-----------------------------------------------------------------*/
2582 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2584 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2590 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2592 if (options.useXstack) {
2594 r = getFreePtr(ic,&aop,FALSE);
2597 pic16_emitcode("mov","%s,_spx",r->name);
2598 pic16_emitcode("movx","a,@%s",r->name);
2599 pic16_emitcode("mov","psw,a");
2600 pic16_emitcode("dec","%s",r->name);
2603 pic16_emitcode ("pop","psw");
2606 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2607 if (options.useXstack) {
2608 pic16_emitcode("movx","a,@%s",r->name);
2609 //pic16_emitcode("mov","(%s+%d),a",
2610 // regspic16[i].base,8*bank+regspic16[i].offset);
2611 pic16_emitcode("dec","%s",r->name);
2614 pic16_emitcode("pop",""); //"(%s+%d)",
2615 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2618 if (options.useXstack) {
2620 pic16_emitcode("mov","_spx,%s",r->name);
2621 pic16_freeAsmop(NULL,aop,ic,TRUE);
2627 /*-----------------------------------------------------------------*/
2628 /* saverbank - saves an entire register bank on the stack */
2629 /*-----------------------------------------------------------------*/
2630 static void saverbank (int bank, iCode *ic, bool pushPsw)
2632 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2638 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2639 if (options.useXstack) {
2642 r = getFreePtr(ic,&aop,FALSE);
2643 pic16_emitcode("mov","%s,_spx",r->name);
2647 for (i = 0 ; i < pic16_nRegs ;i++) {
2648 if (options.useXstack) {
2649 pic16_emitcode("inc","%s",r->name);
2650 //pic16_emitcode("mov","a,(%s+%d)",
2651 // regspic16[i].base,8*bank+regspic16[i].offset);
2652 pic16_emitcode("movx","@%s,a",r->name);
2654 pic16_emitcode("push","");// "(%s+%d)",
2655 //regspic16[i].base,8*bank+regspic16[i].offset);
2659 if (options.useXstack) {
2660 pic16_emitcode("mov","a,psw");
2661 pic16_emitcode("movx","@%s,a",r->name);
2662 pic16_emitcode("inc","%s",r->name);
2663 pic16_emitcode("mov","_spx,%s",r->name);
2664 pic16_freeAsmop (NULL,aop,ic,TRUE);
2667 pic16_emitcode("push","psw");
2669 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2677 /*-----------------------------------------------------------------*/
2678 /* genCall - generates a call statement */
2679 /*-----------------------------------------------------------------*/
2680 static void genCall (iCode *ic)
2685 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2687 /* if caller saves & we have not saved then */
2691 /* if we are calling a function that is not using
2692 * the same register bank then we need to save the
2693 * destination registers on the stack */
2694 dtype = operandType(IC_LEFT(ic));
2695 if (currFunc && dtype &&
2696 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2697 IFFUNC_ISISR(currFunc->type) &&
2700 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2702 /* if send set is not empty the assign */
2706 /* For the Pic port, there is no data stack.
2707 * So parameters passed to functions are stored
2708 * in registers. (The pCode optimizer will get
2709 * rid of most of these :). */
2711 int psuedoStkPtr=-1;
2712 int firstTimeThruLoop = 1;
2714 _G.sendSet = reverseSet(_G.sendSet);
2716 /* First figure how many parameters are getting passed */
2717 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2718 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2719 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2720 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2723 stackParms = psuedoStkPtr;
2725 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2726 int size, offset = 0;
2728 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2729 size = AOP_SIZE(IC_LEFT(sic));
2732 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2733 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2734 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2736 if(!firstTimeThruLoop) {
2737 /* If this is not the first time we've been through the loop
2738 * then we need to save the parameter in a temporary
2739 * register. The last byte of the last parameter is
2743 --psuedoStkPtr; // sanity check
2746 firstTimeThruLoop=0;
2748 mov2w (AOP(IC_LEFT(sic)), offset);
2751 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2757 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2758 OP_SYMBOL(IC_LEFT(ic))->rname :
2759 OP_SYMBOL(IC_LEFT(ic))->name));
2762 /* if we need assign a result value */
2763 if ((IS_ITEMP(IC_RESULT(ic)) &&
2764 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2765 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2766 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2769 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2772 assignResultValue(IC_RESULT(ic), 1);
2774 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2775 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2777 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2781 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2782 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2783 if(STACK_MODEL_LARGE) {
2785 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2789 /* adjust the stack for parameters if required */
2790 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2792 if (ic->parmBytes) {
2795 if (ic->parmBytes > 3) {
2796 pic16_emitcode("mov","a,%s",spname);
2797 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2798 pic16_emitcode("mov","%s,a",spname);
2800 for ( i = 0 ; i < ic->parmBytes ;i++)
2801 pic16_emitcode("dec","%s",spname);
2804 /* if register bank was saved then pop them */
2806 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2808 /* if we hade saved some registers then unsave them */
2809 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2810 unsaveRegisters (ic);
2813 /*-----------------------------------------------------------------*/
2814 /* genPcall - generates a call by pointer statement */
2815 /*-----------------------------------------------------------------*/
2816 static void genPcall (iCode *ic)
2819 symbol *rlbl = newiTempLabel(NULL);
2822 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2823 /* if caller saves & we have not saved then */
2827 /* if we are calling a function that is not using
2828 the same register bank then we need to save the
2829 destination registers on the stack */
2830 dtype = operandType(IC_LEFT(ic));
2831 if (currFunc && dtype &&
2832 IFFUNC_ISISR(currFunc->type) &&
2833 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2834 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2837 /* push the return address on to the stack */
2838 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2839 pic16_emitcode("push","acc");
2840 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2841 pic16_emitcode("push","acc");
2843 if (options.model == MODEL_FLAT24)
2845 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2846 pic16_emitcode("push","acc");
2849 /* now push the calling address */
2850 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2852 pushSide(IC_LEFT(ic), FPTRSIZE);
2854 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2856 /* if send set is not empty the assign */
2860 for (sic = setFirstItem(_G.sendSet) ; sic ;
2861 sic = setNextItem(_G.sendSet)) {
2862 int size, offset = 0;
2863 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2864 size = AOP_SIZE(IC_LEFT(sic));
2866 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2868 if (strcmp(l,fReturn[offset]))
2869 pic16_emitcode("mov","%s,%s",
2874 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2879 pic16_emitcode("ret","");
2880 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2883 /* if we need assign a result value */
2884 if ((IS_ITEMP(IC_RESULT(ic)) &&
2885 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2886 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2887 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2890 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2893 assignResultValue(IC_RESULT(ic), 1);
2895 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2898 /* adjust the stack for parameters if
2900 if (ic->parmBytes) {
2902 if (ic->parmBytes > 3) {
2903 pic16_emitcode("mov","a,%s",spname);
2904 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2905 pic16_emitcode("mov","%s,a",spname);
2907 for ( i = 0 ; i < ic->parmBytes ;i++)
2908 pic16_emitcode("dec","%s",spname);
2912 /* if register bank was saved then unsave them */
2913 if (currFunc && dtype &&
2914 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2915 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2917 /* if we hade saved some registers then
2920 unsaveRegisters (ic);
2924 /*-----------------------------------------------------------------*/
2925 /* resultRemat - result is rematerializable */
2926 /*-----------------------------------------------------------------*/
2927 static int resultRemat (iCode *ic)
2929 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2930 if (SKIP_IC(ic) || ic->op == IFX)
2933 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2934 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2935 if (sym->remat && !POINTER_SET(ic))
2942 #if defined(__BORLANDC__) || defined(_MSC_VER)
2943 #define STRCASECMP stricmp
2945 #define STRCASECMP strcasecmp
2949 /*-----------------------------------------------------------------*/
2950 /* inExcludeList - return 1 if the string is in exclude Reg list */
2951 /*-----------------------------------------------------------------*/
2952 static bool inExcludeList(char *s)
2954 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2958 if (options.excludeRegs[i] &&
2959 STRCASECMP(options.excludeRegs[i],"none") == 0)
2962 for ( i = 0 ; options.excludeRegs[i]; i++) {
2963 if (options.excludeRegs[i] &&
2964 STRCASECMP(s,options.excludeRegs[i]) == 0)
2971 /*-----------------------------------------------------------------*/
2972 /* genFunction - generated code for function entry */
2973 /*-----------------------------------------------------------------*/
2974 static void genFunction (iCode *ic)
2979 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2981 labelOffset += (max_key+4);
2986 ftype = operandType(IC_LEFT(ic));
2988 if(/*!IFFUNC_ISNAKED(ftype) &&*/ IFFUNC_ISISR(ftype)) {
2989 /* create an absolute section at the interrupt vector:
2990 * that is 0x0008 for interrupt 1, 0x0018 interrupt 2 */
2998 sym = OP_SYMBOL( IC_LEFT(ic));
3000 if(STRCASECMP(interrupts[i]->name, sym->name))break;
3003 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3004 __FILE__, __LINE__, sym->name);
3009 sprintf(asymname, "ivec_%s", sym->name);
3010 asym = newSymbol(asymname, 0);
3011 pic16_emitcode(";","-----------------------------------------");
3012 pic16_emitcode(";"," interrupt vector %d for function %s", ivec, sym->name);
3013 pic16_emitcode(";","-----------------------------------------");
3014 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(moduleName, asym->name));
3015 pic16_emitpcode(POC_GOTO, pic16_popGetWithString( sym->rname ));
3017 pic16_pBlockConvert2Absolute(pb);
3021 /* create the function header */
3022 pic16_emitcode(";","-----------------------------------------");
3023 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
3024 pic16_emitcode(";","-----------------------------------------");
3026 pic16_emitcode("","%s:",sym->rname);
3027 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3032 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3033 if(strcmp(ab->name, sym->name)) {
3034 pic16_pBlockConvert2Absolute(pb);
3041 if(IFFUNC_ISNAKED(ftype)) {
3042 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3046 /* if critical function then turn interrupts off */
3047 if (IFFUNC_ISCRITICAL(ftype))
3048 pic16_emitcode("clr","ea");
3050 /* if this is an interrupt service routine then
3051 * save acc, b, dpl, dph */
3052 if (IFFUNC_ISISR(sym->type)) {
3054 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH */
3055 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3056 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3057 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3058 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3059 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3060 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3061 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3065 /* VR -- this is the old code which clears STATUS register for
3066 * the ISR routine. Why? */
3067 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
3068 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
3069 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3070 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
3073 pic16_pBlockConvert2ISR(pb);
3076 if (!inExcludeList("acc"))
3077 pic16_emitcode ("push","acc");
3078 if (!inExcludeList("b"))
3079 pic16_emitcode ("push","b");
3080 if (!inExcludeList("dpl"))
3081 pic16_emitcode ("push","dpl");
3082 if (!inExcludeList("dph"))
3083 pic16_emitcode ("push","dph");
3086 /* if any registers used */
3087 if (sym->regsUsed) {
3088 /* save the registers used */
3089 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3090 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3091 if (bitVectBitValue(sym->regsUsed,i)) {
3092 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3093 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3094 // pic16_regWithIdx(i)->name);
3096 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3102 /* emit code to setup stack frame if user enabled,
3103 * and function is not main() */
3105 // fprintf(stderr, "function name: %s\n", sym->name);
3106 if(strcmp(sym->name, "main")) {
3107 if(!options.ommitFramePtr || sym->regsUsed) {
3108 /* setup the stack frame */
3109 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3110 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3111 if(STACK_MODEL_LARGE)
3112 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3116 /* if callee-save to be used for this function
3117 * then save the registers being used in this function */
3118 if (IFFUNC_CALLEESAVES(sym->type)) {
3121 // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
3123 /* if any registers used */
3124 if (sym->regsUsed) {
3125 /* save the registers used */
3126 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3127 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3128 if (bitVectBitValue(sym->regsUsed,i)) {
3129 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3130 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3131 // pic16_regWithIdx(i)->name);
3133 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3134 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3135 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3136 // &pic16_pc_postdec1, 0));
3147 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3149 if (options.useXstack) {
3150 pic16_emitcode("mov","r0,%s",spname);
3151 pic16_emitcode("mov","a,_bp");
3152 pic16_emitcode("movx","@r0,a");
3153 pic16_emitcode("inc","%s",spname);
3155 /* set up the stack */
3156 pic16_emitcode ("push","_bp"); /* save the callers stack */
3158 pic16_emitcode ("mov","_bp,%s",spname);
3161 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3163 /* adjust the stack for the function */
3168 werror(W_STACK_OVERFLOW,sym->name);
3170 if (i > 3 && sym->recvSize < 4) {
3171 pic16_emitcode ("mov","a,sp");
3172 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3173 pic16_emitcode ("mov","sp,a");
3176 pic16_emitcode("inc","sp");
3180 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3182 pic16_emitcode ("mov","a,_spx");
3183 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3184 pic16_emitcode ("mov","_spx,a");
3189 /*-----------------------------------------------------------------*/
3190 /* genEndFunction - generates epilogue for functions */
3191 /*-----------------------------------------------------------------*/
3192 static void genEndFunction (iCode *ic)
3194 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3198 if(IFFUNC_ISNAKED(sym->type)) {
3199 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3204 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3206 pic16_emitcode ("mov","%s,_bp",spname);
3210 /* if use external stack but some variables were
3211 added to the local stack then decrement the
3213 if (options.useXstack && sym->stack) {
3214 pic16_emitcode("mov","a,sp");
3215 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3216 pic16_emitcode("mov","sp,a");
3221 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3222 if (options.useXstack) {
3223 pic16_emitcode("mov","r0,%s",spname);
3224 pic16_emitcode("movx","a,@r0");
3225 pic16_emitcode("mov","_bp,a");
3226 pic16_emitcode("dec","%s",spname);
3230 pic16_emitcode ("pop","_bp");
3235 /* restore the register bank */
3236 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3237 pic16_emitcode ("pop","psw");
3239 if (IFFUNC_ISISR(sym->type)) {
3241 /* now we need to restore the registers */
3243 /* if any registers used */
3244 if (sym->regsUsed) {
3247 /* restore registers used */
3248 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3249 for ( i = sym->regsUsed->size; i >= 0; i--) {
3250 if (bitVectBitValue(sym->regsUsed,i)) {
3251 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3252 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3253 // pic16_regWithIdx(i)->name);
3255 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3257 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3262 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3263 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3264 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3265 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3266 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3267 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3268 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3271 /* if debug then send end of function */
3272 /* if (options.debug && currFunc) */
3275 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3276 FileBaseName(ic->filename),currFunc->lastLine,
3277 ic->level,ic->block);
3278 if (IS_STATIC(currFunc->etype))
3279 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3281 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3286 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3287 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3288 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3289 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3290 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3293 pic16_emitpcodeNULLop(POC_RETFIE);
3296 if (IFFUNC_ISCRITICAL(sym->type))
3297 pic16_emitcode("setb","ea");
3299 /* if any registers used */
3300 if (sym->regsUsed) {
3302 /* save the registers used */
3303 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3304 for ( i = sym->regsUsed->size; i >= 0; i--) {
3305 if (bitVectBitValue(sym->regsUsed,i)) {
3306 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3307 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3308 // pic16_regWithIdx(i)->name);
3310 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3312 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3318 /* if debug then send end of function */
3321 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3322 FileBaseName(ic->filename),currFunc->lastLine,
3323 ic->level,ic->block);
3324 if (IS_STATIC(currFunc->etype))
3325 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3327 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3331 /* insert code to restore stack frame, if user enabled it
3332 * and function is not main() */
3334 if(strcmp(sym->name, "main")) {
3335 if(!options.ommitFramePtr || sym->regsUsed) {
3336 /* restore stack frame */
3337 if(STACK_MODEL_LARGE)
3338 pic16_emitpcode(POC_MOVFF,
3339 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3340 pic16_emitpcode(POC_MOVFF,
3341 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3345 pic16_emitcode ("return","");
3346 pic16_emitpcodeNULLop(POC_RETURN);
3348 /* Mark the end of a function */
3349 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3355 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3357 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3359 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3360 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3361 pic16_emitpcode(POC_MOVWF, dest);
3363 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3364 pic16_popGet(AOP(op), offset), dest));
3368 /*-----------------------------------------------------------------*/
3369 /* genRet - generate code for return statement */
3370 /*-----------------------------------------------------------------*/
3371 static void genRet (iCode *ic)
3376 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3377 /* if we have no return value then
3378 * just generate the "ret" */
3383 /* we have something to return then
3384 * move the return value into place */
3385 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3386 size = AOP_SIZE(IC_LEFT(ic));
3390 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3391 // pic16_emitpcode(POC_MOVFF,
3392 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3395 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3396 // pic16_emitpcode(POC_MOVFF,
3397 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3400 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3401 // pic16_emitpcode(POC_MOVFF,
3402 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3405 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0));
3407 // pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg));
3408 // pic16_emitpcode(POC_MOVFF,
3409 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3412 /* >32-bits, setup stack and FSR0 */
3414 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3415 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3417 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3419 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3424 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3425 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3427 if(STACK_MODEL_LARGE) {
3428 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3429 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3431 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3436 /* old code, left here for reference -- VR */
3440 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3442 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3443 pic16_emitpcomment("push %s",l);
3446 DEBUGpic16_emitcode(";", "%d", __LINE__);
3447 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3448 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3450 if (strcmp(fReturn[offset],l)) {
3451 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3452 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3453 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3455 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3459 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3469 if (strcmp(fReturn[pushed],"a"))
3470 pic16_emitcode("pop",fReturn[pushed]);
3472 pic16_emitcode("pop","acc");
3478 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3481 /* generate a jump to the return label
3482 * if the next is not the return statement */
3483 if (!(ic->next && ic->next->op == LABEL
3484 && IC_LABEL(ic->next) == returnLabel)) {
3486 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3487 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3491 /*-----------------------------------------------------------------*/
3492 /* genLabel - generates a label */
3493 /*-----------------------------------------------------------------*/
3494 static void genLabel (iCode *ic)
3496 /* special case never generate */
3497 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3498 if (IC_LABEL(ic) == entryLabel)
3501 pic16_emitpLabel(IC_LABEL(ic)->key);
3502 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3505 /*-----------------------------------------------------------------*/
3506 /* genGoto - generates a goto */
3507 /*-----------------------------------------------------------------*/
3509 static void genGoto (iCode *ic)
3511 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3512 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3516 /*-----------------------------------------------------------------*/
3517 /* genMultbits :- multiplication of bits */
3518 /*-----------------------------------------------------------------*/
3519 static void genMultbits (operand *left,
3523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3525 if(!pic16_sameRegs(AOP(result),AOP(right)))
3526 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3528 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3529 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3530 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3535 /*-----------------------------------------------------------------*/
3536 /* genMultOneByte : 8 bit multiplication & division */
3537 /*-----------------------------------------------------------------*/
3538 static void genMultOneByte (operand *left,
3542 sym_link *opetype = operandType(result);
3547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3548 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3549 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3551 /* (if two literals, the value is computed before) */
3552 /* if one literal, literal on the right */
3553 if (AOP_TYPE(left) == AOP_LIT){
3559 size = AOP_SIZE(result);
3562 if (AOP_TYPE(right) == AOP_LIT){
3563 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3564 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3565 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3566 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3568 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3569 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3570 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3571 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3573 pic16_genMult8X8_8 (left, right,result);
3574 } else { // (size > 1)
3576 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3577 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3578 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3579 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3581 if (SPEC_USIGN(opetype)){
3582 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3583 pic16_genUMult8X8_16 (left, right, result, NULL);
3586 /* for filling the MSBs */
3587 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3588 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3592 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3594 pic16_emitcode("mov","a,b");
3596 /* adjust the MSB if left or right neg */
3598 /* if one literal */
3599 if (AOP_TYPE(right) == AOP_LIT){
3600 pic16_emitcode("multiply ","right is a lit");
3601 /* AND literal negative */
3602 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3603 /* adjust MSB (c==0 after mul) */
3604 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3608 pic16_genSMult8X8_16 (left, right, result, NULL);
3612 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3614 pic16_emitcode("rlc","a");
3615 pic16_emitcode("subb","a,acc");
3623 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3624 //pic16_aopPut(AOP(result),"a",offset++);
3628 /*-----------------------------------------------------------------*/
3629 /* genMult - generates code for multiplication */
3630 /*-----------------------------------------------------------------*/
3631 static void genMult (iCode *ic)
3633 operand *left = IC_LEFT(ic);
3634 operand *right = IC_RIGHT(ic);
3635 operand *result= IC_RESULT(ic);
3637 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3638 /* assign the amsops */
3639 pic16_aopOp (left,ic,FALSE);
3640 pic16_aopOp (right,ic,FALSE);
3641 pic16_aopOp (result,ic,TRUE);
3643 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3645 /* special cases first */
3647 if (AOP_TYPE(left) == AOP_CRY &&
3648 AOP_TYPE(right)== AOP_CRY) {
3649 genMultbits(left,right,result);
3653 /* if both are of size == 1 */
3654 if (AOP_SIZE(left) == 1 &&
3655 AOP_SIZE(right) == 1 ) {
3656 genMultOneByte(left,right,result);
3660 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3662 /* should have been converted to function call */
3666 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3667 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3668 pic16_freeAsmop(result,NULL,ic,TRUE);
3671 /*-----------------------------------------------------------------*/
3672 /* genDivbits :- division of bits */
3673 /*-----------------------------------------------------------------*/
3674 static void genDivbits (operand *left,
3681 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3682 /* the result must be bit */
3683 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3684 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3688 pic16_emitcode("div","ab");
3689 pic16_emitcode("rrc","a");
3690 pic16_aopPut(AOP(result),"c",0);
3693 /*-----------------------------------------------------------------*/
3694 /* genDivOneByte : 8 bit division */
3695 /*-----------------------------------------------------------------*/
3696 static void genDivOneByte (operand *left,
3700 sym_link *opetype = operandType(result);
3705 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3706 size = AOP_SIZE(result) - 1;
3708 /* signed or unsigned */
3709 if (SPEC_USIGN(opetype)) {
3710 /* unsigned is easy */
3711 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3712 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3714 pic16_emitcode("div","ab");
3715 pic16_aopPut(AOP(result),"a",0);
3717 pic16_aopPut(AOP(result),zero,offset++);
3721 /* signed is a little bit more difficult */
3723 /* save the signs of the operands */
3724 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3726 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3727 pic16_emitcode("push","acc"); /* save it on the stack */
3729 /* now sign adjust for both left & right */
3730 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3732 lbl = newiTempLabel(NULL);
3733 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3734 pic16_emitcode("cpl","a");
3735 pic16_emitcode("inc","a");
3736 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3737 pic16_emitcode("mov","b,a");
3739 /* sign adjust left side */
3740 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3743 lbl = newiTempLabel(NULL);
3744 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3745 pic16_emitcode("cpl","a");
3746 pic16_emitcode("inc","a");
3747 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3749 /* now the division */
3750 pic16_emitcode("div","ab");
3751 /* we are interested in the lower order
3753 pic16_emitcode("mov","b,a");
3754 lbl = newiTempLabel(NULL);
3755 pic16_emitcode("pop","acc");
3756 /* if there was an over flow we don't
3757 adjust the sign of the result */
3758 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3759 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3761 pic16_emitcode("clr","a");
3762 pic16_emitcode("subb","a,b");
3763 pic16_emitcode("mov","b,a");
3764 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3766 /* now we are done */
3767 pic16_aopPut(AOP(result),"b",0);
3769 pic16_emitcode("mov","c,b.7");
3770 pic16_emitcode("subb","a,acc");
3773 pic16_aopPut(AOP(result),"a",offset++);
3777 /*-----------------------------------------------------------------*/
3778 /* genDiv - generates code for division */
3779 /*-----------------------------------------------------------------*/
3780 static void genDiv (iCode *ic)
3782 operand *left = IC_LEFT(ic);
3783 operand *right = IC_RIGHT(ic);
3784 operand *result= IC_RESULT(ic);
3786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3787 /* assign the amsops */
3788 pic16_aopOp (left,ic,FALSE);
3789 pic16_aopOp (right,ic,FALSE);
3790 pic16_aopOp (result,ic,TRUE);
3792 /* special cases first */
3794 if (AOP_TYPE(left) == AOP_CRY &&
3795 AOP_TYPE(right)== AOP_CRY) {
3796 genDivbits(left,right,result);
3800 /* if both are of size == 1 */
3801 if (AOP_SIZE(left) == 1 &&
3802 AOP_SIZE(right) == 1 ) {
3803 genDivOneByte(left,right,result);
3807 /* should have been converted to function call */
3810 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3811 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3812 pic16_freeAsmop(result,NULL,ic,TRUE);
3815 /*-----------------------------------------------------------------*/
3816 /* genModbits :- modulus of bits */
3817 /*-----------------------------------------------------------------*/
3818 static void genModbits (operand *left,
3825 /* the result must be bit */
3826 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3827 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3831 pic16_emitcode("div","ab");
3832 pic16_emitcode("mov","a,b");
3833 pic16_emitcode("rrc","a");
3834 pic16_aopPut(AOP(result),"c",0);
3837 /*-----------------------------------------------------------------*/
3838 /* genModOneByte : 8 bit modulus */
3839 /*-----------------------------------------------------------------*/
3840 static void genModOneByte (operand *left,
3844 sym_link *opetype = operandType(result);
3848 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3849 /* signed or unsigned */
3850 if (SPEC_USIGN(opetype)) {
3851 /* unsigned is easy */
3852 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3853 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3855 pic16_emitcode("div","ab");
3856 pic16_aopPut(AOP(result),"b",0);
3860 /* signed is a little bit more difficult */
3862 /* save the signs of the operands */
3863 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3866 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3867 pic16_emitcode("push","acc"); /* save it on the stack */
3869 /* now sign adjust for both left & right */
3870 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3873 lbl = newiTempLabel(NULL);
3874 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3875 pic16_emitcode("cpl","a");
3876 pic16_emitcode("inc","a");
3877 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3878 pic16_emitcode("mov","b,a");
3880 /* sign adjust left side */
3881 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3884 lbl = newiTempLabel(NULL);
3885 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3886 pic16_emitcode("cpl","a");
3887 pic16_emitcode("inc","a");
3888 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3890 /* now the multiplication */
3891 pic16_emitcode("div","ab");
3892 /* we are interested in the lower order
3894 lbl = newiTempLabel(NULL);
3895 pic16_emitcode("pop","acc");
3896 /* if there was an over flow we don't
3897 adjust the sign of the result */
3898 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3899 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3901 pic16_emitcode("clr","a");
3902 pic16_emitcode("subb","a,b");
3903 pic16_emitcode("mov","b,a");
3904 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3906 /* now we are done */
3907 pic16_aopPut(AOP(result),"b",0);
3911 /*-----------------------------------------------------------------*/
3912 /* genMod - generates code for division */
3913 /*-----------------------------------------------------------------*/
3914 static void genMod (iCode *ic)
3916 operand *left = IC_LEFT(ic);
3917 operand *right = IC_RIGHT(ic);
3918 operand *result= IC_RESULT(ic);
3920 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3921 /* assign the amsops */
3922 pic16_aopOp (left,ic,FALSE);
3923 pic16_aopOp (right,ic,FALSE);
3924 pic16_aopOp (result,ic,TRUE);
3926 /* special cases first */
3928 if (AOP_TYPE(left) == AOP_CRY &&
3929 AOP_TYPE(right)== AOP_CRY) {
3930 genModbits(left,right,result);
3934 /* if both are of size == 1 */
3935 if (AOP_SIZE(left) == 1 &&
3936 AOP_SIZE(right) == 1 ) {
3937 genModOneByte(left,right,result);
3941 /* should have been converted to function call */
3945 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3946 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3947 pic16_freeAsmop(result,NULL,ic,TRUE);
3950 /*-----------------------------------------------------------------*/
3951 /* genIfxJump :- will create a jump depending on the ifx */
3952 /*-----------------------------------------------------------------*/
3954 note: May need to add parameter to indicate when a variable is in bit space.
3956 static void genIfxJump (iCode *ic, char *jval)
3959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3960 /* if true label then we jump if condition
3962 if ( IC_TRUE(ic) ) {
3964 if(strcmp(jval,"a") == 0)
3966 else if (strcmp(jval,"c") == 0)
3969 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3970 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3973 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3974 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3978 /* false label is present */
3979 if(strcmp(jval,"a") == 0)
3981 else if (strcmp(jval,"c") == 0)
3984 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3985 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3988 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3989 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3994 /* mark the icode as generated */
3998 /*-----------------------------------------------------------------*/
4000 /*-----------------------------------------------------------------*/
4001 static void genSkip(iCode *ifx,int status_bit)
4003 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4007 if ( IC_TRUE(ifx) ) {
4008 switch(status_bit) {
4023 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4024 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4028 switch(status_bit) {
4042 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4043 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4049 /*-----------------------------------------------------------------*/
4051 /*-----------------------------------------------------------------*/
4052 static void genSkipc(resolvedIfx *rifx)
4062 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4063 rifx->generated = 1;
4066 /*-----------------------------------------------------------------*/
4068 /*-----------------------------------------------------------------*/
4069 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4074 if( (rifx->condition ^ invert_condition) & 1)
4079 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4080 rifx->generated = 1;
4084 /*-----------------------------------------------------------------*/
4086 /*-----------------------------------------------------------------*/
4087 static void genSkipz(iCode *ifx, int condition)
4098 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4100 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4103 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4105 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4110 /*-----------------------------------------------------------------*/
4112 /*-----------------------------------------------------------------*/
4113 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4119 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4121 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4124 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4125 rifx->generated = 1;
4129 /*-----------------------------------------------------------------*/
4130 /* genChkZeroes :- greater or less than comparison */
4131 /* For each byte in a literal that is zero, inclusive or the */
4132 /* the corresponding byte in the operand with W */
4133 /* returns true if any of the bytes are zero */
4134 /*-----------------------------------------------------------------*/
4135 static int genChkZeroes(operand *op, int lit, int size)
4142 i = (lit >> (size*8)) & 0xff;
4146 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4148 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4157 /*-----------------------------------------------------------------*/
4158 /* genCmp :- greater or less than comparison */
4159 /*-----------------------------------------------------------------*/
4160 static void genCmp (operand *left,operand *right,
4161 operand *result, iCode *ifx, int sign)
4163 int size; //, offset = 0 ;
4164 unsigned long lit = 0L,i = 0;
4165 resolvedIfx rFalseIfx;
4166 // resolvedIfx rTrueIfx;
4168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4171 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4172 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4176 resolveIfx(&rFalseIfx,ifx);
4177 truelbl = newiTempLabel(NULL);
4178 size = max(AOP_SIZE(left),AOP_SIZE(right));
4180 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4184 /* if literal is on the right then swap with left */
4185 if ((AOP_TYPE(right) == AOP_LIT)) {
4186 operand *tmp = right ;
4187 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4188 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4191 lit = (lit - 1) & mask;
4194 rFalseIfx.condition ^= 1;
4197 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4198 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4202 //if(IC_TRUE(ifx) == NULL)
4203 /* if left & right are bit variables */
4204 if (AOP_TYPE(left) == AOP_CRY &&
4205 AOP_TYPE(right) == AOP_CRY ) {
4206 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4207 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4209 /* subtract right from left if at the
4210 end the carry flag is set then we know that
4211 left is greater than right */
4215 symbol *lbl = newiTempLabel(NULL);
4218 if(AOP_TYPE(right) == AOP_LIT) {
4220 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4222 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4229 genSkipCond(&rFalseIfx,left,size-1,7);
4231 /* no need to compare to 0...*/
4232 /* NOTE: this is a de-generate compare that most certainly
4233 * creates some dead code. */
4234 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4236 if(ifx) ifx->generated = 1;
4243 //i = (lit >> (size*8)) & 0xff;
4244 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4246 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4248 i = ((0-lit) & 0xff);
4251 /* lit is 0x7f, all signed chars are less than
4252 * this except for 0x7f itself */
4253 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4254 genSkipz2(&rFalseIfx,0);
4256 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4257 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4258 genSkipc(&rFalseIfx);
4263 genSkipz2(&rFalseIfx,1);
4265 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4266 genSkipc(&rFalseIfx);
4270 if(ifx) ifx->generated = 1;
4274 /* chars are out of the way. now do ints and longs */
4277 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4284 genSkipCond(&rFalseIfx,left,size,7);
4285 if(ifx) ifx->generated = 1;
4290 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4292 //rFalseIfx.condition ^= 1;
4293 //genSkipCond(&rFalseIfx,left,size,7);
4294 //rFalseIfx.condition ^= 1;
4296 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4297 if(rFalseIfx.condition)
4298 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4300 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4302 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4303 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4304 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4307 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4309 if(rFalseIfx.condition) {
4311 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4317 genSkipc(&rFalseIfx);
4318 pic16_emitpLabel(truelbl->key);
4319 if(ifx) ifx->generated = 1;
4326 if( (lit & 0xff) == 0) {
4327 /* lower byte is zero */
4328 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4329 i = ((lit >> 8) & 0xff) ^0x80;
4330 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4331 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4332 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4333 genSkipc(&rFalseIfx);
4336 if(ifx) ifx->generated = 1;
4341 /* Special cases for signed longs */
4342 if( (lit & 0xffffff) == 0) {
4343 /* lower byte is zero */
4344 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4345 i = ((lit >> 8*3) & 0xff) ^0x80;
4346 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4347 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4348 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4349 genSkipc(&rFalseIfx);
4352 if(ifx) ifx->generated = 1;
4360 if(lit & (0x80 << (size*8))) {
4361 /* lit is negative */
4362 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4364 //genSkipCond(&rFalseIfx,left,size,7);
4366 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4368 if(rFalseIfx.condition)
4369 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4371 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4375 /* lit is positive */
4376 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4377 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4378 if(rFalseIfx.condition)
4379 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4381 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4386 This works, but is only good for ints.
4387 It also requires a "known zero" register.
4388 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4389 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4390 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4391 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4392 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4393 genSkipc(&rFalseIfx);
4395 pic16_emitpLabel(truelbl->key);
4396 if(ifx) ifx->generated = 1;
4400 /* There are no more special cases, so perform a general compare */
4402 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4403 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4407 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4409 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4411 //rFalseIfx.condition ^= 1;
4412 genSkipc(&rFalseIfx);
4414 pic16_emitpLabel(truelbl->key);
4416 if(ifx) ifx->generated = 1;
4423 /* sign is out of the way. So now do an unsigned compare */
4424 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4427 /* General case - compare to an unsigned literal on the right.*/
4429 i = (lit >> (size*8)) & 0xff;
4430 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4431 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4433 i = (lit >> (size*8)) & 0xff;
4436 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4438 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4440 /* this byte of the lit is zero,
4441 *if it's not the last then OR in the variable */
4443 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4448 pic16_emitpLabel(lbl->key);
4449 //if(emitFinalCheck)
4450 genSkipc(&rFalseIfx);
4452 pic16_emitpLabel(truelbl->key);
4454 if(ifx) ifx->generated = 1;
4461 if(AOP_TYPE(left) == AOP_LIT) {
4462 //symbol *lbl = newiTempLabel(NULL);
4464 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4467 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4470 if((lit == 0) && (sign == 0)){
4473 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4475 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4477 genSkipz2(&rFalseIfx,0);
4478 if(ifx) ifx->generated = 1;
4485 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4486 /* degenerate compare can never be true */
4487 if(rFalseIfx.condition == 0)
4488 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4490 if(ifx) ifx->generated = 1;
4495 /* signed comparisons to a literal byte */
4497 int lp1 = (lit+1) & 0xff;
4499 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4502 rFalseIfx.condition ^= 1;
4503 genSkipCond(&rFalseIfx,right,0,7);
4506 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4507 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4508 genSkipz2(&rFalseIfx,1);
4511 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4512 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4513 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4514 rFalseIfx.condition ^= 1;
4515 genSkipc(&rFalseIfx);
4519 /* unsigned comparisons to a literal byte */
4521 switch(lit & 0xff ) {
4523 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4524 genSkipz2(&rFalseIfx,0);
4527 rFalseIfx.condition ^= 1;
4528 genSkipCond(&rFalseIfx,right,0,7);
4532 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4533 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4534 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4535 rFalseIfx.condition ^= 1;
4536 if (AOP_TYPE(result) == AOP_CRY)
4537 genSkipc(&rFalseIfx);
4539 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4540 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4546 if(ifx) ifx->generated = 1;
4552 /* Size is greater than 1 */
4560 /* this means lit = 0xffffffff, or -1 */
4563 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4564 rFalseIfx.condition ^= 1;
4565 genSkipCond(&rFalseIfx,right,size,7);
4566 if(ifx) ifx->generated = 1;
4573 if(rFalseIfx.condition) {
4574 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4575 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4578 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4580 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4584 if(rFalseIfx.condition) {
4585 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4586 pic16_emitpLabel(truelbl->key);
4588 rFalseIfx.condition ^= 1;
4589 genSkipCond(&rFalseIfx,right,s,7);
4592 if(ifx) ifx->generated = 1;
4596 if((size == 1) && (0 == (lp1&0xff))) {
4597 /* lower byte of signed word is zero */
4598 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4599 i = ((lp1 >> 8) & 0xff) ^0x80;
4600 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4601 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4602 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4603 rFalseIfx.condition ^= 1;
4604 genSkipc(&rFalseIfx);
4607 if(ifx) ifx->generated = 1;
4611 if(lit & (0x80 << (size*8))) {
4612 /* Lit is less than zero */
4613 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4614 //rFalseIfx.condition ^= 1;
4615 //genSkipCond(&rFalseIfx,left,size,7);
4616 //rFalseIfx.condition ^= 1;
4617 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4618 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4620 if(rFalseIfx.condition)
4621 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4623 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4627 /* Lit is greater than or equal to zero */
4628 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4629 //rFalseIfx.condition ^= 1;
4630 //genSkipCond(&rFalseIfx,right,size,7);
4631 //rFalseIfx.condition ^= 1;
4633 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4634 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4636 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4637 if(rFalseIfx.condition)
4638 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4640 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4645 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4646 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4650 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4652 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4654 rFalseIfx.condition ^= 1;
4655 //rFalseIfx.condition = 1;
4656 genSkipc(&rFalseIfx);
4658 pic16_emitpLabel(truelbl->key);
4660 if(ifx) ifx->generated = 1;
4665 /* compare word or long to an unsigned literal on the right.*/
4670 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4673 break; /* handled above */
4676 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4678 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4679 genSkipz2(&rFalseIfx,0);
4683 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4685 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4688 if(rFalseIfx.condition)
4689 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4691 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4694 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4695 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4697 rFalseIfx.condition ^= 1;
4698 genSkipc(&rFalseIfx);
4701 pic16_emitpLabel(truelbl->key);
4703 if(ifx) ifx->generated = 1;
4709 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4710 i = (lit >> (size*8)) & 0xff;
4712 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4713 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4716 i = (lit >> (size*8)) & 0xff;
4719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4721 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4723 /* this byte of the lit is zero,
4724 *if it's not the last then OR in the variable */
4726 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4731 pic16_emitpLabel(lbl->key);
4733 rFalseIfx.condition ^= 1;
4734 genSkipc(&rFalseIfx);
4738 pic16_emitpLabel(truelbl->key);
4739 if(ifx) ifx->generated = 1;
4743 /* Compare two variables */
4745 DEBUGpic16_emitcode(";sign","%d",sign);
4749 /* Sigh. thus sucks... */
4751 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4752 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4753 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4754 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4755 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4756 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4758 /* Signed char comparison */
4759 /* Special thanks to Nikolai Golovchenko for this snippet */
4760 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4761 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4762 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4763 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4764 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4765 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4767 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4768 genSkipc(&rFalseIfx);
4770 if(ifx) ifx->generated = 1;
4776 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4777 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4781 /* The rest of the bytes of a multi-byte compare */
4785 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4788 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4789 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4794 pic16_emitpLabel(lbl->key);
4796 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4797 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4798 (AOP_TYPE(result) == AOP_REG)) {
4799 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4800 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4802 genSkipc(&rFalseIfx);
4804 //genSkipc(&rFalseIfx);
4805 if(ifx) ifx->generated = 1;
4812 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4813 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4814 pic16_outBitC(result);
4816 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4817 /* if the result is used in the next
4818 ifx conditional branch then generate
4819 code a little differently */
4821 genIfxJump (ifx,"c");
4823 pic16_outBitC(result);
4824 /* leave the result in acc */
4829 /*-----------------------------------------------------------------*/
4830 /* genCmpGt :- greater than comparison */
4831 /*-----------------------------------------------------------------*/
4832 static void genCmpGt (iCode *ic, iCode *ifx)
4834 operand *left, *right, *result;
4835 sym_link *letype , *retype;
4838 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4840 right= IC_RIGHT(ic);
4841 result = IC_RESULT(ic);
4843 letype = getSpec(operandType(left));
4844 retype =getSpec(operandType(right));
4845 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4846 /* assign the amsops */
4847 pic16_aopOp (left,ic,FALSE);
4848 pic16_aopOp (right,ic,FALSE);
4849 pic16_aopOp (result,ic,TRUE);
4851 genCmp(right, left, result, ifx, sign);
4853 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4854 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4855 pic16_freeAsmop(result,NULL,ic,TRUE);
4858 /*-----------------------------------------------------------------*/
4859 /* genCmpLt - less than comparisons */
4860 /*-----------------------------------------------------------------*/
4861 static void genCmpLt (iCode *ic, iCode *ifx)
4863 operand *left, *right, *result;
4864 sym_link *letype , *retype;
4867 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4869 right= IC_RIGHT(ic);
4870 result = IC_RESULT(ic);
4872 letype = getSpec(operandType(left));
4873 retype =getSpec(operandType(right));
4874 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4876 /* assign the amsops */
4877 pic16_aopOp (left,ic,FALSE);
4878 pic16_aopOp (right,ic,FALSE);
4879 pic16_aopOp (result,ic,TRUE);
4881 genCmp(left, right, result, ifx, sign);
4883 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4884 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4885 pic16_freeAsmop(result,NULL,ic,TRUE);
4888 /*-----------------------------------------------------------------*/
4889 /* genc16bit2lit - compare a 16 bit value to a literal */
4890 /*-----------------------------------------------------------------*/
4891 static void genc16bit2lit(operand *op, int lit, int offset)
4895 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4896 if( (lit&0xff) == 0)
4901 switch( BYTEofLONG(lit,i)) {
4903 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4906 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4909 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4912 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4913 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4918 switch( BYTEofLONG(lit,i)) {
4920 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4924 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4928 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4931 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4933 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4939 /*-----------------------------------------------------------------*/
4940 /* gencjneshort - compare and jump if not equal */
4941 /*-----------------------------------------------------------------*/
4942 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4944 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4946 int res_offset = 0; /* the result may be a different size then left or right */
4947 int res_size = AOP_SIZE(result);
4951 unsigned long lit = 0L;
4952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4953 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4955 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4956 resolveIfx(&rIfx,ifx);
4957 lbl = newiTempLabel(NULL);
4960 /* if the left side is a literal or
4961 if the right is in a pointer register and left
4963 if ((AOP_TYPE(left) == AOP_LIT) ||
4964 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4969 if(AOP_TYPE(right) == AOP_LIT)
4970 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4972 /* if the right side is a literal then anything goes */
4973 if (AOP_TYPE(right) == AOP_LIT &&
4974 AOP_TYPE(left) != AOP_DIR ) {
4977 genc16bit2lit(left, lit, 0);
4979 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4984 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4985 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4987 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4991 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4993 if(res_offset < res_size-1)
5001 /* if the right side is in a register or in direct space or
5002 if the left is a pointer register & right is not */
5003 else if (AOP_TYPE(right) == AOP_REG ||
5004 AOP_TYPE(right) == AOP_DIR ||
5005 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5006 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5007 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5008 int lbl_key = lbl->key;
5011 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5012 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5014 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5015 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5016 __FUNCTION__,__LINE__);
5020 /* switch(size) { */
5022 /* genc16bit2lit(left, lit, 0); */
5024 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5029 if((AOP_TYPE(left) == AOP_DIR) &&
5030 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5032 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5033 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5035 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5037 switch (lit & 0xff) {
5039 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5042 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5043 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5044 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5048 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5049 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5050 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5051 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5055 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5056 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5061 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5064 if(AOP_TYPE(result) == AOP_CRY) {
5065 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5070 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5072 /* fix me. probably need to check result size too */
5073 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5078 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5079 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5086 if(res_offset < res_size-1)
5091 } else if(AOP_TYPE(right) == AOP_REG &&
5092 AOP_TYPE(left) != AOP_DIR){
5095 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5096 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5097 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5102 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5104 if(res_offset < res_size-1)
5109 /* right is a pointer reg need both a & b */
5111 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5113 pic16_emitcode("mov","b,%s",l);
5114 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5115 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5120 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5122 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5124 pic16_emitpLabel(lbl->key);
5126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5133 /*-----------------------------------------------------------------*/
5134 /* gencjne - compare and jump if not equal */
5135 /*-----------------------------------------------------------------*/
5136 static void gencjne(operand *left, operand *right, iCode *ifx)
5138 symbol *tlbl = newiTempLabel(NULL);
5140 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 gencjneshort(left, right, lbl);
5143 pic16_emitcode("mov","a,%s",one);
5144 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5145 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5146 pic16_emitcode("clr","a");
5147 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5149 pic16_emitpLabel(lbl->key);
5150 pic16_emitpLabel(tlbl->key);
5155 /*-----------------------------------------------------------------*/
5156 /* genCmpEq - generates code for equal to */
5157 /*-----------------------------------------------------------------*/
5158 static void genCmpEq (iCode *ic, iCode *ifx)
5160 operand *left, *right, *result;
5161 unsigned long lit = 0L;
5163 symbol *falselbl = newiTempLabel(NULL);
5166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5169 DEBUGpic16_emitcode ("; ifx is non-null","");
5171 DEBUGpic16_emitcode ("; ifx is null","");
5173 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5174 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5175 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5177 size = max(AOP_SIZE(left),AOP_SIZE(right));
5179 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5181 /* if literal, literal on the right or
5182 if the right is in a pointer register and left
5184 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5185 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5186 operand *tmp = right ;
5192 if(ifx && !AOP_SIZE(result)){
5194 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5195 /* if they are both bit variables */
5196 if (AOP_TYPE(left) == AOP_CRY &&
5197 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5198 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5199 if(AOP_TYPE(right) == AOP_LIT){
5200 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5202 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5203 pic16_emitcode("cpl","c");
5204 } else if(lit == 1L) {
5205 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5207 pic16_emitcode("clr","c");
5209 /* AOP_TYPE(right) == AOP_CRY */
5211 symbol *lbl = newiTempLabel(NULL);
5212 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5213 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5214 pic16_emitcode("cpl","c");
5215 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5217 /* if true label then we jump if condition
5219 tlbl = newiTempLabel(NULL);
5220 if ( IC_TRUE(ifx) ) {
5221 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5222 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5224 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5225 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5227 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5230 /* left and right are both bit variables, result is carry */
5233 resolveIfx(&rIfx,ifx);
5235 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5236 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5237 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5238 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5243 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5245 /* They're not both bit variables. Is the right a literal? */
5246 if(AOP_TYPE(right) == AOP_LIT) {
5247 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5252 switch(lit & 0xff) {
5254 if ( IC_TRUE(ifx) ) {
5255 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5257 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5259 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5260 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5264 if ( IC_TRUE(ifx) ) {
5265 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5267 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5269 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5270 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5274 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5276 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5281 /* end of size == 1 */
5285 genc16bit2lit(left,lit,offset);
5288 /* end of size == 2 */
5293 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5294 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5295 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5296 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5299 /* search for patterns that can be optimized */
5301 genc16bit2lit(left,lit,0);
5305 emitSKPZ; // if hi word unequal
5307 emitSKPNZ; // if hi word equal
5309 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5310 genc16bit2lit(left,lit,2);
5313 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5314 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5318 pic16_emitpLabel(falselbl->key);
5327 } else if(AOP_TYPE(right) == AOP_CRY ) {
5328 /* we know the left is not a bit, but that the right is */
5329 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5330 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5331 pic16_popGet(AOP(right),offset));
5332 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5334 /* if the two are equal, then W will be 0 and the Z bit is set
5335 * we could test Z now, or go ahead and check the high order bytes if
5336 * the variable we're comparing is larger than a byte. */
5339 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5341 if ( IC_TRUE(ifx) ) {
5343 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5344 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5347 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5348 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5352 /* They're both variables that are larger than bits */
5355 tlbl = newiTempLabel(NULL);
5358 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5359 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5361 if ( IC_TRUE(ifx) ) {
5365 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5367 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5368 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5372 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5375 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5376 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5381 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5383 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5384 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5388 if(s>1 && IC_TRUE(ifx)) {
5389 pic16_emitpLabel(tlbl->key);
5390 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5394 /* mark the icode as generated */
5399 /* if they are both bit variables */
5400 if (AOP_TYPE(left) == AOP_CRY &&
5401 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5402 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5403 if(AOP_TYPE(right) == AOP_LIT){
5404 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5406 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5407 pic16_emitcode("cpl","c");
5408 } else if(lit == 1L) {
5409 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5411 pic16_emitcode("clr","c");
5413 /* AOP_TYPE(right) == AOP_CRY */
5415 symbol *lbl = newiTempLabel(NULL);
5416 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5417 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5418 pic16_emitcode("cpl","c");
5419 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5422 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5423 pic16_outBitC(result);
5427 genIfxJump (ifx,"c");
5430 /* if the result is used in an arithmetic operation
5431 then put the result in place */
5432 pic16_outBitC(result);
5435 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5436 gencjne(left,right,result,ifx);
5439 gencjne(left,right,newiTempLabel(NULL));
5441 if(IC_TRUE(ifx)->key)
5442 gencjne(left,right,IC_TRUE(ifx)->key);
5444 gencjne(left,right,IC_FALSE(ifx)->key);
5448 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5449 pic16_aopPut(AOP(result),"a",0);
5454 genIfxJump (ifx,"a");
5458 /* if the result is used in an arithmetic operation
5459 then put the result in place */
5461 if (AOP_TYPE(result) != AOP_CRY)
5462 pic16_outAcc(result);
5464 /* leave the result in acc */
5468 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5469 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5470 pic16_freeAsmop(result,NULL,ic,TRUE);
5473 /*-----------------------------------------------------------------*/
5474 /* ifxForOp - returns the icode containing the ifx for operand */
5475 /*-----------------------------------------------------------------*/
5476 static iCode *ifxForOp ( operand *op, iCode *ic )
5478 /* if true symbol then needs to be assigned */
5479 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5480 if (IS_TRUE_SYMOP(op))
5483 /* if this has register type condition and
5484 the next instruction is ifx with the same operand
5485 and live to of the operand is upto the ifx only then */
5487 ic->next->op == IFX &&
5488 IC_COND(ic->next)->key == op->key &&
5489 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5493 ic->next->op == IFX &&
5494 IC_COND(ic->next)->key == op->key) {
5495 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5499 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5501 ic->next->op == IFX)
5502 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5505 ic->next->op == IFX &&
5506 IC_COND(ic->next)->key == op->key) {
5507 DEBUGpic16_emitcode ("; "," key is okay");
5508 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5509 OP_SYMBOL(op)->liveTo,
5516 /*-----------------------------------------------------------------*/
5517 /* genAndOp - for && operation */
5518 /*-----------------------------------------------------------------*/
5519 static void genAndOp (iCode *ic)
5521 operand *left,*right, *result;
5524 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5525 /* note here that && operations that are in an
5526 if statement are taken away by backPatchLabels
5527 only those used in arthmetic operations remain */
5528 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5529 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5530 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5532 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5534 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5535 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5536 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5538 /* if both are bit variables */
5539 /* if (AOP_TYPE(left) == AOP_CRY && */
5540 /* AOP_TYPE(right) == AOP_CRY ) { */
5541 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5542 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5543 /* pic16_outBitC(result); */
5545 /* tlbl = newiTempLabel(NULL); */
5546 /* pic16_toBoolean(left); */
5547 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5548 /* pic16_toBoolean(right); */
5549 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5550 /* pic16_outBitAcc(result); */
5553 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5554 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5555 pic16_freeAsmop(result,NULL,ic,TRUE);
5559 /*-----------------------------------------------------------------*/
5560 /* genOrOp - for || operation */
5561 /*-----------------------------------------------------------------*/
5564 modified this code, but it doesn't appear to ever get called
5567 static void genOrOp (iCode *ic)
5569 operand *left,*right, *result;
5572 /* note here that || operations that are in an
5573 if statement are taken away by backPatchLabels
5574 only those used in arthmetic operations remain */
5575 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5576 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5577 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5578 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5580 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5582 /* if both are bit variables */
5583 if (AOP_TYPE(left) == AOP_CRY &&
5584 AOP_TYPE(right) == AOP_CRY ) {
5585 pic16_emitcode("clrc","");
5586 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5587 AOP(left)->aopu.aop_dir,
5588 AOP(left)->aopu.aop_dir);
5589 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5590 AOP(right)->aopu.aop_dir,
5591 AOP(right)->aopu.aop_dir);
5592 pic16_emitcode("setc","");
5595 tlbl = newiTempLabel(NULL);
5596 pic16_toBoolean(left);
5598 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5599 pic16_toBoolean(right);
5600 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5602 pic16_outBitAcc(result);
5605 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5606 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5607 pic16_freeAsmop(result,NULL,ic,TRUE);
5610 /*-----------------------------------------------------------------*/
5611 /* isLiteralBit - test if lit == 2^n */
5612 /*-----------------------------------------------------------------*/
5613 static int isLiteralBit(unsigned long lit)
5615 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5616 0x100L,0x200L,0x400L,0x800L,
5617 0x1000L,0x2000L,0x4000L,0x8000L,
5618 0x10000L,0x20000L,0x40000L,0x80000L,
5619 0x100000L,0x200000L,0x400000L,0x800000L,
5620 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5621 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5625 for(idx = 0; idx < 32; idx++)
5631 /*-----------------------------------------------------------------*/
5632 /* continueIfTrue - */
5633 /*-----------------------------------------------------------------*/
5634 static void continueIfTrue (iCode *ic)
5636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5638 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5642 /*-----------------------------------------------------------------*/
5644 /*-----------------------------------------------------------------*/
5645 static void jumpIfTrue (iCode *ic)
5647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5649 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5653 /*-----------------------------------------------------------------*/
5654 /* jmpTrueOrFalse - */
5655 /*-----------------------------------------------------------------*/
5656 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5658 // ugly but optimized by peephole
5659 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5661 symbol *nlbl = newiTempLabel(NULL);
5662 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5663 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5664 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5665 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5668 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5669 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5674 /*-----------------------------------------------------------------*/
5675 /* genAnd - code for and */
5676 /*-----------------------------------------------------------------*/
5677 static void genAnd (iCode *ic, iCode *ifx)
5679 operand *left, *right, *result;
5681 unsigned long lit = 0L;
5686 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5687 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5688 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5689 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5691 resolveIfx(&rIfx,ifx);
5693 /* if left is a literal & right is not then exchange them */
5694 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5695 AOP_NEEDSACC(left)) {
5696 operand *tmp = right ;
5701 /* if result = right then exchange them */
5702 if(pic16_sameRegs(AOP(result),AOP(right))){
5703 operand *tmp = right ;
5708 /* if right is bit then exchange them */
5709 if (AOP_TYPE(right) == AOP_CRY &&
5710 AOP_TYPE(left) != AOP_CRY){
5711 operand *tmp = right ;
5715 if(AOP_TYPE(right) == AOP_LIT)
5716 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5718 size = AOP_SIZE(result);
5720 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5723 // result = bit & yy;
5724 if (AOP_TYPE(left) == AOP_CRY){
5725 // c = bit & literal;
5726 if(AOP_TYPE(right) == AOP_LIT){
5728 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5731 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5734 if(size && (AOP_TYPE(result) == AOP_CRY)){
5735 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5738 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5742 pic16_emitcode("clr","c");
5745 if (AOP_TYPE(right) == AOP_CRY){
5747 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5748 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5751 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5753 pic16_emitcode("rrc","a");
5754 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5760 pic16_outBitC(result);
5762 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5763 genIfxJump(ifx, "c");
5767 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5768 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5769 if((AOP_TYPE(right) == AOP_LIT) &&
5770 (AOP_TYPE(result) == AOP_CRY) &&
5771 (AOP_TYPE(left) != AOP_CRY)){
5772 int posbit = isLiteralBit(lit);
5776 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5779 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5785 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5786 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5788 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5789 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5792 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5793 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5794 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5801 symbol *tlbl = newiTempLabel(NULL);
5802 int sizel = AOP_SIZE(left);
5804 pic16_emitcode("setb","c");
5806 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5807 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5809 if((posbit = isLiteralBit(bytelit)) != 0)
5810 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5812 if(bytelit != 0x0FFL)
5813 pic16_emitcode("anl","a,%s",
5814 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5815 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5820 // bit = left & literal
5822 pic16_emitcode("clr","c");
5823 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5825 // if(left & literal)
5828 jmpTrueOrFalse(ifx, tlbl);
5832 pic16_outBitC(result);
5836 /* if left is same as result */
5837 if(pic16_sameRegs(AOP(result),AOP(left))){
5839 for(;size--; offset++,lit>>=8) {
5840 if(AOP_TYPE(right) == AOP_LIT){
5841 switch(lit & 0xff) {
5843 /* and'ing with 0 has clears the result */
5844 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5845 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5848 /* and'ing with 0xff is a nop when the result and left are the same */
5853 int p = my_powof2( (~lit) & 0xff );
5855 /* only one bit is set in the literal, so use a bcf instruction */
5856 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5857 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5860 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5861 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5862 if(know_W != (lit&0xff))
5863 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5865 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5870 if (AOP_TYPE(left) == AOP_ACC) {
5871 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5873 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5874 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5881 // left & result in different registers
5882 if(AOP_TYPE(result) == AOP_CRY){
5884 // if(size), result in bit
5885 // if(!size && ifx), conditional oper: if(left & right)
5886 symbol *tlbl = newiTempLabel(NULL);
5887 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5889 pic16_emitcode("setb","c");
5891 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5892 pic16_emitcode("anl","a,%s",
5893 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5894 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5899 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5900 pic16_outBitC(result);
5902 jmpTrueOrFalse(ifx, tlbl);
5904 for(;(size--);offset++) {
5906 // result = left & right
5907 if(AOP_TYPE(right) == AOP_LIT){
5908 int t = (lit >> (offset*8)) & 0x0FFL;
5911 pic16_emitcode("clrf","%s",
5912 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5913 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5916 pic16_emitcode("movf","%s,w",
5917 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5918 pic16_emitcode("movwf","%s",
5919 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5920 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5921 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5924 pic16_emitcode("movlw","0x%x",t);
5925 pic16_emitcode("andwf","%s,w",
5926 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5927 pic16_emitcode("movwf","%s",
5928 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5930 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5931 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5932 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5937 if (AOP_TYPE(left) == AOP_ACC) {
5938 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5939 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5941 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5942 pic16_emitcode("andwf","%s,w",
5943 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5944 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5945 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5947 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5948 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5954 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5955 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5956 pic16_freeAsmop(result,NULL,ic,TRUE);
5959 /*-----------------------------------------------------------------*/
5960 /* genOr - code for or */
5961 /*-----------------------------------------------------------------*/
5962 static void genOr (iCode *ic, iCode *ifx)
5964 operand *left, *right, *result;
5966 unsigned long lit = 0L;
5968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5970 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5971 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5972 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5974 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5976 /* if left is a literal & right is not then exchange them */
5977 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5978 AOP_NEEDSACC(left)) {
5979 operand *tmp = right ;
5984 /* if result = right then exchange them */
5985 if(pic16_sameRegs(AOP(result),AOP(right))){
5986 operand *tmp = right ;
5991 /* if right is bit then exchange them */
5992 if (AOP_TYPE(right) == AOP_CRY &&
5993 AOP_TYPE(left) != AOP_CRY){
5994 operand *tmp = right ;
5999 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6001 if(AOP_TYPE(right) == AOP_LIT)
6002 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6004 size = AOP_SIZE(result);
6008 if (AOP_TYPE(left) == AOP_CRY){
6009 if(AOP_TYPE(right) == AOP_LIT){
6010 // c = bit & literal;
6012 // lit != 0 => result = 1
6013 if(AOP_TYPE(result) == AOP_CRY){
6015 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6016 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6017 // AOP(result)->aopu.aop_dir,
6018 // AOP(result)->aopu.aop_dir);
6020 continueIfTrue(ifx);
6024 // lit == 0 => result = left
6025 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6027 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6030 if (AOP_TYPE(right) == AOP_CRY){
6031 if(pic16_sameRegs(AOP(result),AOP(left))){
6033 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6034 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6035 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6037 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6038 AOP(result)->aopu.aop_dir,
6039 AOP(result)->aopu.aop_dir);
6040 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6041 AOP(right)->aopu.aop_dir,
6042 AOP(right)->aopu.aop_dir);
6043 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6044 AOP(result)->aopu.aop_dir,
6045 AOP(result)->aopu.aop_dir);
6047 if( AOP_TYPE(result) == AOP_ACC) {
6048 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6049 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6050 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6055 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6056 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6057 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6058 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6060 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6061 AOP(result)->aopu.aop_dir,
6062 AOP(result)->aopu.aop_dir);
6063 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6064 AOP(right)->aopu.aop_dir,
6065 AOP(right)->aopu.aop_dir);
6066 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6067 AOP(left)->aopu.aop_dir,
6068 AOP(left)->aopu.aop_dir);
6069 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6070 AOP(result)->aopu.aop_dir,
6071 AOP(result)->aopu.aop_dir);
6076 symbol *tlbl = newiTempLabel(NULL);
6077 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6080 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6081 if( AOP_TYPE(right) == AOP_ACC) {
6082 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6084 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6085 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6090 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6091 pic16_emitcode(";XXX setb","c");
6092 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6093 AOP(left)->aopu.aop_dir,tlbl->key+100);
6094 pic16_toBoolean(right);
6095 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6096 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6097 jmpTrueOrFalse(ifx, tlbl);
6101 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6108 pic16_outBitC(result);
6110 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6111 genIfxJump(ifx, "c");
6115 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6116 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6117 if((AOP_TYPE(right) == AOP_LIT) &&
6118 (AOP_TYPE(result) == AOP_CRY) &&
6119 (AOP_TYPE(left) != AOP_CRY)){
6121 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6124 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6126 continueIfTrue(ifx);
6129 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6130 // lit = 0, result = boolean(left)
6132 pic16_emitcode(";XXX setb","c");
6133 pic16_toBoolean(right);
6135 symbol *tlbl = newiTempLabel(NULL);
6136 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6138 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6140 genIfxJump (ifx,"a");
6144 pic16_outBitC(result);
6148 /* if left is same as result */
6149 if(pic16_sameRegs(AOP(result),AOP(left))){
6151 for(;size--; offset++,lit>>=8) {
6152 if(AOP_TYPE(right) == AOP_LIT){
6153 if((lit & 0xff) == 0)
6154 /* or'ing with 0 has no effect */
6157 int p = my_powof2(lit & 0xff);
6159 /* only one bit is set in the literal, so use a bsf instruction */
6160 pic16_emitpcode(POC_BSF,
6161 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6163 if(know_W != (lit & 0xff))
6164 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6165 know_W = lit & 0xff;
6166 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6171 if (AOP_TYPE(left) == AOP_ACC) {
6172 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6173 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6175 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6176 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6178 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6179 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6185 // left & result in different registers
6186 if(AOP_TYPE(result) == AOP_CRY){
6188 // if(size), result in bit
6189 // if(!size && ifx), conditional oper: if(left | right)
6190 symbol *tlbl = newiTempLabel(NULL);
6191 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6192 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6196 pic16_emitcode(";XXX setb","c");
6198 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6199 pic16_emitcode(";XXX orl","a,%s",
6200 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6201 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6206 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6207 pic16_outBitC(result);
6209 jmpTrueOrFalse(ifx, tlbl);
6210 } else for(;(size--);offset++){
6212 // result = left & right
6213 if(AOP_TYPE(right) == AOP_LIT){
6214 int t = (lit >> (offset*8)) & 0x0FFL;
6217 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6218 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6220 pic16_emitcode("movf","%s,w",
6221 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6222 pic16_emitcode("movwf","%s",
6223 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6226 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6227 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6228 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6230 pic16_emitcode("movlw","0x%x",t);
6231 pic16_emitcode("iorwf","%s,w",
6232 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6233 pic16_emitcode("movwf","%s",
6234 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6240 // faster than result <- left, anl result,right
6241 // and better if result is SFR
6242 if (AOP_TYPE(left) == AOP_ACC) {
6243 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6244 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6246 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6247 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6249 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6250 pic16_emitcode("iorwf","%s,w",
6251 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6253 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6254 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6259 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6260 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6261 pic16_freeAsmop(result,NULL,ic,TRUE);
6264 /*-----------------------------------------------------------------*/
6265 /* genXor - code for xclusive or */
6266 /*-----------------------------------------------------------------*/
6267 static void genXor (iCode *ic, iCode *ifx)
6269 operand *left, *right, *result;
6271 unsigned long lit = 0L;
6273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6276 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6277 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6279 /* if left is a literal & right is not ||
6280 if left needs acc & right does not */
6281 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6282 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6283 operand *tmp = right ;
6288 /* if result = right then exchange them */
6289 if(pic16_sameRegs(AOP(result),AOP(right))){
6290 operand *tmp = right ;
6295 /* if right is bit then exchange them */
6296 if (AOP_TYPE(right) == AOP_CRY &&
6297 AOP_TYPE(left) != AOP_CRY){
6298 operand *tmp = right ;
6302 if(AOP_TYPE(right) == AOP_LIT)
6303 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6305 size = AOP_SIZE(result);
6309 if (AOP_TYPE(left) == AOP_CRY){
6310 if(AOP_TYPE(right) == AOP_LIT){
6311 // c = bit & literal;
6313 // lit>>1 != 0 => result = 1
6314 if(AOP_TYPE(result) == AOP_CRY){
6316 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6317 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6319 continueIfTrue(ifx);
6322 pic16_emitcode("setb","c");
6326 // lit == 0, result = left
6327 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6329 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6331 // lit == 1, result = not(left)
6332 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6333 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6334 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6335 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6338 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6339 pic16_emitcode("cpl","c");
6346 symbol *tlbl = newiTempLabel(NULL);
6347 if (AOP_TYPE(right) == AOP_CRY){
6349 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6352 int sizer = AOP_SIZE(right);
6354 // if val>>1 != 0, result = 1
6355 pic16_emitcode("setb","c");
6357 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6359 // test the msb of the lsb
6360 pic16_emitcode("anl","a,#0xfe");
6361 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6365 pic16_emitcode("rrc","a");
6367 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6368 pic16_emitcode("cpl","c");
6369 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6374 pic16_outBitC(result);
6376 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6377 genIfxJump(ifx, "c");
6381 if(pic16_sameRegs(AOP(result),AOP(left))){
6382 /* if left is same as result */
6383 for(;size--; offset++) {
6384 if(AOP_TYPE(right) == AOP_LIT){
6385 int t = (lit >> (offset*8)) & 0x0FFL;
6389 if (IS_AOP_PREG(left)) {
6390 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6391 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6392 pic16_aopPut(AOP(result),"a",offset);
6394 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6395 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6396 pic16_emitcode("xrl","%s,%s",
6397 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6398 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6401 if (AOP_TYPE(left) == AOP_ACC)
6402 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6404 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6405 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6407 if (IS_AOP_PREG(left)) {
6408 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6409 pic16_aopPut(AOP(result),"a",offset);
6411 pic16_emitcode("xrl","%s,a",
6412 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6418 // left & result in different registers
6419 if(AOP_TYPE(result) == AOP_CRY){
6421 // if(size), result in bit
6422 // if(!size && ifx), conditional oper: if(left ^ right)
6423 symbol *tlbl = newiTempLabel(NULL);
6424 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6426 pic16_emitcode("setb","c");
6428 if((AOP_TYPE(right) == AOP_LIT) &&
6429 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6430 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6432 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6433 pic16_emitcode("xrl","a,%s",
6434 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6436 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6441 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6442 pic16_outBitC(result);
6444 jmpTrueOrFalse(ifx, tlbl);
6445 } else for(;(size--);offset++){
6447 // result = left & right
6448 if(AOP_TYPE(right) == AOP_LIT){
6449 int t = (lit >> (offset*8)) & 0x0FFL;
6452 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6453 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6454 pic16_emitcode("movf","%s,w",
6455 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6456 pic16_emitcode("movwf","%s",
6457 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6460 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6461 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6462 pic16_emitcode("comf","%s,w",
6463 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6464 pic16_emitcode("movwf","%s",
6465 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6468 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6469 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6470 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6471 pic16_emitcode("movlw","0x%x",t);
6472 pic16_emitcode("xorwf","%s,w",
6473 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6474 pic16_emitcode("movwf","%s",
6475 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6481 // faster than result <- left, anl result,right
6482 // and better if result is SFR
6483 if (AOP_TYPE(left) == AOP_ACC) {
6484 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6485 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6487 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6488 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6489 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6490 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6492 if ( AOP_TYPE(result) != AOP_ACC){
6493 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6494 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6500 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6501 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6502 pic16_freeAsmop(result,NULL,ic,TRUE);
6505 /*-----------------------------------------------------------------*/
6506 /* genInline - write the inline code out */
6507 /*-----------------------------------------------------------------*/
6508 static void genInline (iCode *ic)
6510 char *buffer, *bp, *bp1;
6512 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6514 _G.inLine += (!options.asmpeep);
6516 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6517 strcpy(buffer,IC_INLINE(ic));
6519 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
6521 /* emit each line as a code */
6528 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6530 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6538 pic16_emitcode(bp1,"");
6545 if ((bp1 != bp) && *bp1)
6547 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6549 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1));
6555 _G.inLine -= (!options.asmpeep);
6558 /*-----------------------------------------------------------------*/
6559 /* genRRC - rotate right with carry */
6560 /*-----------------------------------------------------------------*/
6561 static void genRRC (iCode *ic)
6563 operand *left , *result ;
6564 int size, offset = 0, same;
6566 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6568 /* rotate right with carry */
6570 result=IC_RESULT(ic);
6571 pic16_aopOp (left,ic,FALSE);
6572 pic16_aopOp (result,ic,FALSE);
6574 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6576 same = pic16_sameRegs(AOP(result),AOP(left));
6578 size = AOP_SIZE(result);
6580 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6582 /* get the lsb and put it into the carry */
6583 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6590 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6592 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6593 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6599 pic16_freeAsmop(left,NULL,ic,TRUE);
6600 pic16_freeAsmop(result,NULL,ic,TRUE);
6603 /*-----------------------------------------------------------------*/
6604 /* genRLC - generate code for rotate left with carry */
6605 /*-----------------------------------------------------------------*/
6606 static void genRLC (iCode *ic)
6608 operand *left , *result ;
6609 int size, offset = 0;
6612 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6613 /* rotate right with carry */
6615 result=IC_RESULT(ic);
6616 pic16_aopOp (left,ic,FALSE);
6617 pic16_aopOp (result,ic,FALSE);
6619 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6621 same = pic16_sameRegs(AOP(result),AOP(left));
6623 /* move it to the result */
6624 size = AOP_SIZE(result);
6626 /* get the msb and put it into the carry */
6627 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6634 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6636 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6637 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6644 pic16_freeAsmop(left,NULL,ic,TRUE);
6645 pic16_freeAsmop(result,NULL,ic,TRUE);
6649 /* gpasm can get the highest order bit with HIGH/UPPER
6650 * so the following probably is not needed -- VR */
6652 /*-----------------------------------------------------------------*/
6653 /* genGetHbit - generates code get highest order bit */
6654 /*-----------------------------------------------------------------*/
6655 static void genGetHbit (iCode *ic)
6657 operand *left, *result;
6659 result=IC_RESULT(ic);
6660 pic16_aopOp (left,ic,FALSE);
6661 pic16_aopOp (result,ic,FALSE);
6663 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6664 /* get the highest order byte into a */
6665 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6666 if(AOP_TYPE(result) == AOP_CRY){
6667 pic16_emitcode("rlc","a");
6668 pic16_outBitC(result);
6671 pic16_emitcode("rl","a");
6672 pic16_emitcode("anl","a,#0x01");
6673 pic16_outAcc(result);
6677 pic16_freeAsmop(left,NULL,ic,TRUE);
6678 pic16_freeAsmop(result,NULL,ic,TRUE);
6682 /*-----------------------------------------------------------------*/
6683 /* AccRol - rotate left accumulator by known count */
6684 /*-----------------------------------------------------------------*/
6685 static void AccRol (int shCount)
6687 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6688 shCount &= 0x0007; // shCount : 0..7
6693 pic16_emitcode("rl","a");
6696 pic16_emitcode("rl","a");
6697 pic16_emitcode("rl","a");
6700 pic16_emitcode("swap","a");
6701 pic16_emitcode("rr","a");
6704 pic16_emitcode("swap","a");
6707 pic16_emitcode("swap","a");
6708 pic16_emitcode("rl","a");
6711 pic16_emitcode("rr","a");
6712 pic16_emitcode("rr","a");
6715 pic16_emitcode("rr","a");
6721 /*-----------------------------------------------------------------*/
6722 /* AccLsh - left shift accumulator by known count */
6723 /*-----------------------------------------------------------------*/
6724 static void AccLsh (int shCount)
6726 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6732 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6735 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6736 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6739 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6740 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6743 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6746 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6747 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6750 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6751 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6754 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6758 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6761 /*-----------------------------------------------------------------*/
6762 /* AccRsh - right shift accumulator by known count */
6763 /*-----------------------------------------------------------------*/
6764 static void AccRsh (int shCount, int andmask)
6766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6771 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6772 // andmask = 0; /* no need */
6775 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6776 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6777 // andmask = 0; /* no need */
6780 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6781 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6784 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6787 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6788 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6791 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6792 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6795 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6800 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6802 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
6806 /*-----------------------------------------------------------------*/
6807 /* AccSRsh - signed right shift accumulator by known count */
6808 /*-----------------------------------------------------------------*/
6809 static void AccSRsh (int shCount)
6812 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6815 pic16_emitcode("mov","c,acc.7");
6816 pic16_emitcode("rrc","a");
6817 } else if(shCount == 2){
6818 pic16_emitcode("mov","c,acc.7");
6819 pic16_emitcode("rrc","a");
6820 pic16_emitcode("mov","c,acc.7");
6821 pic16_emitcode("rrc","a");
6823 tlbl = newiTempLabel(NULL);
6824 /* rotate right accumulator */
6825 AccRol(8 - shCount);
6826 /* and kill the higher order bits */
6827 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6828 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6829 pic16_emitcode("orl","a,#0x%02x",
6830 (unsigned char)~SRMask[shCount]);
6831 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6836 /*-----------------------------------------------------------------*/
6837 /* shiftR1Left2Result - shift right one byte from left to result */
6838 /*-----------------------------------------------------------------*/
6839 static void shiftR1Left2ResultSigned (operand *left, int offl,
6840 operand *result, int offr,
6845 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6847 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6851 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6853 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6855 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6856 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6862 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6864 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6866 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6867 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6869 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6870 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6876 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6878 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6879 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6882 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6886 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6887 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6889 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6893 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6894 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6895 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6896 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6897 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6903 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6904 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6906 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6908 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6909 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6910 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6915 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6916 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6917 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6918 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6919 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6920 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6922 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6923 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6924 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6925 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6926 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6932 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6933 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6934 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6935 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6937 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6938 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6939 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6947 /*-----------------------------------------------------------------*/
6948 /* shiftR1Left2Result - shift right one byte from left to result */
6949 /*-----------------------------------------------------------------*/
6950 static void shiftR1Left2Result (operand *left, int offl,
6951 operand *result, int offr,
6952 int shCount, int sign)
6956 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6958 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6960 /* Copy the msb into the carry if signed. */
6962 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6972 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6974 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6975 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6981 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6983 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6984 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6987 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6992 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6994 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6995 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6998 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6999 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7000 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7001 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7005 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7006 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7007 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7011 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7012 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7013 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7015 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7020 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7021 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7022 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7023 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7024 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7030 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7031 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7040 /*-----------------------------------------------------------------*/
7041 /* shiftL1Left2Result - shift left one byte from left to result */
7042 /*-----------------------------------------------------------------*/
7043 static void shiftL1Left2Result (operand *left, int offl,
7044 operand *result, int offr, int shCount)
7049 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7051 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7052 DEBUGpic16_emitcode ("; ***","same = %d",same);
7053 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7055 /* shift left accumulator */
7056 //AccLsh(shCount); // don't comment out just yet...
7057 // pic16_aopPut(AOP(result),"a",offr);
7061 /* Shift left 1 bit position */
7062 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7064 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7066 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7067 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7071 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7072 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7073 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7074 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7077 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7078 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7079 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7080 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7081 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7084 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7085 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7086 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7089 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7090 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7091 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7092 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7095 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7096 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7097 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7098 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7099 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7102 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7103 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7104 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7108 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7113 /*-----------------------------------------------------------------*/
7114 /* movLeft2Result - move byte from left to result */
7115 /*-----------------------------------------------------------------*/
7116 static void movLeft2Result (operand *left, int offl,
7117 operand *result, int offr)
7120 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7121 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7122 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7124 if (*l == '@' && (IS_AOP_PREG(result))) {
7125 pic16_emitcode("mov","a,%s",l);
7126 pic16_aopPut(AOP(result),"a",offr);
7128 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7129 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7134 /*-----------------------------------------------------------------*/
7135 /* shiftL2Left2Result - shift left two bytes from left to result */
7136 /*-----------------------------------------------------------------*/
7137 static void shiftL2Left2Result (operand *left, int offl,
7138 operand *result, int offr, int shCount)
7140 int same = pic16_sameRegs(AOP(result), AOP(left));
7143 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7145 if (same && (offl != offr)) { // shift bytes
7148 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7149 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7151 } else { // just treat as different later on
7164 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7165 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7166 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7170 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7171 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7177 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7178 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7179 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7180 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7181 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7182 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7183 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7185 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7186 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
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_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7193 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7194 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7195 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7196 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7197 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7198 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7199 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7202 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7203 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7204 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7205 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7206 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7216 /* note, use a mov/add for the shift since the mov has a
7217 chance of getting optimized out */
7218 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7219 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7220 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7221 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7222 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7226 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7227 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7233 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7234 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7236 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7237 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7238 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7239 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7240 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7244 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7245 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7249 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7250 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7251 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7252 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7254 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7255 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7256 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7257 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7258 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7259 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7260 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7261 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7264 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7265 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7266 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7267 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7268 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7273 /*-----------------------------------------------------------------*/
7274 /* shiftR2Left2Result - shift right two bytes from left to result */
7275 /*-----------------------------------------------------------------*/
7276 static void shiftR2Left2Result (operand *left, int offl,
7277 operand *result, int offr,
7278 int shCount, int sign)
7280 int same = pic16_sameRegs(AOP(result), AOP(left));
7282 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7284 if (same && (offl != offr)) { // shift right bytes
7287 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7288 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7290 } else { // just treat as different later on
7302 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7307 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7308 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7310 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7311 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7312 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7313 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7318 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7321 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7322 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7329 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7330 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7331 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7333 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7334 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7335 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7336 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7338 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7339 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7340 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7342 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7343 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7344 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7345 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7346 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7350 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7351 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7355 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7356 pic16_emitpcode(POC_BTFSC,
7357 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7358 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7366 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7367 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7369 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7370 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7371 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7372 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7374 pic16_emitpcode(POC_BTFSC,
7375 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7376 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7378 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7379 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7380 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7381 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7383 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7384 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7385 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7386 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7387 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7388 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7389 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7390 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7392 pic16_emitpcode(POC_BTFSC,
7393 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7394 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7396 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7397 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7404 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7405 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7406 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7407 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7410 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7412 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7417 /*-----------------------------------------------------------------*/
7418 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7419 /*-----------------------------------------------------------------*/
7420 static void shiftLLeftOrResult (operand *left, int offl,
7421 operand *result, int offr, int shCount)
7423 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7425 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7426 /* shift left accumulator */
7428 /* or with result */
7429 /* back to result */
7430 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7433 /*-----------------------------------------------------------------*/
7434 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7435 /*-----------------------------------------------------------------*/
7436 static void shiftRLeftOrResult (operand *left, int offl,
7437 operand *result, int offr, int shCount)
7439 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7441 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7442 /* shift right accumulator */
7444 /* or with result */
7445 /* back to result */
7446 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7449 /*-----------------------------------------------------------------*/
7450 /* genlshOne - left shift a one byte quantity by known count */
7451 /*-----------------------------------------------------------------*/
7452 static void genlshOne (operand *result, operand *left, int shCount)
7454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7455 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7458 /*-----------------------------------------------------------------*/
7459 /* genlshTwo - left shift two bytes by known amount != 0 */
7460 /*-----------------------------------------------------------------*/
7461 static void genlshTwo (operand *result,operand *left, int shCount)
7465 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7466 size = pic16_getDataSize(result);
7468 /* if shCount >= 8 */
7474 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7476 movLeft2Result(left, LSB, result, MSB16);
7478 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7481 /* 1 <= shCount <= 7 */
7484 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7486 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7490 /*-----------------------------------------------------------------*/
7491 /* shiftLLong - shift left one long from left to result */
7492 /* offr = LSB or MSB16 */
7493 /*-----------------------------------------------------------------*/
7494 static void shiftLLong (operand *left, operand *result, int offr )
7496 int size = AOP_SIZE(result);
7497 int same = pic16_sameRegs(AOP(left),AOP(result));
7500 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7502 if (same && (offr == MSB16)) { //shift one byte
7503 for(i=size-1;i>=MSB16;i--) {
7504 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7505 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7508 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7511 if (size >= LSB+offr ){
7513 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7515 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7516 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7520 if(size >= MSB16+offr){
7522 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7524 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7525 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7529 if(size >= MSB24+offr){
7531 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7533 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7534 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7538 if(size > MSB32+offr){
7540 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7542 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7543 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7547 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7551 /*-----------------------------------------------------------------*/
7552 /* genlshFour - shift four byte by a known amount != 0 */
7553 /*-----------------------------------------------------------------*/
7554 static void genlshFour (operand *result, operand *left, int shCount)
7558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7559 size = AOP_SIZE(result);
7561 /* if shifting more that 3 bytes */
7562 if (shCount >= 24 ) {
7565 /* lowest order of left goes to the highest
7566 order of the destination */
7567 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7569 movLeft2Result(left, LSB, result, MSB32);
7571 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7572 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7573 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7578 /* more than two bytes */
7579 else if ( shCount >= 16 ) {
7580 /* lower order two bytes goes to higher order two bytes */
7582 /* if some more remaining */
7584 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7586 movLeft2Result(left, MSB16, result, MSB32);
7587 movLeft2Result(left, LSB, result, MSB24);
7589 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7590 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7594 /* if more than 1 byte */
7595 else if ( shCount >= 8 ) {
7596 /* lower order three bytes goes to higher order three bytes */
7600 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7602 movLeft2Result(left, LSB, result, MSB16);
7604 else{ /* size = 4 */
7606 movLeft2Result(left, MSB24, result, MSB32);
7607 movLeft2Result(left, MSB16, result, MSB24);
7608 movLeft2Result(left, LSB, result, MSB16);
7609 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7611 else if(shCount == 1)
7612 shiftLLong(left, result, MSB16);
7614 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7615 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7616 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7617 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7622 /* 1 <= shCount <= 7 */
7623 else if(shCount <= 3)
7625 shiftLLong(left, result, LSB);
7626 while(--shCount >= 1)
7627 shiftLLong(result, result, LSB);
7629 /* 3 <= shCount <= 7, optimize */
7631 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7632 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7633 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7637 /*-----------------------------------------------------------------*/
7638 /* genLeftShiftLiteral - left shifting by known count */
7639 /*-----------------------------------------------------------------*/
7640 static void genLeftShiftLiteral (operand *left,
7645 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7648 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7649 pic16_freeAsmop(right,NULL,ic,TRUE);
7651 pic16_aopOp(left,ic,FALSE);
7652 pic16_aopOp(result,ic,FALSE);
7654 size = getSize(operandType(result));
7657 pic16_emitcode("; shift left ","result %d, left %d",size,
7661 /* I suppose that the left size >= result size */
7664 movLeft2Result(left, size, result, size);
7668 else if(shCount >= (size * 8))
7670 pic16_aopPut(AOP(result),zero,size);
7674 genlshOne (result,left,shCount);
7679 genlshTwo (result,left,shCount);
7683 genlshFour (result,left,shCount);
7687 pic16_freeAsmop(left,NULL,ic,TRUE);
7688 pic16_freeAsmop(result,NULL,ic,TRUE);
7691 /*-----------------------------------------------------------------*
7692 * genMultiAsm - repeat assembly instruction for size of register.
7693 * if endian == 1, then the high byte (i.e base address + size of
7694 * register) is used first else the low byte is used first;
7695 *-----------------------------------------------------------------*/
7696 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7701 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7714 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7719 /*-----------------------------------------------------------------*/
7720 /* genLeftShift - generates code for left shifting */
7721 /*-----------------------------------------------------------------*/
7722 static void genLeftShift (iCode *ic)
7724 operand *left,*right, *result;
7727 symbol *tlbl , *tlbl1;
7730 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7732 right = IC_RIGHT(ic);
7734 result = IC_RESULT(ic);
7736 pic16_aopOp(right,ic,FALSE);
7738 /* if the shift count is known then do it
7739 as efficiently as possible */
7740 if (AOP_TYPE(right) == AOP_LIT) {
7741 genLeftShiftLiteral (left,right,result,ic);
7745 /* shift count is unknown then we have to form
7746 a loop get the loop count in B : Note: we take
7747 only the lower order byte since shifting
7748 more that 32 bits make no sense anyway, ( the
7749 largest size of an object can be only 32 bits ) */
7752 pic16_aopOp(left,ic,FALSE);
7753 pic16_aopOp(result,ic,FALSE);
7755 /* now move the left to the result if they are not the
7757 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7758 AOP_SIZE(result) > 1) {
7760 size = AOP_SIZE(result);
7763 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7764 if (*l == '@' && (IS_AOP_PREG(result))) {
7766 pic16_emitcode("mov","a,%s",l);
7767 pic16_aopPut(AOP(result),"a",offset);
7769 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7770 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7771 //pic16_aopPut(AOP(result),l,offset);
7777 size = AOP_SIZE(result);
7779 /* if it is only one byte then */
7781 if(optimized_for_speed) {
7782 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7783 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7784 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7785 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7786 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7787 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7788 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7789 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7790 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7791 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7792 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7793 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7796 tlbl = newiTempLabel(NULL);
7797 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7798 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7799 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7802 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7803 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7804 pic16_emitpLabel(tlbl->key);
7805 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7806 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7808 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7813 if (pic16_sameRegs(AOP(left),AOP(result))) {
7815 tlbl = newiTempLabel(NULL);
7816 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7817 genMultiAsm(POC_RRCF, result, size,1);
7818 pic16_emitpLabel(tlbl->key);
7819 genMultiAsm(POC_RLCF, result, size,0);
7820 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7822 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7826 //tlbl = newiTempLabel(NULL);
7828 //tlbl1 = newiTempLabel(NULL);
7830 //reAdjustPreg(AOP(result));
7832 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7833 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7834 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7836 //pic16_emitcode("add","a,acc");
7837 //pic16_aopPut(AOP(result),"a",offset++);
7839 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7841 // pic16_emitcode("rlc","a");
7842 // pic16_aopPut(AOP(result),"a",offset++);
7844 //reAdjustPreg(AOP(result));
7846 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7847 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7850 tlbl = newiTempLabel(NULL);
7851 tlbl1= newiTempLabel(NULL);
7853 size = AOP_SIZE(result);
7856 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7858 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7860 /* offset should be 0, 1 or 3 */
7862 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7864 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7866 pic16_emitpcode(POC_MOVWF, pctemp);
7869 pic16_emitpLabel(tlbl->key);
7872 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7874 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7876 pic16_emitpcode(POC_DECFSZ, pctemp);
7877 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7878 pic16_emitpLabel(tlbl1->key);
7880 pic16_popReleaseTempReg(pctemp);
7884 pic16_freeAsmop (right,NULL,ic,TRUE);
7885 pic16_freeAsmop(left,NULL,ic,TRUE);
7886 pic16_freeAsmop(result,NULL,ic,TRUE);
7889 /*-----------------------------------------------------------------*/
7890 /* genrshOne - right shift a one byte quantity by known count */
7891 /*-----------------------------------------------------------------*/
7892 static void genrshOne (operand *result, operand *left,
7893 int shCount, int sign)
7895 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7896 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7899 /*-----------------------------------------------------------------*/
7900 /* genrshTwo - right shift two bytes by known amount != 0 */
7901 /*-----------------------------------------------------------------*/
7902 static void genrshTwo (operand *result,operand *left,
7903 int shCount, int sign)
7905 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7906 /* if shCount >= 8 */
7910 shiftR1Left2Result(left, MSB16, result, LSB,
7913 movLeft2Result(left, MSB16, result, LSB);
7915 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7918 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7919 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7923 /* 1 <= shCount <= 7 */
7925 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7928 /*-----------------------------------------------------------------*/
7929 /* shiftRLong - shift right one long from left to result */
7930 /* offl = LSB or MSB16 */
7931 /*-----------------------------------------------------------------*/
7932 static void shiftRLong (operand *left, int offl,
7933 operand *result, int sign)
7935 int size = AOP_SIZE(result);
7936 int same = pic16_sameRegs(AOP(left),AOP(result));
7938 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7940 if (same && (offl == MSB16)) { //shift one byte right
7941 for(i=MSB16;i<size;i++) {
7942 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7943 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7948 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7954 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7956 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7957 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7961 /* add sign of "a" */
7962 pic16_addSign(result, MSB32, sign);
7966 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7968 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7969 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7973 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7975 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7976 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7980 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7983 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7984 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7989 /*-----------------------------------------------------------------*/
7990 /* genrshFour - shift four byte by a known amount != 0 */
7991 /*-----------------------------------------------------------------*/
7992 static void genrshFour (operand *result, operand *left,
7993 int shCount, int sign)
7995 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7996 /* if shifting more that 3 bytes */
7997 if(shCount >= 24 ) {
8000 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8002 movLeft2Result(left, MSB32, result, LSB);
8004 pic16_addSign(result, MSB16, sign);
8006 else if(shCount >= 16){
8009 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8011 movLeft2Result(left, MSB24, result, LSB);
8012 movLeft2Result(left, MSB32, result, MSB16);
8014 pic16_addSign(result, MSB24, sign);
8016 else if(shCount >= 8){
8019 shiftRLong(left, MSB16, result, sign);
8020 else if(shCount == 0){
8021 movLeft2Result(left, MSB16, result, LSB);
8022 movLeft2Result(left, MSB24, result, MSB16);
8023 movLeft2Result(left, MSB32, result, MSB24);
8024 pic16_addSign(result, MSB32, sign);
8026 else{ //shcount >= 2
8027 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8028 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8029 /* the last shift is signed */
8030 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8031 pic16_addSign(result, MSB32, sign);
8034 else{ /* 1 <= shCount <= 7 */
8036 shiftRLong(left, LSB, result, sign);
8038 shiftRLong(result, LSB, result, sign);
8041 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8042 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8043 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8048 /*-----------------------------------------------------------------*/
8049 /* genRightShiftLiteral - right shifting by known count */
8050 /*-----------------------------------------------------------------*/
8051 static void genRightShiftLiteral (operand *left,
8057 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8060 pic16_freeAsmop(right,NULL,ic,TRUE);
8062 pic16_aopOp(left,ic,FALSE);
8063 pic16_aopOp(result,ic,FALSE);
8065 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8068 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8072 lsize = pic16_getDataSize(left);
8073 res_size = pic16_getDataSize(result);
8074 /* test the LEFT size !!! */
8076 /* I suppose that the left size >= result size */
8079 movLeft2Result(left, lsize, result, res_size);
8082 else if(shCount >= (lsize * 8)){
8085 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8087 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8088 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8093 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8094 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8095 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8097 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8102 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8109 genrshOne (result,left,shCount,sign);
8113 genrshTwo (result,left,shCount,sign);
8117 genrshFour (result,left,shCount,sign);
8125 pic16_freeAsmop(left,NULL,ic,TRUE);
8126 pic16_freeAsmop(result,NULL,ic,TRUE);
8129 /*-----------------------------------------------------------------*/
8130 /* genSignedRightShift - right shift of signed number */
8131 /*-----------------------------------------------------------------*/
8132 static void genSignedRightShift (iCode *ic)
8134 operand *right, *left, *result;
8137 symbol *tlbl, *tlbl1 ;
8140 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8142 /* we do it the hard way put the shift count in b
8143 and loop thru preserving the sign */
8144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8146 right = IC_RIGHT(ic);
8148 result = IC_RESULT(ic);
8150 pic16_aopOp(right,ic,FALSE);
8151 pic16_aopOp(left,ic,FALSE);
8152 pic16_aopOp(result,ic,FALSE);
8155 if ( AOP_TYPE(right) == AOP_LIT) {
8156 genRightShiftLiteral (left,right,result,ic,1);
8159 /* shift count is unknown then we have to form
8160 a loop get the loop count in B : Note: we take
8161 only the lower order byte since shifting
8162 more that 32 bits make no sense anyway, ( the
8163 largest size of an object can be only 32 bits ) */
8165 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8166 //pic16_emitcode("inc","b");
8167 //pic16_freeAsmop (right,NULL,ic,TRUE);
8168 //pic16_aopOp(left,ic,FALSE);
8169 //pic16_aopOp(result,ic,FALSE);
8171 /* now move the left to the result if they are not the
8173 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8174 AOP_SIZE(result) > 1) {
8176 size = AOP_SIZE(result);
8180 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8181 if (*l == '@' && IS_AOP_PREG(result)) {
8183 pic16_emitcode("mov","a,%s",l);
8184 pic16_aopPut(AOP(result),"a",offset);
8186 pic16_aopPut(AOP(result),l,offset);
8188 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8189 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8195 /* mov the highest order bit to OVR */
8196 tlbl = newiTempLabel(NULL);
8197 tlbl1= newiTempLabel(NULL);
8199 size = AOP_SIZE(result);
8202 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8204 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8206 /* offset should be 0, 1 or 3 */
8207 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8209 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8211 pic16_emitpcode(POC_MOVWF, pctemp);
8214 pic16_emitpLabel(tlbl->key);
8216 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8217 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8220 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8223 pic16_emitpcode(POC_DECFSZ, pctemp);
8224 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8225 pic16_emitpLabel(tlbl1->key);
8227 pic16_popReleaseTempReg(pctemp);
8229 size = AOP_SIZE(result);
8231 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8232 pic16_emitcode("rlc","a");
8233 pic16_emitcode("mov","ov,c");
8234 /* if it is only one byte then */
8236 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8238 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8239 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8240 pic16_emitcode("mov","c,ov");
8241 pic16_emitcode("rrc","a");
8242 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8243 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8244 pic16_aopPut(AOP(result),"a",0);
8248 reAdjustPreg(AOP(result));
8249 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8250 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8251 pic16_emitcode("mov","c,ov");
8253 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8255 pic16_emitcode("rrc","a");
8256 pic16_aopPut(AOP(result),"a",offset--);
8258 reAdjustPreg(AOP(result));
8259 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8260 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8265 pic16_freeAsmop(left,NULL,ic,TRUE);
8266 pic16_freeAsmop(result,NULL,ic,TRUE);
8267 pic16_freeAsmop(right,NULL,ic,TRUE);
8270 /*-----------------------------------------------------------------*/
8271 /* genRightShift - generate code for right shifting */
8272 /*-----------------------------------------------------------------*/
8273 static void genRightShift (iCode *ic)
8275 operand *right, *left, *result;
8279 symbol *tlbl, *tlbl1 ;
8281 /* if signed then we do it the hard way preserve the
8282 sign bit moving it inwards */
8283 letype = getSpec(operandType(IC_LEFT(ic)));
8284 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8286 if (!SPEC_USIGN(letype)) {
8287 genSignedRightShift (ic);
8291 /* signed & unsigned types are treated the same : i.e. the
8292 signed is NOT propagated inwards : quoting from the
8293 ANSI - standard : "for E1 >> E2, is equivalent to division
8294 by 2**E2 if unsigned or if it has a non-negative value,
8295 otherwise the result is implementation defined ", MY definition
8296 is that the sign does not get propagated */
8298 right = IC_RIGHT(ic);
8300 result = IC_RESULT(ic);
8302 pic16_aopOp(right,ic,FALSE);
8304 /* if the shift count is known then do it
8305 as efficiently as possible */
8306 if (AOP_TYPE(right) == AOP_LIT) {
8307 genRightShiftLiteral (left,right,result,ic, 0);
8311 /* shift count is unknown then we have to form
8312 a loop get the loop count in B : Note: we take
8313 only the lower order byte since shifting
8314 more that 32 bits make no sense anyway, ( the
8315 largest size of an object can be only 32 bits ) */
8317 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8318 pic16_emitcode("inc","b");
8319 pic16_aopOp(left,ic,FALSE);
8320 pic16_aopOp(result,ic,FALSE);
8322 /* now move the left to the result if they are not the
8324 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8325 AOP_SIZE(result) > 1) {
8327 size = AOP_SIZE(result);
8330 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8331 if (*l == '@' && IS_AOP_PREG(result)) {
8333 pic16_emitcode("mov","a,%s",l);
8334 pic16_aopPut(AOP(result),"a",offset);
8336 pic16_aopPut(AOP(result),l,offset);
8341 tlbl = newiTempLabel(NULL);
8342 tlbl1= newiTempLabel(NULL);
8343 size = AOP_SIZE(result);
8346 /* if it is only one byte then */
8349 tlbl = newiTempLabel(NULL);
8350 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8351 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8352 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8355 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8356 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8357 pic16_emitpLabel(tlbl->key);
8358 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8359 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8361 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8366 reAdjustPreg(AOP(result));
8367 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8368 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8371 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8373 pic16_emitcode("rrc","a");
8374 pic16_aopPut(AOP(result),"a",offset--);
8376 reAdjustPreg(AOP(result));
8378 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8379 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8382 pic16_freeAsmop(left,NULL,ic,TRUE);
8383 pic16_freeAsmop (right,NULL,ic,TRUE);
8384 pic16_freeAsmop(result,NULL,ic,TRUE);
8387 /*-----------------------------------------------------------------*/
8388 /* genUnpackBits - generates code for unpacking bits */
8389 /*-----------------------------------------------------------------*/
8390 static void genUnpackBits (operand *result, char *rname, int ptype)
8397 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8398 etype = getSpec(operandType(result));
8400 /* read the first byte */
8407 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8410 pic16_emitcode("clr","a");
8411 pic16_emitcode("movc","a","@a+dptr");
8416 /* if we have bitdisplacement then it fits */
8417 /* into this byte completely or if length is */
8418 /* less than a byte */
8419 if ((shCnt = SPEC_BSTR(etype)) ||
8420 (SPEC_BLEN(etype) <= 8)) {
8422 /* shift right acc */
8425 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8426 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8428 /* VR -- normally I would use the following, but since we use the hack,
8429 * to avoid the masking from AccRsh, why not mask it right now? */
8432 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8435 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8441 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8442 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8445 /* bit field did not fit in a byte */
8446 rlen = SPEC_BLEN(etype) - 8;
8447 pic16_aopPut(AOP(result),"a",offset++);
8454 pic16_emitcode("inc","%s",rname);
8455 pic16_emitcode("mov","a,@%s",rname);
8459 pic16_emitcode("inc","%s",rname);
8460 pic16_emitcode("movx","a,@%s",rname);
8464 pic16_emitcode("inc","dptr");
8465 pic16_emitcode("movx","a,@dptr");
8469 pic16_emitcode("clr","a");
8470 pic16_emitcode("inc","dptr");
8471 pic16_emitcode("movc","a","@a+dptr");
8475 pic16_emitcode("inc","dptr");
8476 pic16_emitcode("lcall","__gptrget");
8481 /* if we are done */
8485 pic16_aopPut(AOP(result),"a",offset++);
8490 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8491 pic16_aopPut(AOP(result),"a",offset);
8498 static void genDataPointerGet(operand *left,
8502 int size, offset = 0, leoffset=0 ;
8504 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8505 pic16_aopOp(result, ic, FALSE);
8507 size = AOP_SIZE(result);
8508 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
8512 /* The following tests may save a redudant movff instruction when
8513 * accessing unions */
8515 /* if they are the same */
8516 if (operandsEqu (left, result)) {
8517 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
8521 /* if they are the same registers */
8522 if (pic16_sameRegs(AOP(left),AOP(result))) {
8523 DEBUGpic16_emitcode("; ***", "left and result registers are same");
8529 if ( AOP_TYPE(left) == AOP_PCODE) {
8530 fprintf(stderr,"genDataPointerGet %s, %d\n",
8531 AOP(left)->aopu.pcop->name,
8532 (AOP(left)->aopu.pcop->type == PO_DIR)?
8533 PCOR(AOP(left)->aopu.pcop)->instance:
8534 PCOI(AOP(left)->aopu.pcop)->offset);
8538 if(AOP(left)->aopu.pcop->type == PO_DIR)
8539 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
8541 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8544 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
8546 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
8547 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
8548 mov2w(AOP(left), leoffset);
8549 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
8551 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
8552 pic16_popGet(AOP(left), leoffset),
8553 pic16_popGet(AOP(result), offset)));
8561 pic16_freeAsmop(result,NULL,ic,TRUE);
8564 void pic16_loadFSR0(operand *op)
8566 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
8570 /*-----------------------------------------------------------------*/
8571 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8572 /*-----------------------------------------------------------------*/
8573 static void genNearPointerGet (operand *left,
8578 //regs *preg = NULL ;
8579 sym_link *rtype, *retype;
8580 sym_link *ltype = operandType(left);
8582 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8584 rtype = operandType(result);
8585 retype= getSpec(rtype);
8587 pic16_aopOp(left,ic,FALSE);
8589 /* if left is rematerialisable and
8590 * result is not bit variable type and
8591 * the left is pointer to data space i.e
8592 * lower 128 bytes of space */
8593 if (AOP_TYPE(left) == AOP_PCODE
8594 && !IS_BITFIELD(retype)
8595 && DCL_TYPE(ltype) == POINTER) {
8597 genDataPointerGet (left,result,ic);
8598 pic16_freeAsmop(left, NULL, ic, TRUE);
8602 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8604 /* if the value is already in a pointer register
8605 * then don't need anything more */
8606 if (!AOP_INPREG(AOP(left))) {
8607 /* otherwise get a free pointer register */
8608 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8610 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
8611 pic16_loadFSR0( left );
8614 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8616 pic16_aopOp (result,ic,FALSE);
8618 /* if bitfield then unpack the bits */
8619 if (IS_BITFIELD(retype))
8620 genUnpackBits (result, NULL, POINTER);
8622 /* we have can just get the values */
8623 int size = AOP_SIZE(result);
8626 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8629 /* fsr0 is loaded already -- VR */
8630 // pic16_loadFSR0( left );
8632 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8633 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8637 pic16_emitpcode(POC_MOVFF,
8638 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
8639 pic16_popGet(AOP(result), offset++)));
8641 pic16_emitpcode(POC_MOVFF,
8642 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
8643 pic16_popGet(AOP(result), offset++)));
8647 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
8648 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8650 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8654 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8656 pic16_emitcode("mov","a,@%s",rname);
8657 pic16_aopPut(AOP(result),"a",offset);
8659 sprintf(buffer,"@%s",rname);
8660 pic16_aopPut(AOP(result),buffer,offset);
8664 pic16_emitcode("inc","%s",rname);
8669 /* now some housekeeping stuff */
8671 /* we had to allocate for this iCode */
8672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8673 pic16_freeAsmop(NULL,aop,ic,TRUE);
8675 /* we did not allocate which means left
8676 already in a pointer register, then
8677 if size > 0 && this could be used again
8678 we have to point it back to where it
8680 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8681 if (AOP_SIZE(result) > 1 &&
8682 !OP_SYMBOL(left)->remat &&
8683 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8685 // int size = AOP_SIZE(result) - 1;
8687 // pic16_emitcode("dec","%s",rname);
8692 pic16_freeAsmop(left,NULL,ic,TRUE);
8693 pic16_freeAsmop(result,NULL,ic,TRUE);
8697 /*-----------------------------------------------------------------*/
8698 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8699 /*-----------------------------------------------------------------*/
8700 static void genPagedPointerGet (operand *left,
8707 sym_link *rtype, *retype;
8709 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8711 rtype = operandType(result);
8712 retype= getSpec(rtype);
8714 pic16_aopOp(left,ic,FALSE);
8716 /* if the value is already in a pointer register
8717 then don't need anything more */
8718 if (!AOP_INPREG(AOP(left))) {
8719 /* otherwise get a free pointer register */
8721 preg = getFreePtr(ic,&aop,FALSE);
8722 pic16_emitcode("mov","%s,%s",
8724 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8725 rname = preg->name ;
8727 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8729 pic16_freeAsmop(left,NULL,ic,TRUE);
8730 pic16_aopOp (result,ic,FALSE);
8732 /* if bitfield then unpack the bits */
8733 if (IS_BITFIELD(retype))
8734 genUnpackBits (result,rname,PPOINTER);
8736 /* we have can just get the values */
8737 int size = AOP_SIZE(result);
8742 pic16_emitcode("movx","a,@%s",rname);
8743 pic16_aopPut(AOP(result),"a",offset);
8748 pic16_emitcode("inc","%s",rname);
8752 /* now some housekeeping stuff */
8754 /* we had to allocate for this iCode */
8755 pic16_freeAsmop(NULL,aop,ic,TRUE);
8757 /* we did not allocate which means left
8758 already in a pointer register, then
8759 if size > 0 && this could be used again
8760 we have to point it back to where it
8762 if (AOP_SIZE(result) > 1 &&
8763 !OP_SYMBOL(left)->remat &&
8764 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8766 int size = AOP_SIZE(result) - 1;
8768 pic16_emitcode("dec","%s",rname);
8773 pic16_freeAsmop(result,NULL,ic,TRUE);
8778 /*-----------------------------------------------------------------*/
8779 /* genFarPointerGet - gget value from far space */
8780 /*-----------------------------------------------------------------*/
8781 static void genFarPointerGet (operand *left,
8782 operand *result, iCode *ic)
8785 sym_link *retype = getSpec(operandType(result));
8787 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8789 pic16_aopOp(left,ic,FALSE);
8791 /* if the operand is already in dptr
8792 then we do nothing else we move the value to dptr */
8793 if (AOP_TYPE(left) != AOP_STR) {
8794 /* if this is remateriazable */
8795 if (AOP_TYPE(left) == AOP_IMMD)
8796 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8797 else { /* we need to get it byte by byte */
8798 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8799 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8800 if (options.model == MODEL_FLAT24)
8802 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8806 /* so dptr know contains the address */
8807 pic16_freeAsmop(left,NULL,ic,TRUE);
8808 pic16_aopOp(result,ic,FALSE);
8810 /* if bit then unpack */
8811 if (IS_BITFIELD(retype))
8812 genUnpackBits(result,"dptr",FPOINTER);
8814 size = AOP_SIZE(result);
8818 pic16_emitcode("movx","a,@dptr");
8819 pic16_aopPut(AOP(result),"a",offset++);
8821 pic16_emitcode("inc","dptr");
8825 pic16_freeAsmop(result,NULL,ic,TRUE);
8828 /*-----------------------------------------------------------------*/
8829 /* genCodePointerGet - get value from code space */
8830 /*-----------------------------------------------------------------*/
8831 static void genCodePointerGet (operand *left,
8832 operand *result, iCode *ic)
8835 sym_link *retype = getSpec(operandType(result));
8837 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8839 pic16_aopOp(left,ic,FALSE);
8841 /* if the operand is already in dptr
8842 then we do nothing else we move the value to dptr */
8843 if (AOP_TYPE(left) != AOP_STR) {
8844 /* if this is remateriazable */
8845 if (AOP_TYPE(left) == AOP_IMMD)
8846 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8847 else { /* we need to get it byte by byte */
8848 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8849 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8850 if (options.model == MODEL_FLAT24)
8852 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8856 /* so dptr know contains the address */
8857 pic16_freeAsmop(left,NULL,ic,TRUE);
8858 pic16_aopOp(result,ic,FALSE);
8860 /* if bit then unpack */
8861 if (IS_BITFIELD(retype))
8862 genUnpackBits(result,"dptr",CPOINTER);
8864 size = AOP_SIZE(result);
8868 pic16_emitcode("clr","a");
8869 pic16_emitcode("movc","a,@a+dptr");
8870 pic16_aopPut(AOP(result),"a",offset++);
8872 pic16_emitcode("inc","dptr");
8876 pic16_freeAsmop(result,NULL,ic,TRUE);
8879 /*-----------------------------------------------------------------*/
8880 /* genGenPointerGet - gget value from generic pointer space */
8881 /*-----------------------------------------------------------------*/
8882 static void genGenPointerGet (operand *left,
8883 operand *result, iCode *ic)
8885 int size, offset, lit;
8886 sym_link *retype = getSpec(operandType(result));
8888 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8889 pic16_aopOp(left,ic,FALSE);
8890 pic16_aopOp(result,ic,FALSE);
8891 size = AOP_SIZE(result);
8893 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8895 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
8897 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
8898 // load FSR0 from immediate
8899 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
8901 // pic16_loadFSR0( left );
8906 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8908 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8915 else { /* we need to get it byte by byte */
8916 // set up FSR0 with address from left
8917 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
8918 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
8924 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8926 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8933 /* if bit then unpack */
8934 if (IS_BITFIELD(retype))
8935 genUnpackBits(result,"BAD",GPOINTER);
8938 pic16_freeAsmop(left,NULL,ic,TRUE);
8939 pic16_freeAsmop(result,NULL,ic,TRUE);
8943 /*-----------------------------------------------------------------*/
8944 /* genConstPointerGet - get value from const generic pointer space */
8945 /*-----------------------------------------------------------------*/
8946 static void genConstPointerGet (operand *left,
8947 operand *result, iCode *ic)
8949 //sym_link *retype = getSpec(operandType(result));
8950 symbol *albl = newiTempLabel(NULL);
8951 symbol *blbl = newiTempLabel(NULL);
8954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8955 pic16_aopOp(left,ic,FALSE);
8956 pic16_aopOp(result,ic,FALSE);
8959 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8961 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8963 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8964 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8965 pic16_emitpLabel(albl->key);
8967 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8969 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8970 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8971 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8972 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8973 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8975 pic16_emitpLabel(blbl->key);
8977 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8980 pic16_freeAsmop(left,NULL,ic,TRUE);
8981 pic16_freeAsmop(result,NULL,ic,TRUE);
8984 /*-----------------------------------------------------------------*/
8985 /* genPointerGet - generate code for pointer get */
8986 /*-----------------------------------------------------------------*/
8987 static void genPointerGet (iCode *ic)
8989 operand *left, *result ;
8990 sym_link *type, *etype;
8993 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8996 result = IC_RESULT(ic) ;
8998 /* depending on the type of pointer we need to
8999 move it to the correct pointer register */
9000 type = operandType(left);
9001 etype = getSpec(type);
9004 if (IS_PTR_CONST(type))
9006 if (IS_CODEPTR(type))
9008 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9010 /* if left is of type of pointer then it is simple */
9011 if (IS_PTR(type) && !IS_FUNC(type->next))
9012 p_type = DCL_TYPE(type);
9014 /* we have to go by the storage class */
9015 p_type = PTR_TYPE(SPEC_OCLS(etype));
9017 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9019 if (SPEC_OCLS(etype)->codesp ) {
9020 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9021 //p_type = CPOINTER ;
9024 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9025 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9026 /*p_type = FPOINTER ;*/
9028 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9029 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9030 /* p_type = PPOINTER; */
9032 if (SPEC_OCLS(etype) == idata )
9033 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9034 /* p_type = IPOINTER; */
9036 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9037 /* p_type = POINTER ; */
9040 /* now that we have the pointer type we assign
9041 the pointer values */
9046 genNearPointerGet (left,result,ic);
9050 genPagedPointerGet(left,result,ic);
9054 genFarPointerGet (left,result,ic);
9058 genConstPointerGet (left,result,ic);
9059 //pic16_emitcodePointerGet (left,result,ic);
9064 if (IS_PTR_CONST(type))
9065 genConstPointerGet (left,result,ic);
9068 genGenPointerGet (left,result,ic);
9074 /*-----------------------------------------------------------------*/
9075 /* genPackBits - generates code for packed bit storage */
9076 /*-----------------------------------------------------------------*/
9077 static void genPackBits (sym_link *etype ,
9079 char *rname, int p_type)
9087 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9088 blen = SPEC_BLEN(etype);
9089 bstr = SPEC_BSTR(etype);
9091 if(AOP_TYPE(right) == AOP_LIT) {
9092 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9095 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9097 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9100 /* if the bit lenth is less than or */
9101 /* it exactly fits a byte then */
9102 if((shCnt=SPEC_BSTR(etype))
9103 || SPEC_BLEN(etype) <= 8 ) {
9105 /* shift left acc */
9108 /* using PRODL as a temporary register here */
9109 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9115 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9116 // pic16_emitcode ("mov","b,a");
9117 // pic16_emitcode("mov","a,@%s",rname);
9121 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9122 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9123 (unsigned char)(0xff >> (8-bstr))) ));
9124 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9125 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9129 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9130 ((unsigned char)(0xFF << (blen+bstr)) |
9131 (unsigned char)(0xFF >> (8-bstr)) ) );
9132 pic16_emitcode ("orl","a,b");
9133 if (p_type == GPOINTER)
9134 pic16_emitcode("pop","b");
9139 pic16_emitcode("mov","@%s,a",rname);
9142 pic16_emitcode("movx","@dptr,a");
9145 DEBUGpic16_emitcode(";lcall","__gptrput");
9154 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9155 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9160 if ( SPEC_BLEN(etype) <= 8 )
9163 pic16_emitcode("inc","%s",rname);
9164 rLen = SPEC_BLEN(etype) ;
9168 /* now generate for lengths greater than one byte */
9171 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9181 pic16_emitcode("mov","@%s,a",rname);
9183 pic16_emitcode("mov","@%s,%s",rname,l);
9188 pic16_emitcode("movx","@dptr,a");
9193 DEBUGpic16_emitcode(";lcall","__gptrput");
9196 pic16_emitcode ("inc","%s",rname);
9201 /* last last was not complete */
9203 /* save the byte & read byte */
9206 pic16_emitcode ("mov","b,a");
9207 pic16_emitcode("mov","a,@%s",rname);
9211 pic16_emitcode ("mov","b,a");
9212 pic16_emitcode("movx","a,@dptr");
9216 pic16_emitcode ("push","b");
9217 pic16_emitcode ("push","acc");
9218 pic16_emitcode ("lcall","__gptrget");
9219 pic16_emitcode ("pop","b");
9223 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9224 pic16_emitcode ("orl","a,b");
9227 if (p_type == GPOINTER)
9228 pic16_emitcode("pop","b");
9233 pic16_emitcode("mov","@%s,a",rname);
9237 pic16_emitcode("movx","@dptr,a");
9241 DEBUGpic16_emitcode(";lcall","__gptrput");
9245 /*-----------------------------------------------------------------*/
9246 /* genDataPointerSet - remat pointer to data space */
9247 /*-----------------------------------------------------------------*/
9248 static void genDataPointerSet(operand *right,
9252 int size, offset = 0, resoffset=0 ;
9254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9255 pic16_aopOp(right,ic,FALSE);
9257 size = AOP_SIZE(right);
9258 fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9261 if ( AOP_TYPE(result) == AOP_PCODE) {
9262 fprintf(stderr,"genDataPointerSet %s, %d\n",
9263 AOP(result)->aopu.pcop->name,
9264 (AOP(result)->aopu.pcop->type == PO_DIR)?
9265 PCOR(AOP(result)->aopu.pcop)->instance:
9266 PCOI(AOP(result)->aopu.pcop)->offset);
9270 if(AOP(result)->aopu.pcop->type == PO_DIR)
9271 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9274 if (AOP_TYPE(right) == AOP_LIT) {
9275 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9277 lit = lit >> (8*offset);
9279 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9280 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9282 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),resoffset));
9285 mov2w(AOP(right), offset);
9286 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),resoffset));
9292 pic16_freeAsmop(right,NULL,ic,TRUE);
9297 /*-----------------------------------------------------------------*/
9298 /* genNearPointerSet - pic16_emitcode for near pointer put */
9299 /*-----------------------------------------------------------------*/
9300 static void genNearPointerSet (operand *right,
9307 sym_link *ptype = operandType(result);
9310 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9311 retype= getSpec(operandType(right));
9312 resetype = getSpec(operandType(result));
9314 pic16_aopOp(result,ic,FALSE);
9316 /* if the result is rematerializable &
9317 * in data space & not a bit variable */
9319 /* and result is not a bit variable */
9320 if (AOP_TYPE(result) == AOP_PCODE
9321 // && AOP_TYPE(result) == AOP_IMMD
9322 && DCL_TYPE(ptype) == POINTER
9323 && !IS_BITFIELD(retype)
9324 && !IS_BITFIELD(resetype)) {
9326 genDataPointerSet (right,result,ic);
9327 pic16_freeAsmop(result,NULL,ic,TRUE);
9331 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9332 pic16_aopOp(right,ic,FALSE);
9333 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9335 /* if the value is already in a pointer register
9336 * then don't need anything more */
9337 if (!AOP_INPREG(AOP(result))) {
9338 /* otherwise get a free pointer register */
9339 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9341 pic16_loadFSR0( result );
9344 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9346 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9348 /* if bitfield then unpack the bits */
9349 if (IS_BITFIELD(resetype)) {
9350 genPackBits (resetype, right, NULL, POINTER);
9352 /* we have can just get the values */
9353 int size = AOP_SIZE(right);
9356 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9358 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9361 //pic16_emitcode("mov","@%s,a",rname);
9362 pic16_emitcode("movf","indf0,w ;1");
9365 if (AOP_TYPE(right) == AOP_LIT) {
9366 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9369 pic16_emitcode("movlw","%s",l);
9370 pic16_emitcode("movwf","indf0 ;2");
9372 pic16_emitcode("clrf","indf0");
9374 pic16_emitcode("movf","%s,w",l);
9375 pic16_emitcode("movwf","indf0 ;2");
9377 //pic16_emitcode("mov","@%s,%s",rname,l);
9380 pic16_emitcode("incf","fsr0,f ;3");
9381 //pic16_emitcode("inc","%s",rname);
9386 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9387 /* now some housekeeping stuff */
9389 /* we had to allocate for this iCode */
9390 pic16_freeAsmop(NULL,aop,ic,TRUE);
9392 /* we did not allocate which means left
9393 * already in a pointer register, then
9394 * if size > 0 && this could be used again
9395 * we have to point it back to where it
9397 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9398 if (AOP_SIZE(right) > 1
9399 && !OP_SYMBOL(result)->remat
9400 && ( OP_SYMBOL(result)->liveTo > ic->seq
9403 int size = AOP_SIZE(right) - 1;
9406 pic16_emitcode("decf","fsr0,f");
9407 //pic16_emitcode("dec","%s",rname);
9411 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9414 pic16_freeAsmop(right,NULL,ic,TRUE);
9415 pic16_freeAsmop(result,NULL,ic,TRUE);
9418 /*-----------------------------------------------------------------*/
9419 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9420 /*-----------------------------------------------------------------*/
9421 static void genPagedPointerSet (operand *right,
9430 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9432 retype= getSpec(operandType(right));
9434 pic16_aopOp(result,ic,FALSE);
9436 /* if the value is already in a pointer register
9437 then don't need anything more */
9438 if (!AOP_INPREG(AOP(result))) {
9439 /* otherwise get a free pointer register */
9441 preg = getFreePtr(ic,&aop,FALSE);
9442 pic16_emitcode("mov","%s,%s",
9444 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9445 rname = preg->name ;
9447 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9449 pic16_freeAsmop(result,NULL,ic,TRUE);
9450 pic16_aopOp (right,ic,FALSE);
9452 /* if bitfield then unpack the bits */
9453 if (IS_BITFIELD(retype))
9454 genPackBits (retype,right,rname,PPOINTER);
9456 /* we have can just get the values */
9457 int size = AOP_SIZE(right);
9461 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9464 pic16_emitcode("movx","@%s,a",rname);
9467 pic16_emitcode("inc","%s",rname);
9473 /* now some housekeeping stuff */
9475 /* we had to allocate for this iCode */
9476 pic16_freeAsmop(NULL,aop,ic,TRUE);
9478 /* we did not allocate which means left
9479 already in a pointer register, then
9480 if size > 0 && this could be used again
9481 we have to point it back to where it
9483 if (AOP_SIZE(right) > 1 &&
9484 !OP_SYMBOL(result)->remat &&
9485 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9487 int size = AOP_SIZE(right) - 1;
9489 pic16_emitcode("dec","%s",rname);
9494 pic16_freeAsmop(right,NULL,ic,TRUE);
9499 /*-----------------------------------------------------------------*/
9500 /* genFarPointerSet - set value from far space */
9501 /*-----------------------------------------------------------------*/
9502 static void genFarPointerSet (operand *right,
9503 operand *result, iCode *ic)
9506 sym_link *retype = getSpec(operandType(right));
9508 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9509 pic16_aopOp(result,ic,FALSE);
9511 /* if the operand is already in dptr
9512 then we do nothing else we move the value to dptr */
9513 if (AOP_TYPE(result) != AOP_STR) {
9514 /* if this is remateriazable */
9515 if (AOP_TYPE(result) == AOP_IMMD)
9516 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9517 else { /* we need to get it byte by byte */
9518 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9519 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9520 if (options.model == MODEL_FLAT24)
9522 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9526 /* so dptr know contains the address */
9527 pic16_freeAsmop(result,NULL,ic,TRUE);
9528 pic16_aopOp(right,ic,FALSE);
9530 /* if bit then unpack */
9531 if (IS_BITFIELD(retype))
9532 genPackBits(retype,right,"dptr",FPOINTER);
9534 size = AOP_SIZE(right);
9538 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9540 pic16_emitcode("movx","@dptr,a");
9542 pic16_emitcode("inc","dptr");
9546 pic16_freeAsmop(right,NULL,ic,TRUE);
9549 /*-----------------------------------------------------------------*/
9550 /* genGenPointerSet - set value from generic pointer space */
9551 /*-----------------------------------------------------------------*/
9552 static void genGenPointerSet (operand *right,
9553 operand *result, iCode *ic)
9555 int size, offset, lit;
9556 sym_link *retype = getSpec(operandType(right));
9558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9560 pic16_aopOp(result,ic,FALSE);
9561 pic16_aopOp(right,ic,FALSE);
9562 size = AOP_SIZE(right);
9565 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9567 /* if the operand is already in dptr
9568 then we do nothing else we move the value to dptr */
9569 if (AOP_TYPE(result) != AOP_STR) {
9570 /* if this is remateriazable */
9571 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9572 // WARNING: anythig until "else" is untested!
9573 if (AOP_TYPE(result) == AOP_IMMD) {
9574 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9575 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
9576 // load FSR0 from immediate
9577 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9581 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9583 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9589 else { /* we need to get it byte by byte */
9590 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9591 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9593 // set up FSR0 with address of result
9594 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9595 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9597 /* hack hack! see if this the FSR. If so don't load W */
9598 if(AOP_TYPE(right) != AOP_ACC) {
9600 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9604 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9606 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9613 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9614 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9616 } // if (AOP_TYPE(result) != AOP_IMMD)
9618 } // if (AOP_TYPE(result) != AOP_STR)
9619 /* so dptr know contains the address */
9622 /* if bit then unpack */
9623 if (IS_BITFIELD(retype))
9624 genPackBits(retype,right,"dptr",GPOINTER);
9626 size = AOP_SIZE(right);
9629 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9631 // set up FSR0 with address of result
9632 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9633 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9636 if (AOP_TYPE(right) == AOP_LIT) {
9637 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9639 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
9641 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9643 } else { // no literal
9645 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9647 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9655 pic16_freeAsmop(right,NULL,ic,TRUE);
9656 pic16_freeAsmop(result,NULL,ic,TRUE);
9659 /*-----------------------------------------------------------------*/
9660 /* genPointerSet - stores the value into a pointer location */
9661 /*-----------------------------------------------------------------*/
9662 static void genPointerSet (iCode *ic)
9664 operand *right, *result ;
9665 sym_link *type, *etype;
9668 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9670 right = IC_RIGHT(ic);
9671 result = IC_RESULT(ic) ;
9673 /* depending on the type of pointer we need to
9674 move it to the correct pointer register */
9675 type = operandType(result);
9676 etype = getSpec(type);
9677 /* if left is of type of pointer then it is simple */
9678 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9679 p_type = DCL_TYPE(type);
9682 /* we have to go by the storage class */
9683 p_type = PTR_TYPE(SPEC_OCLS(etype));
9685 /* if (SPEC_OCLS(etype)->codesp ) { */
9686 /* p_type = CPOINTER ; */
9689 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9690 /* p_type = FPOINTER ; */
9692 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9693 /* p_type = PPOINTER ; */
9695 /* if (SPEC_OCLS(etype) == idata ) */
9696 /* p_type = IPOINTER ; */
9698 /* p_type = POINTER ; */
9701 /* now that we have the pointer type we assign
9702 the pointer values */
9707 genNearPointerSet (right,result,ic);
9711 genPagedPointerSet (right,result,ic);
9715 genFarPointerSet (right,result,ic);
9719 genGenPointerSet (right,result,ic);
9723 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9724 "genPointerSet: illegal pointer type");
9728 /*-----------------------------------------------------------------*/
9729 /* genIfx - generate code for Ifx statement */
9730 /*-----------------------------------------------------------------*/
9731 static void genIfx (iCode *ic, iCode *popIc)
9733 operand *cond = IC_COND(ic);
9736 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9738 pic16_aopOp(cond,ic,FALSE);
9740 /* get the value into acc */
9741 if (AOP_TYPE(cond) != AOP_CRY)
9742 pic16_toBoolean(cond);
9745 /* the result is now in the accumulator */
9746 pic16_freeAsmop(cond,NULL,ic,TRUE);
9748 /* if there was something to be popped then do it */
9752 /* if the condition is a bit variable */
9753 if (isbit && IS_ITEMP(cond) &&
9755 genIfxJump(ic,SPIL_LOC(cond)->rname);
9756 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9759 if (isbit && !IS_ITEMP(cond))
9760 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9768 /*-----------------------------------------------------------------*/
9769 /* genAddrOf - generates code for address of */
9770 /*-----------------------------------------------------------------*/
9771 static void genAddrOf (iCode *ic)
9773 operand *result, *left;
9775 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9776 pCodeOp *pcop0, *pcop1, *pcop2;
9778 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9780 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9781 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9783 sym = OP_SYMBOL( left );
9785 size = AOP_SIZE(IC_RESULT(ic));
9787 if(pic16_debug_verbose) {
9788 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9789 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9792 /* Assume that what we want the address of is in data space
9793 * since there is no stack on the PIC, yet! -- VR */
9795 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9798 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9801 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9805 pic16_emitpcode(POC_MOVLW, pcop0);
9806 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9807 pic16_emitpcode(POC_MOVLW, pcop1);
9808 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9809 pic16_emitpcode(POC_MOVLW, pcop2);
9810 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9813 pic16_emitpcode(POC_MOVLW, pcop0);
9814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9815 pic16_emitpcode(POC_MOVLW, pcop1);
9816 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9818 pic16_emitpcode(POC_MOVLW, pcop0);
9819 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9822 pic16_freeAsmop(result,NULL,ic,TRUE);
9823 pic16_freeAsmop(left, NULL, ic, FALSE);
9828 /*-----------------------------------------------------------------*/
9829 /* genFarFarAssign - assignment when both are in far space */
9830 /*-----------------------------------------------------------------*/
9831 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9833 int size = AOP_SIZE(right);
9836 /* first push the right side on to the stack */
9838 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9840 pic16_emitcode ("push","acc");
9843 pic16_freeAsmop(right,NULL,ic,FALSE);
9844 /* now assign DPTR to result */
9845 pic16_aopOp(result,ic,FALSE);
9846 size = AOP_SIZE(result);
9848 pic16_emitcode ("pop","acc");
9849 pic16_aopPut(AOP(result),"a",--offset);
9851 pic16_freeAsmop(result,NULL,ic,FALSE);
9856 /*-----------------------------------------------------------------*/
9857 /* genAssign - generate code for assignment */
9858 /*-----------------------------------------------------------------*/
9859 static void genAssign (iCode *ic)
9861 operand *result, *right;
9862 int size, offset,know_W;
9863 unsigned long lit = 0L;
9865 result = IC_RESULT(ic);
9866 right = IC_RIGHT(ic) ;
9868 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9870 /* if they are the same */
9871 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9874 pic16_aopOp(right,ic,FALSE);
9875 pic16_aopOp(result,ic,TRUE);
9877 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9879 /* if they are the same registers */
9880 if (pic16_sameRegs(AOP(right),AOP(result)))
9883 /* if the result is a bit */
9884 if (AOP_TYPE(result) == AOP_CRY) {
9885 /* if the right size is a literal then
9886 we know what the value is */
9887 if (AOP_TYPE(right) == AOP_LIT) {
9889 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9890 pic16_popGet(AOP(result),0));
9892 if (((int) operandLitValue(right)))
9893 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9894 AOP(result)->aopu.aop_dir,
9895 AOP(result)->aopu.aop_dir);
9897 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9898 AOP(result)->aopu.aop_dir,
9899 AOP(result)->aopu.aop_dir);
9903 /* the right is also a bit variable */
9904 if (AOP_TYPE(right) == AOP_CRY) {
9905 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9906 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9907 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9909 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9910 AOP(result)->aopu.aop_dir,
9911 AOP(result)->aopu.aop_dir);
9912 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9913 AOP(right)->aopu.aop_dir,
9914 AOP(right)->aopu.aop_dir);
9915 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9916 AOP(result)->aopu.aop_dir,
9917 AOP(result)->aopu.aop_dir);
9922 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9923 pic16_toBoolean(right);
9925 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9926 //pic16_aopPut(AOP(result),"a",0);
9930 /* bit variables done */
9932 size = AOP_SIZE(result);
9934 if(AOP_TYPE(right) == AOP_LIT)
9935 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9937 /* VR - What is this?! */
9938 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9940 if(aopIdx(AOP(result),0) == 4) {
9941 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9942 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9943 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9946 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9951 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9952 if(AOP_TYPE(right) == AOP_LIT) {
9954 if(know_W != (lit&0xff))
9955 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9957 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9959 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9963 } else if (AOP_TYPE(right) == AOP_CRY) {
9964 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9966 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9967 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9970 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9973 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9974 normally should work, but mind that the W register live range
9975 is not checked, so if the code generator assumes that the W
9976 is already loaded after such a pair, wrong code will be generated.
9978 Checking the live range is the next step.
9979 This is experimental code yet and has not been fully tested yet.
9980 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9981 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9983 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9985 /* This is the old code, which is assumed(?!) that works fine(!?) */
9987 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9988 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9997 pic16_freeAsmop (right,NULL,ic,FALSE);
9998 pic16_freeAsmop (result,NULL,ic,TRUE);
10001 /*-----------------------------------------------------------------*/
10002 /* genJumpTab - generates code for jump table */
10003 /*-----------------------------------------------------------------*/
10004 static void genJumpTab (iCode *ic)
10009 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10011 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10012 /* get the condition into accumulator */
10013 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10015 /* multiply by three */
10016 pic16_emitcode("add","a,acc");
10017 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10019 jtab = newiTempLabel(NULL);
10020 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10021 pic16_emitcode("jmp","@a+dptr");
10022 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10024 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10025 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10027 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10028 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10029 pic16_emitpLabel(jtab->key);
10031 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10033 /* now generate the jump labels */
10034 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10035 jtab = setNextItem(IC_JTLABELS(ic))) {
10036 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10037 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10043 /*-----------------------------------------------------------------*/
10044 /* genMixedOperation - gen code for operators between mixed types */
10045 /*-----------------------------------------------------------------*/
10047 TSD - Written for the PIC port - but this unfortunately is buggy.
10048 This routine is good in that it is able to efficiently promote
10049 types to different (larger) sizes. Unfortunately, the temporary
10050 variables that are optimized out by this routine are sometimes
10051 used in other places. So until I know how to really parse the
10052 iCode tree, I'm going to not be using this routine :(.
10054 static int genMixedOperation (iCode *ic)
10057 operand *result = IC_RESULT(ic);
10058 sym_link *ctype = operandType(IC_LEFT(ic));
10059 operand *right = IC_RIGHT(ic);
10065 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10067 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10073 nextright = IC_RIGHT(nextic);
10074 nextleft = IC_LEFT(nextic);
10075 nextresult = IC_RESULT(nextic);
10077 pic16_aopOp(right,ic,FALSE);
10078 pic16_aopOp(result,ic,FALSE);
10079 pic16_aopOp(nextright, nextic, FALSE);
10080 pic16_aopOp(nextleft, nextic, FALSE);
10081 pic16_aopOp(nextresult, nextic, FALSE);
10083 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10085 operand *t = right;
10089 pic16_emitcode(";remove right +","");
10091 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10093 operand *t = right;
10097 pic16_emitcode(";remove left +","");
10101 big = AOP_SIZE(nextleft);
10102 small = AOP_SIZE(nextright);
10104 switch(nextic->op) {
10107 pic16_emitcode(";optimize a +","");
10108 /* if unsigned or not an integral type */
10109 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10110 pic16_emitcode(";add a bit to something","");
10113 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10115 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10116 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10117 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10119 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10127 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10128 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10129 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10132 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10134 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10135 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10136 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10137 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10138 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10141 pic16_emitcode("rlf","known_zero,w");
10148 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10149 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10150 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10152 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10162 pic16_freeAsmop(right,NULL,ic,TRUE);
10163 pic16_freeAsmop(result,NULL,ic,TRUE);
10164 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10165 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10167 nextic->generated = 1;
10174 /*-----------------------------------------------------------------*/
10175 /* genCast - gen code for casting */
10176 /*-----------------------------------------------------------------*/
10177 static void genCast (iCode *ic)
10179 operand *result = IC_RESULT(ic);
10180 sym_link *ctype = operandType(IC_LEFT(ic));
10181 sym_link *rtype = operandType(IC_RIGHT(ic));
10182 operand *right = IC_RIGHT(ic);
10185 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10186 /* if they are equivalent then do nothing */
10187 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10190 pic16_aopOp(right,ic,FALSE) ;
10191 pic16_aopOp(result,ic,FALSE);
10193 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10195 /* if the result is a bit */
10196 if (AOP_TYPE(result) == AOP_CRY) {
10198 /* if the right size is a literal then
10199 * we know what the value is */
10200 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10202 if (AOP_TYPE(right) == AOP_LIT) {
10203 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10204 pic16_popGet(AOP(result),0));
10206 if (((int) operandLitValue(right)))
10207 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10208 AOP(result)->aopu.aop_dir,
10209 AOP(result)->aopu.aop_dir);
10211 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10212 AOP(result)->aopu.aop_dir,
10213 AOP(result)->aopu.aop_dir);
10217 /* the right is also a bit variable */
10218 if (AOP_TYPE(right) == AOP_CRY) {
10220 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10222 pic16_emitcode("clrc","");
10223 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10224 AOP(right)->aopu.aop_dir,
10225 AOP(right)->aopu.aop_dir);
10226 pic16_aopPut(AOP(result),"c",0);
10230 /* we need to or */
10231 if (AOP_TYPE(right) == AOP_REG) {
10232 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10233 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10234 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10236 pic16_toBoolean(right);
10237 pic16_aopPut(AOP(result),"a",0);
10241 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10244 size = AOP_SIZE(result);
10246 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10248 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10249 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10250 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10253 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10258 /* if they are the same size : or less */
10259 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10261 /* if they are in the same place */
10262 if (pic16_sameRegs(AOP(right),AOP(result)))
10265 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10267 if (IS_PTR_CONST(rtype))
10269 if (IS_CODEPTR(rtype))
10271 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10274 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10276 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10278 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10281 if(AOP_TYPE(right) == AOP_IMMD) {
10282 pCodeOp *pcop0, *pcop1, *pcop2;
10283 symbol *sym = OP_SYMBOL( right );
10285 size = AOP_SIZE(result);
10287 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10289 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10291 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10294 pic16_emitpcode(POC_MOVLW, pcop0);
10295 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10296 pic16_emitpcode(POC_MOVLW, pcop1);
10297 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10298 pic16_emitpcode(POC_MOVLW, pcop2);
10299 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10302 pic16_emitpcode(POC_MOVLW, pcop0);
10303 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10304 pic16_emitpcode(POC_MOVLW, pcop1);
10305 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10307 pic16_emitpcode(POC_MOVLW, pcop0);
10308 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10312 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10313 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10314 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10315 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10316 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10317 if(AOP_SIZE(result) <2)
10318 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10320 /* if they in different places then copy */
10321 size = AOP_SIZE(result);
10324 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10325 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10332 /* if the result is of type pointer */
10333 if (IS_PTR(ctype)) {
10335 sym_link *type = operandType(right);
10336 sym_link *etype = getSpec(type);
10338 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10340 /* pointer to generic pointer */
10341 if (IS_GENPTR(ctype)) {
10345 p_type = DCL_TYPE(type);
10347 /* we have to go by the storage class */
10348 p_type = PTR_TYPE(SPEC_OCLS(etype));
10350 /* if (SPEC_OCLS(etype)->codesp ) */
10351 /* p_type = CPOINTER ; */
10353 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10354 /* p_type = FPOINTER ; */
10356 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10357 /* p_type = PPOINTER; */
10359 /* if (SPEC_OCLS(etype) == idata ) */
10360 /* p_type = IPOINTER ; */
10362 /* p_type = POINTER ; */
10365 /* the first two bytes are known */
10366 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10367 size = GPTRSIZE - 1;
10370 if(offset < AOP_SIZE(right)) {
10371 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10372 if ((AOP_TYPE(right) == AOP_PCODE) &&
10373 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10374 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10375 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10377 pic16_aopPut(AOP(result),
10378 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10382 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10385 /* the last byte depending on type */
10389 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10392 pic16_emitcode(";BUG!? ","%d",__LINE__);
10396 pic16_emitcode(";BUG!? ","%d",__LINE__);
10400 pic16_emitcode(";BUG!? ","%d",__LINE__);
10405 /* this should never happen */
10406 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10407 "got unknown pointer type");
10410 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10414 /* just copy the pointers */
10415 size = AOP_SIZE(result);
10418 pic16_aopPut(AOP(result),
10419 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10428 /* so we now know that the size of destination is greater
10429 than the size of the source.
10430 Now, if the next iCode is an operator then we might be
10431 able to optimize the operation without performing a cast.
10433 if(genMixedOperation(ic))
10436 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10438 /* we move to result for the size of source */
10439 size = AOP_SIZE(right);
10442 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10443 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10447 /* now depending on the sign of the destination */
10448 size = AOP_SIZE(result) - AOP_SIZE(right);
10449 /* if unsigned or not an integral type */
10450 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10452 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10454 /* we need to extend the sign :( */
10457 /* Save one instruction of casting char to int */
10458 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10459 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10460 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10462 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10465 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10467 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10469 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10472 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10477 pic16_freeAsmop(right,NULL,ic,TRUE);
10478 pic16_freeAsmop(result,NULL,ic,TRUE);
10482 /*-----------------------------------------------------------------*/
10483 /* genDjnz - generate decrement & jump if not zero instrucion */
10484 /*-----------------------------------------------------------------*/
10485 static int genDjnz (iCode *ic, iCode *ifx)
10487 symbol *lbl, *lbl1;
10488 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10493 /* if the if condition has a false label
10494 then we cannot save */
10498 /* if the minus is not of the form
10500 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10501 !IS_OP_LITERAL(IC_RIGHT(ic)))
10504 if (operandLitValue(IC_RIGHT(ic)) != 1)
10507 /* if the size of this greater than one then no
10509 if (getSize(operandType(IC_RESULT(ic))) > 1)
10512 /* otherwise we can save BIG */
10513 lbl = newiTempLabel(NULL);
10514 lbl1= newiTempLabel(NULL);
10516 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10518 if (IS_AOP_PREG(IC_RESULT(ic))) {
10519 pic16_emitcode("dec","%s",
10520 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10521 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10522 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10526 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10527 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10529 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10530 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10533 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10534 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10535 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10536 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10539 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10540 ifx->generated = 1;
10544 /*-----------------------------------------------------------------*/
10545 /* genReceive - generate code for a receive iCode */
10546 /*-----------------------------------------------------------------*/
10547 static void genReceive (iCode *ic)
10549 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10551 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10552 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10553 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10555 int size = getSize(operandType(IC_RESULT(ic)));
10556 int offset = pic16_fReturnSizePic - size;
10559 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10560 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10564 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10566 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10567 size = AOP_SIZE(IC_RESULT(ic));
10570 pic16_emitcode ("pop","acc");
10571 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10574 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10577 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10579 assignResultValue(IC_RESULT(ic), 0);
10582 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10585 /*-----------------------------------------------------------------*/
10586 /* genDummyRead - generate code for dummy read of volatiles */
10587 /*-----------------------------------------------------------------*/
10589 genDummyRead (iCode * ic)
10591 pic16_emitcode ("; genDummyRead","");
10592 pic16_emitcode ("; not implemented","");
10597 /*-----------------------------------------------------------------*/
10598 /* genpic16Code - generate code for pic16 based controllers */
10599 /*-----------------------------------------------------------------*/
10601 * At this point, ralloc.c has gone through the iCode and attempted
10602 * to optimize in a way suitable for a PIC. Now we've got to generate
10603 * PIC instructions that correspond to the iCode.
10605 * Once the instructions are generated, we'll pass through both the
10606 * peep hole optimizer and the pCode optimizer.
10607 *-----------------------------------------------------------------*/
10609 void genpic16Code (iCode *lic)
10614 lineHead = lineCurr = NULL;
10616 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10617 pic16_addpBlock(pb);
10620 /* if debug information required */
10621 if (options.debug && currFunc) {
10623 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10625 if (IS_STATIC(currFunc->etype)) {
10626 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10627 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10629 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10630 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10637 for (ic = lic ; ic ; ic = ic->next ) {
10639 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10640 if ( cln != ic->lineno ) {
10641 if ( options.debug ) {
10643 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10644 FileBaseName(ic->filename),ic->lineno,
10645 ic->level,ic->block);
10649 if(!options.noCcodeInAsm) {
10650 pic16_addpCode2pBlock(pb,
10651 pic16_newpCodeCSource(ic->lineno, ic->filename,
10652 printCLine(ic->filename, ic->lineno)));
10658 if(options.iCodeInAsm) {
10659 /* insert here code to print iCode as comment */
10660 pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic));
10663 /* if the result is marked as
10664 spilt and rematerializable or code for
10665 this has already been generated then
10667 if (resultRemat(ic) || ic->generated )
10670 /* depending on the operation */
10689 /* IPOP happens only when trying to restore a
10690 spilt live range, if there is an ifx statement
10691 following this pop then the if statement might
10692 be using some of the registers being popped which
10693 would destroy the contents of the register so
10694 we need to check for this condition and handle it */
10696 ic->next->op == IFX &&
10697 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10698 genIfx (ic->next,ic);
10716 genEndFunction (ic);
10732 pic16_genPlus (ic) ;
10736 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10737 pic16_genMinus (ic);
10753 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10757 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10764 /* note these two are xlated by algebraic equivalence
10765 during parsing SDCC.y */
10766 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10767 "got '>=' or '<=' shouldn't have come here");
10771 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10783 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10787 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10791 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10815 genRightShift (ic);
10818 case GET_VALUE_AT_ADDRESS:
10823 if (POINTER_SET(ic))
10850 addSet(&_G.sendSet,ic);
10853 case DUMMY_READ_VOLATILE:
10863 /* now we are ready to call the
10864 peep hole optimizer */
10865 if (!options.nopeep) {
10866 peepHole (&lineHead);
10868 /* now do the actual printing */
10869 printLine (lineHead,codeOutFile);
10872 DFPRINTF((stderr,"printing pBlock\n\n"));
10873 pic16_printpBlock(stdout,pb);